1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.buffer;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.nio.ByteBuffer;
22 import java.nio.channels.GatheringByteChannel;
23 import java.nio.channels.ScatteringByteChannel;
24 import java.nio.charset.Charset;
25 import java.util.NoSuchElementException;
26
27
28
29
30
31 public abstract class AbstractChannelBuffer implements ChannelBuffer {
32
33 private int readerIndex;
34 private int writerIndex;
35 private int markedReaderIndex;
36 private int markedWriterIndex;
37
38 public int readerIndex() {
39 return readerIndex;
40 }
41
42 public void readerIndex(int readerIndex) {
43 if (readerIndex < 0 || readerIndex > writerIndex) {
44 throw new IndexOutOfBoundsException();
45 }
46 this.readerIndex = readerIndex;
47 }
48
49 public int writerIndex() {
50 return writerIndex;
51 }
52
53 public void writerIndex(int writerIndex) {
54 if (writerIndex < readerIndex || writerIndex > capacity()) {
55 throw new IndexOutOfBoundsException("Invalid readerIndex: "
56 + readerIndex + " - Maximum is " + writerIndex);
57 }
58 this.writerIndex = writerIndex;
59 }
60
61 public void setIndex(int readerIndex, int writerIndex) {
62 if (readerIndex < 0 || readerIndex > writerIndex || writerIndex > capacity()) {
63 throw new IndexOutOfBoundsException("Invalid writerIndex: "
64 + writerIndex + " - Maximum is " + readerIndex + " or " + capacity());
65 }
66 this.readerIndex = readerIndex;
67 this.writerIndex = writerIndex;
68 }
69
70 public void clear() {
71 readerIndex = writerIndex = 0;
72 }
73
74 public boolean readable() {
75 return readableBytes() > 0;
76 }
77
78 public boolean writable() {
79 return writableBytes() > 0;
80 }
81
82 public int readableBytes() {
83 return writerIndex - readerIndex;
84 }
85
86 public int writableBytes() {
87 return capacity() - writerIndex;
88 }
89
90 public void markReaderIndex() {
91 markedReaderIndex = readerIndex;
92 }
93
94 public void resetReaderIndex() {
95 readerIndex(markedReaderIndex);
96 }
97
98 public void markWriterIndex() {
99 markedWriterIndex = writerIndex;
100 }
101
102 public void resetWriterIndex() {
103 writerIndex = markedWriterIndex;
104 }
105
106 public void discardReadBytes() {
107 if (readerIndex == 0) {
108 return;
109 }
110 setBytes(0, this, readerIndex, writerIndex - readerIndex);
111 writerIndex -= readerIndex;
112 markedReaderIndex = Math.max(markedReaderIndex - readerIndex, 0);
113 markedWriterIndex = Math.max(markedWriterIndex - readerIndex, 0);
114 readerIndex = 0;
115 }
116
117 public void ensureWritableBytes(int writableBytes) {
118 if (writableBytes > writableBytes()) {
119 throw new IndexOutOfBoundsException("Writable bytes exceeded: Got "
120 + writableBytes + ", maximum is " + writableBytes());
121 }
122 }
123
124 public short getUnsignedByte(int index) {
125 return (short) (getByte(index) & 0xFF);
126 }
127
128 public int getUnsignedShort(int index) {
129 return getShort(index) & 0xFFFF;
130 }
131
132 public int getMedium(int index) {
133 int value = getUnsignedMedium(index);
134 if ((value & 0x800000) != 0) {
135 value |= 0xff000000;
136 }
137 return value;
138 }
139
140 public long getUnsignedInt(int index) {
141 return getInt(index) & 0xFFFFFFFFL;
142 }
143
144 public char getChar(int index) {
145 return (char) getShort(index);
146 }
147
148 public float getFloat(int index) {
149 return Float.intBitsToFloat(getInt(index));
150 }
151
152 public double getDouble(int index) {
153 return Double.longBitsToDouble(getLong(index));
154 }
155
156 public void getBytes(int index, byte[] dst) {
157 getBytes(index, dst, 0, dst.length);
158 }
159
160 public void getBytes(int index, ChannelBuffer dst) {
161 getBytes(index, dst, dst.writableBytes());
162 }
163
164 public void getBytes(int index, ChannelBuffer dst, int length) {
165 if (length > dst.writableBytes()) {
166 throw new IndexOutOfBoundsException("Too many bytes to be read: Need "
167 + length + ", maximum is " + dst.writableBytes());
168 }
169 getBytes(index, dst, dst.writerIndex(), length);
170 dst.writerIndex(dst.writerIndex() + length);
171 }
172
173 public void setChar(int index, int value) {
174 setShort(index, value);
175 }
176
177 public void setFloat(int index, float value) {
178 setInt(index, Float.floatToRawIntBits(value));
179 }
180
181 public void setDouble(int index, double value) {
182 setLong(index, Double.doubleToRawLongBits(value));
183 }
184
185 public void setBytes(int index, byte[] src) {
186 setBytes(index, src, 0, src.length);
187 }
188
189 public void setBytes(int index, ChannelBuffer src) {
190 setBytes(index, src, src.readableBytes());
191 }
192
193 public void setBytes(int index, ChannelBuffer src, int length) {
194 if (length > src.readableBytes()) {
195 throw new IndexOutOfBoundsException("Too many bytes to write: Need "
196 + length + ", maximum is " + src.readableBytes());
197 }
198 setBytes(index, src, src.readerIndex(), length);
199 src.readerIndex(src.readerIndex() + length);
200 }
201
202 public void setZero(int index, int length) {
203 if (length == 0) {
204 return;
205 }
206 if (length < 0) {
207 throw new IllegalArgumentException(
208 "length must be 0 or greater than 0.");
209 }
210
211 int nLong = length >>> 3;
212 int nBytes = length & 7;
213 for (int i = nLong; i > 0; i --) {
214 setLong(index, 0);
215 index += 8;
216 }
217 if (nBytes == 4) {
218 setInt(index, 0);
219 } else if (nBytes < 4) {
220 for (int i = nBytes; i > 0; i --) {
221 setByte(index, (byte) 0);
222 index ++;
223 }
224 } else {
225 setInt(index, 0);
226 index += 4;
227 for (int i = nBytes - 4; i > 0; i --) {
228 setByte(index, (byte) 0);
229 index ++;
230 }
231 }
232 }
233
234 public byte readByte() {
235 if (readerIndex == writerIndex) {
236 throw new IndexOutOfBoundsException("Readable byte limit exceeded: "
237 + readerIndex);
238 }
239 return getByte(readerIndex ++);
240 }
241
242 public short readUnsignedByte() {
243 return (short) (readByte() & 0xFF);
244 }
245
246 public short readShort() {
247 checkReadableBytes(2);
248 short v = getShort(readerIndex);
249 readerIndex += 2;
250 return v;
251 }
252
253 public int readUnsignedShort() {
254 return readShort() & 0xFFFF;
255 }
256
257 public int readMedium() {
258 int value = readUnsignedMedium();
259 if ((value & 0x800000) != 0) {
260 value |= 0xff000000;
261 }
262 return value;
263 }
264
265 public int readUnsignedMedium() {
266 checkReadableBytes(3);
267 int v = getUnsignedMedium(readerIndex);
268 readerIndex += 3;
269 return v;
270 }
271
272 public int readInt() {
273 checkReadableBytes(4);
274 int v = getInt(readerIndex);
275 readerIndex += 4;
276 return v;
277 }
278
279 public long readUnsignedInt() {
280 return readInt() & 0xFFFFFFFFL;
281 }
282
283 public long readLong() {
284 checkReadableBytes(8);
285 long v = getLong(readerIndex);
286 readerIndex += 8;
287 return v;
288 }
289
290 public char readChar() {
291 return (char) readShort();
292 }
293
294 public float readFloat() {
295 return Float.intBitsToFloat(readInt());
296 }
297
298 public double readDouble() {
299 return Double.longBitsToDouble(readLong());
300 }
301
302 public ChannelBuffer readBytes(int length) {
303 checkReadableBytes(length);
304 if (length == 0) {
305 return ChannelBuffers.EMPTY_BUFFER;
306 }
307 ChannelBuffer buf = factory().getBuffer(order(), length);
308 buf.writeBytes(this, readerIndex, length);
309 readerIndex += length;
310 return buf;
311 }
312
313 public ChannelBuffer readSlice(int length) {
314 ChannelBuffer slice = slice(readerIndex, length);
315 readerIndex += length;
316 return slice;
317 }
318
319 public void readBytes(byte[] dst, int dstIndex, int length) {
320 checkReadableBytes(length);
321 getBytes(readerIndex, dst, dstIndex, length);
322 readerIndex += length;
323 }
324
325 public void readBytes(byte[] dst) {
326 readBytes(dst, 0, dst.length);
327 }
328
329 public void readBytes(ChannelBuffer dst) {
330 readBytes(dst, dst.writableBytes());
331 }
332
333 public void readBytes(ChannelBuffer dst, int length) {
334 if (length > dst.writableBytes()) {
335 throw new IndexOutOfBoundsException("Too many bytes to be read: Need "
336 + length + ", maximum is " + dst.writableBytes());
337 }
338 readBytes(dst, dst.writerIndex(), length);
339 dst.writerIndex(dst.writerIndex() + length);
340 }
341
342 public void readBytes(ChannelBuffer dst, int dstIndex, int length) {
343 checkReadableBytes(length);
344 getBytes(readerIndex, dst, dstIndex, length);
345 readerIndex += length;
346 }
347
348 public void readBytes(ByteBuffer dst) {
349 int length = dst.remaining();
350 checkReadableBytes(length);
351 getBytes(readerIndex, dst);
352 readerIndex += length;
353 }
354
355 public int readBytes(GatheringByteChannel out, int length)
356 throws IOException {
357 checkReadableBytes(length);
358 int readBytes = getBytes(readerIndex, out, length);
359 readerIndex += readBytes;
360 return readBytes;
361 }
362
363 public void readBytes(OutputStream out, int length) throws IOException {
364 checkReadableBytes(length);
365 getBytes(readerIndex, out, length);
366 readerIndex += length;
367 }
368
369 public void skipBytes(int length) {
370 int newReaderIndex = readerIndex + length;
371 if (newReaderIndex > writerIndex) {
372 throw new IndexOutOfBoundsException("Readable bytes exceeded - Need "
373 + newReaderIndex + ", maximum is " + writerIndex);
374 }
375 readerIndex = newReaderIndex;
376 }
377
378 public void writeByte(int value) {
379 setByte(writerIndex, value);
380 writerIndex++;
381 }
382
383 public void writeShort(int value) {
384 setShort(writerIndex, value);
385 writerIndex += 2;
386 }
387
388 public void writeMedium(int value) {
389 setMedium(writerIndex, value);
390 writerIndex += 3;
391 }
392
393 public void writeInt(int value) {
394 setInt(writerIndex, value);
395 writerIndex += 4;
396 }
397
398 public void writeLong(long value) {
399 setLong(writerIndex, value);
400 writerIndex += 8;
401 }
402
403 public void writeChar(int value) {
404 writeShort(value);
405 }
406
407 public void writeFloat(float value) {
408 writeInt(Float.floatToRawIntBits(value));
409 }
410
411 public void writeDouble(double value) {
412 writeLong(Double.doubleToRawLongBits(value));
413 }
414
415 public void writeBytes(byte[] src, int srcIndex, int length) {
416 setBytes(writerIndex, src, srcIndex, length);
417 writerIndex += length;
418 }
419
420 public void writeBytes(byte[] src) {
421 writeBytes(src, 0, src.length);
422 }
423
424 public void writeBytes(ChannelBuffer src) {
425 writeBytes(src, src.readableBytes());
426 }
427
428 public void writeBytes(ChannelBuffer src, int length) {
429 if (length > src.readableBytes()) {
430 throw new IndexOutOfBoundsException("Too many bytes to write - Need "
431 + length + ", maximum is " + src.readableBytes());
432 }
433 writeBytes(src, src.readerIndex(), length);
434 src.readerIndex(src.readerIndex() + length);
435 }
436
437 public void writeBytes(ChannelBuffer src, int srcIndex, int length) {
438 setBytes(writerIndex, src, srcIndex, length);
439 writerIndex += length;
440 }
441
442 public void writeBytes(ByteBuffer src) {
443 int length = src.remaining();
444 setBytes(writerIndex, src);
445 writerIndex += length;
446 }
447
448 public int writeBytes(InputStream in, int length)
449 throws IOException {
450 int writtenBytes = setBytes(writerIndex, in, length);
451 if (writtenBytes > 0) {
452 writerIndex += writtenBytes;
453 }
454 return writtenBytes;
455 }
456
457 public int writeBytes(ScatteringByteChannel in, int length)
458 throws IOException {
459 int writtenBytes = setBytes(writerIndex, in, length);
460 if (writtenBytes > 0) {
461 writerIndex += writtenBytes;
462 }
463 return writtenBytes;
464 }
465
466 public void writeZero(int length) {
467 if (length == 0) {
468 return;
469 }
470 if (length < 0) {
471 throw new IllegalArgumentException(
472 "length must be 0 or greater than 0.");
473 }
474 int nLong = length >>> 3;
475 int nBytes = length & 7;
476 for (int i = nLong; i > 0; i --) {
477 writeLong(0);
478 }
479 if (nBytes == 4) {
480 writeInt(0);
481 } else if (nBytes < 4) {
482 for (int i = nBytes; i > 0; i --) {
483 writeByte((byte) 0);
484 }
485 } else {
486 writeInt(0);
487 for (int i = nBytes - 4; i > 0; i --) {
488 writeByte((byte) 0);
489 }
490 }
491 }
492
493 public ChannelBuffer copy() {
494 return copy(readerIndex, readableBytes());
495 }
496
497 public ChannelBuffer slice() {
498 return slice(readerIndex, readableBytes());
499 }
500
501 public ByteBuffer toByteBuffer() {
502 return toByteBuffer(readerIndex, readableBytes());
503 }
504
505 public ByteBuffer[] toByteBuffers() {
506 return toByteBuffers(readerIndex, readableBytes());
507 }
508
509 public ByteBuffer[] toByteBuffers(int index, int length) {
510 return new ByteBuffer[] { toByteBuffer(index, length) };
511 }
512
513 public String toString(Charset charset) {
514 return toString(readerIndex, readableBytes(), charset);
515 }
516
517 public String toString(int index, int length, Charset charset) {
518 if (length == 0) {
519 return "";
520 }
521
522 return ChannelBuffers.decodeString(
523 toByteBuffer(index, length), charset);
524 }
525
526 public int indexOf(int fromIndex, int toIndex, byte value) {
527 return ChannelBuffers.indexOf(this, fromIndex, toIndex, value);
528 }
529
530 public int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
531 return ChannelBuffers.indexOf(this, fromIndex, toIndex, indexFinder);
532 }
533
534 public int bytesBefore(byte value) {
535 return bytesBefore(readerIndex(), readableBytes(), value);
536 }
537
538 public int bytesBefore(ChannelBufferIndexFinder indexFinder) {
539 return bytesBefore(readerIndex(), readableBytes(), indexFinder);
540 }
541
542 public int bytesBefore(int length, byte value) {
543 checkReadableBytes(length);
544 return bytesBefore(readerIndex(), length, value);
545 }
546
547 public int bytesBefore(int length, ChannelBufferIndexFinder indexFinder) {
548 checkReadableBytes(length);
549 return bytesBefore(readerIndex(), length, indexFinder);
550 }
551
552 public int bytesBefore(int index, int length, byte value) {
553 if (index < 0 || length < 0 || index + length > capacity()) {
554 throw new IndexOutOfBoundsException();
555 }
556 int endIndex = indexOf(index, index + length, value);
557 if (endIndex < 0) {
558 return -1;
559 }
560 return endIndex - index;
561 }
562
563 public int bytesBefore(int index, int length,
564 ChannelBufferIndexFinder indexFinder) {
565 if (index < 0 || length < 0 || index + length > capacity()) {
566 throw new IndexOutOfBoundsException();
567 }
568 int endIndex = indexOf(index, index + length, indexFinder);
569 if (endIndex < 0) {
570 return -1;
571 }
572 return endIndex - index;
573 }
574
575 @Override
576 public int hashCode() {
577 return ChannelBuffers.hashCode(this);
578 }
579
580 @Override
581 public boolean equals(Object o) {
582 if (!(o instanceof ChannelBuffer)) {
583 return false;
584 }
585 return ChannelBuffers.equals(this, (ChannelBuffer) o);
586 }
587
588 public int compareTo(ChannelBuffer that) {
589 return ChannelBuffers.compare(this, that);
590 }
591
592 @Override
593 public String toString() {
594 return getClass().getSimpleName() + '(' +
595 "ridx=" + readerIndex + ", " +
596 "widx=" + writerIndex + ", " +
597 "cap=" + capacity() +
598 ')';
599 }
600
601
602
603
604
605
606 protected void checkReadableBytes(int minimumReadableBytes) {
607 if (readableBytes() < minimumReadableBytes) {
608 throw new IndexOutOfBoundsException("Not enough readable bytes - Need "
609 + minimumReadableBytes + ", maximum is " + readableBytes());
610 }
611 }
612 }