1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections.primitives;
18
19 import java.util.ConcurrentModificationException;
20 import java.util.NoSuchElementException;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public abstract class RandomAccessByteList extends AbstractByteCollection implements ByteList {
41
42
43
44
45
46 protected RandomAccessByteList() {
47 }
48
49
50
51
52 public abstract byte get(int index);
53 public abstract int size();
54
55
56
57
58
59
60
61
62 public byte removeElementAt(int index) {
63 throw new UnsupportedOperationException();
64 }
65
66
67
68
69
70 public byte set(int index, byte element) {
71 throw new UnsupportedOperationException();
72 }
73
74
75
76
77
78 public void add(int index, byte element) {
79 throw new UnsupportedOperationException();
80 }
81
82
83
84
85
86 public boolean add(byte element) {
87 add(size(),element);
88 return true;
89 }
90
91 public boolean addAll(int index, ByteCollection collection) {
92 boolean modified = false;
93 for(ByteIterator iter = collection.iterator(); iter.hasNext(); ) {
94 add(index++,iter.next());
95 modified = true;
96 }
97 return modified;
98 }
99
100 public int indexOf(byte element) {
101 int i = 0;
102 for(ByteIterator iter = iterator(); iter.hasNext(); ) {
103 if(iter.next() == element) {
104 return i;
105 } else {
106 i++;
107 }
108 }
109 return -1;
110 }
111
112 public int lastIndexOf(byte element) {
113 for(ByteListIterator iter = listIterator(size()); iter.hasPrevious(); ) {
114 if(iter.previous() == element) {
115 return iter.nextIndex();
116 }
117 }
118 return -1;
119 }
120
121 public ByteIterator iterator() {
122 return listIterator();
123 }
124
125 public ByteListIterator listIterator() {
126 return listIterator(0);
127 }
128
129 public ByteListIterator listIterator(int index) {
130 return new RandomAccessByteListIterator(this,index);
131 }
132
133 public ByteList subList(int fromIndex, int toIndex) {
134 return new RandomAccessByteSubList(this,fromIndex,toIndex);
135 }
136
137 public boolean equals(Object that) {
138 if(this == that) {
139 return true;
140 } else if(that instanceof ByteList) {
141 ByteList thatList = (ByteList)that;
142 if(size() != thatList.size()) {
143 return false;
144 }
145 for(ByteIterator thatIter = thatList.iterator(), thisIter = iterator(); thisIter.hasNext();) {
146 if(thisIter.next() != thatIter.next()) {
147 return false;
148 }
149 }
150 return true;
151 } else {
152 return false;
153 }
154 }
155
156 public int hashCode() {
157 int hash = 1;
158 for(ByteIterator iter = iterator(); iter.hasNext(); ) {
159 hash = 31*hash + iter.next();
160 }
161 return hash;
162 }
163
164 public String toString() {
165 StringBuffer buf = new StringBuffer();
166 buf.append("[");
167 for(ByteIterator iter = iterator(); iter.hasNext();) {
168 buf.append(iter.next());
169 if(iter.hasNext()) {
170 buf.append(", ");
171 }
172 }
173 buf.append("]");
174 return buf.toString();
175 }
176
177
178
179
180
181 protected int getModCount() {
182 return _modCount;
183 }
184
185
186 protected void incrModCount() {
187 _modCount++;
188 }
189
190
191
192
193 private int _modCount = 0;
194
195
196
197
198 private static class ComodChecker {
199 ComodChecker(RandomAccessByteList source) {
200 _source = source;
201 resyncModCount();
202 }
203
204 protected RandomAccessByteList getList() {
205 return _source;
206 }
207
208 protected void assertNotComodified() throws ConcurrentModificationException {
209 if(_expectedModCount != getList().getModCount()) {
210 throw new ConcurrentModificationException();
211 }
212 }
213
214 protected void resyncModCount() {
215 _expectedModCount = getList().getModCount();
216 }
217
218 private RandomAccessByteList _source = null;
219 private int _expectedModCount = -1;
220 }
221
222 protected static class RandomAccessByteListIterator extends ComodChecker implements ByteListIterator {
223 RandomAccessByteListIterator(RandomAccessByteList list, int index) {
224 super(list);
225 if(index < 0 || index > getList().size()) {
226 throw new IndexOutOfBoundsException("Index " + index + " not in [0," + getList().size() + ")");
227 } else {
228 _nextIndex = index;
229 resyncModCount();
230 }
231 }
232
233 public boolean hasNext() {
234 assertNotComodified();
235 return _nextIndex < getList().size();
236 }
237
238 public boolean hasPrevious() {
239 assertNotComodified();
240 return _nextIndex > 0;
241 }
242
243 public int nextIndex() {
244 assertNotComodified();
245 return _nextIndex;
246 }
247
248 public int previousIndex() {
249 assertNotComodified();
250 return _nextIndex - 1;
251 }
252
253 public byte next() {
254 assertNotComodified();
255 if(!hasNext()) {
256 throw new NoSuchElementException();
257 } else {
258 byte val = getList().get(_nextIndex);
259 _lastReturnedIndex = _nextIndex;
260 _nextIndex++;
261 return val;
262 }
263 }
264
265 public byte previous() {
266 assertNotComodified();
267 if(!hasPrevious()) {
268 throw new NoSuchElementException();
269 } else {
270 byte val = getList().get(_nextIndex-1);
271 _lastReturnedIndex = _nextIndex-1;
272 _nextIndex--;
273 return val;
274 }
275 }
276
277 public void add(byte value) {
278 assertNotComodified();
279 getList().add(_nextIndex,value);
280 _nextIndex++;
281 _lastReturnedIndex = -1;
282 resyncModCount();
283 }
284
285 public void remove() {
286 assertNotComodified();
287 if (_lastReturnedIndex == -1) {
288 throw new IllegalStateException();
289 }
290 if (_lastReturnedIndex == _nextIndex) {
291
292 getList().removeElementAt(_lastReturnedIndex);
293 } else {
294
295 getList().removeElementAt(_lastReturnedIndex);
296 _nextIndex--;
297 }
298 _lastReturnedIndex = -1;
299 resyncModCount();
300 }
301
302 public void set(byte value) {
303 assertNotComodified();
304 if(-1 == _lastReturnedIndex) {
305 throw new IllegalStateException();
306 } else {
307 getList().set(_lastReturnedIndex,value);
308 resyncModCount();
309 }
310 }
311
312 private int _nextIndex = 0;
313 private int _lastReturnedIndex = -1;
314 }
315
316 protected static class RandomAccessByteSubList extends RandomAccessByteList implements ByteList {
317 RandomAccessByteSubList(RandomAccessByteList list, int fromIndex, int toIndex) {
318 if(fromIndex < 0 || toIndex > list.size()) {
319 throw new IndexOutOfBoundsException();
320 } else if(fromIndex > toIndex) {
321 throw new IllegalArgumentException();
322 } else {
323 _list = list;
324 _offset = fromIndex;
325 _limit = toIndex - fromIndex;
326 _comod = new ComodChecker(list);
327 _comod.resyncModCount();
328 }
329 }
330
331 public byte get(int index) {
332 checkRange(index);
333 _comod.assertNotComodified();
334 return _list.get(toUnderlyingIndex(index));
335 }
336
337 public byte removeElementAt(int index) {
338 checkRange(index);
339 _comod.assertNotComodified();
340 byte val = _list.removeElementAt(toUnderlyingIndex(index));
341 _limit--;
342 _comod.resyncModCount();
343 incrModCount();
344 return val;
345 }
346
347 public byte set(int index, byte element) {
348 checkRange(index);
349 _comod.assertNotComodified();
350 byte val = _list.set(toUnderlyingIndex(index),element);
351 incrModCount();
352 _comod.resyncModCount();
353 return val;
354 }
355
356 public void add(int index, byte element) {
357 checkRangeIncludingEndpoint(index);
358 _comod.assertNotComodified();
359 _list.add(toUnderlyingIndex(index),element);
360 _limit++;
361 _comod.resyncModCount();
362 incrModCount();
363 }
364
365 public int size() {
366 _comod.assertNotComodified();
367 return _limit;
368 }
369
370 private void checkRange(int index) {
371 if(index < 0 || index >= size()) {
372 throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + ")");
373 }
374 }
375
376 private void checkRangeIncludingEndpoint(int index) {
377 if(index < 0 || index > size()) {
378 throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + "]");
379 }
380 }
381
382 private int toUnderlyingIndex(int index) {
383 return (index + _offset);
384 }
385
386 private int _offset = 0;
387 private int _limit = 0;
388 private RandomAccessByteList _list = null;
389 private ComodChecker _comod = null;
390
391 }
392 }
393