vfs: check userland buffers before reading them.
[haiku.git] / src / kits / debugger / util / RangeList.cpp
blob8ab7f80bac956f80adacdb0017a55cdd0de6cbe8
1 /*
2 * Copyright 2013, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "RangeList.h"
9 #include <AutoDeleter.h>
12 RangeList::RangeList()
13 : BObjectList<Range>(20, true)
18 RangeList::~RangeList()
23 status_t
24 RangeList::AddRange(int32 lowValue, int32 highValue)
26 if (lowValue > highValue)
27 return B_BAD_VALUE;
29 int32 i = 0;
30 if (CountItems() != 0) {
31 for (; i < CountItems(); i++) {
32 Range* range = ItemAt(i);
33 if (lowValue < range->lowerBound) {
34 if (highValue < range->lowerBound) {
35 // the new range is completely below the bounds
36 // of the ranges we currently contain,
37 // insert it here.
38 break;
39 } else if (highValue <= range->upperBound) {
40 // the new range partly overlaps the lower
41 // current range
42 range->lowerBound = lowValue;
43 return B_OK;
44 } else {
45 // the new range completely encompasses
46 // the current range
47 range->lowerBound = lowValue;
48 range->upperBound = highValue;
49 _CollapseOverlappingRanges(i +1, highValue);
52 } else if (lowValue < range->upperBound) {
53 if (highValue <= range->upperBound) {
54 // the requested range is already completely contained
55 // within our existing range list
56 return B_OK;
57 } else {
58 range->upperBound = highValue;
59 _CollapseOverlappingRanges(i + 1, highValue);
60 return B_OK;
66 Range* range = new(std::nothrow) Range(lowValue, highValue);
67 if (range == NULL)
68 return B_NO_MEMORY;
70 BPrivate::ObjectDeleter<Range> rangeDeleter(range);
71 if (!AddItem(range, i))
72 return B_NO_MEMORY;
74 rangeDeleter.Detach();
75 return B_OK;
79 status_t
80 RangeList::AddRange(const Range& range)
82 return AddRange(range.lowerBound, range.upperBound);
86 void
87 RangeList::RemoveRangeAt(int32 index)
89 if (index < 0 || index >= CountItems())
90 return;
92 RemoveItem(ItemAt(index));
96 bool
97 RangeList::Contains(int32 value) const
99 for (int32 i = 0; i < CountItems(); i++) {
100 const Range* range = ItemAt(i);
101 if (value < range->lowerBound || value > range->upperBound)
102 break;
103 else if (value >= range->lowerBound && value <= range->upperBound)
104 return true;
107 return false;
111 int32
112 RangeList::CountRanges() const
114 return CountItems();
118 const Range*
119 RangeList::RangeAt(int32 index) const
121 return ItemAt(index);
125 void
126 RangeList::_CollapseOverlappingRanges(int32 startIndex, int32 highValue)
128 for (int32 i = startIndex; i < CountItems();) {
129 // check if it also overlaps any of the following
130 // ranges.
131 Range* nextRange = ItemAt(i);
132 if (nextRange->lowerBound > highValue)
133 return;
134 else if (nextRange->upperBound < highValue) {
135 RemoveItem(nextRange);
136 continue;
137 } else {
138 nextRange->lowerBound = highValue + 1;
139 return;