summaryrefslogtreecommitdiffstats
path: root/kdat/Range.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdat/Range.cpp')
-rw-r--r--kdat/Range.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/kdat/Range.cpp b/kdat/Range.cpp
new file mode 100644
index 0000000..b2836aa
--- /dev/null
+++ b/kdat/Range.cpp
@@ -0,0 +1,132 @@
+// 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();
+}