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.
tdeadmin/kdat/Range.cpp

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 QPtrList<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();
}