You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.6 KiB
133 lines
3.6 KiB
// KDat - a tar-based DAT archiver
|
|
// Copyright (C) 1998-2000 Sean Vyain, svyain@mail.tds.net
|
|
// Copyright (C) 2001-2002 Lawrence Widman, kdat@cardiothink.com
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
#include <assert.h>
|
|
|
|
#include "Range.h"
|
|
|
|
Range::Range( int start, int end )
|
|
: _start( start ),
|
|
_end( end )
|
|
{
|
|
}
|
|
|
|
int Range::getStart()
|
|
{
|
|
return _start;
|
|
}
|
|
|
|
int Range::getEnd()
|
|
{
|
|
return _end;
|
|
}
|
|
|
|
void Range::setStart( int start )
|
|
{
|
|
_start = start;
|
|
}
|
|
|
|
void Range::setEnd( int end )
|
|
{
|
|
_end = end;
|
|
}
|
|
|
|
RangeList::RangeList()
|
|
{
|
|
}
|
|
|
|
RangeList::~RangeList()
|
|
{
|
|
while ( _ranges.first() ) {
|
|
delete _ranges.first();
|
|
_ranges.removeFirst();
|
|
}
|
|
}
|
|
|
|
const TQPtrList<Range>& RangeList::getRanges() const
|
|
{
|
|
return _ranges;
|
|
}
|
|
|
|
void RangeList::addRange( int start, int end )
|
|
{
|
|
assert( end >= start );
|
|
|
|
if ( start == end ) {
|
|
return;
|
|
}
|
|
|
|
// Remove all of the ranges that are totally contained by the new range.
|
|
for ( _ranges.first(); _ranges.current(); ) {
|
|
if ( ( _ranges.current()->getStart() >= start ) && ( _ranges.current()->getEnd() <= end ) ) {
|
|
_ranges.remove();
|
|
} else if ( ( start >= _ranges.current()->getStart() ) && ( end <= _ranges.current()->getEnd() ) ) {
|
|
// The new range is totally contained in the current range.
|
|
return;
|
|
} else {
|
|
_ranges.next();
|
|
}
|
|
}
|
|
|
|
// Find the correct insertion point for the new range.
|
|
int idx = 0;
|
|
for ( _ranges.first(); _ranges.current(); _ranges.next(), idx++ ) {
|
|
if ( _ranges.current()->getStart() > start ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !_ranges.current() ) {
|
|
// Append new range to end of list.
|
|
if ( ( _ranges.last() ) && ( _ranges.last()->getEnd() >= start ) ) {
|
|
// Ranges overlap, merge them.
|
|
_ranges.last()->setEnd( end );
|
|
} else {
|
|
// Append a new range.
|
|
_ranges.append( new Range( start, end ) );
|
|
}
|
|
} else {
|
|
// Insert new range before current range.
|
|
if ( _ranges.current()->getStart() <= end ) {
|
|
// Ranges overlap, merge them.
|
|
_ranges.current()->setStart( start );
|
|
end = _ranges.current()->getEnd();
|
|
|
|
// Check previous range for overlap.
|
|
if ( ( _ranges.prev() ) && ( _ranges.current()->getEnd() >= start ) ) {
|
|
// New range overlapped both the before and after ranges.
|
|
_ranges.current()->setEnd( end );
|
|
_ranges.next();
|
|
_ranges.remove();
|
|
}
|
|
} else {
|
|
// Check previous range for overlap.
|
|
if ( ( _ranges.prev() ) && ( _ranges.current()->getEnd() >= start ) ) {
|
|
// New range overlapped the before range.
|
|
_ranges.current()->setEnd( end );
|
|
} else {
|
|
_ranges.insert( idx, new Range( start, end ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void RangeList::clear()
|
|
{
|
|
_ranges.clear();
|
|
}
|