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