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 @Deprecated
314 public ChannelBuffer readBytes(ChannelBufferIndexFinder endIndexFinder) {
315 int endIndex = indexOf(readerIndex, writerIndex, endIndexFinder);
316 if (endIndex < 0) {
317 throw new NoSuchElementException();
318 }
319 return readBytes(endIndex - readerIndex);
320 }
321
322 public ChannelBuffer readSlice(int length) {
323 ChannelBuffer slice = slice(readerIndex, length);
324 readerIndex += length;
325 return slice;
326 }
327
328 @Deprecated
329 public ChannelBuffer readSlice(ChannelBufferIndexFinder endIndexFinder) {
330 int endIndex = indexOf(readerIndex, writerIndex, endIndexFinder);
331 if (endIndex < 0) {
332 throw new NoSuchElementException();
333 }
334 return readSlice(endIndex - readerIndex);
335 }
336
337 public void readBytes(byte[] dst, int dstIndex, int length) {
338 checkReadableBytes(length);
339 getBytes(readerIndex, dst, dstIndex, length);
340 readerIndex += length;
341 }
342
343 public void readBytes(byte[] dst) {
344 readBytes(dst, 0, dst.length);
345 }
346
347 public void readBytes(ChannelBuffer dst) {
348 readBytes(dst, dst.writableBytes());
349 }
350
351 public void readBytes(ChannelBuffer dst, int length) {
352 if (length > dst.writableBytes()) {
353 throw new IndexOutOfBoundsException("Too many bytes to be read: Need "
354 + length + ", maximum is " + dst.writableBytes());
355 }
356 readBytes(dst, dst.writerIndex(), length);
357 dst.writerIndex(dst.writerIndex() + length);
358 }
359
360 public void readBytes(ChannelBuffer dst, int dstIndex, int length) {
361 checkReadableBytes(length);
362 getBytes(readerIndex, dst, dstIndex, length);
363 readerIndex += length;
364 }
365
366 public void readBytes(ByteBuffer dst) {
367 int length = dst.remaining();
368 checkReadableBytes(length);
369 getBytes(readerIndex, dst);
370 readerIndex += length;
371 }
372
373 public int readBytes(GatheringByteChannel out, int length)
374 throws IOException {
375 checkReadableBytes(length);
376 int readBytes = getBytes(readerIndex, out, length);
377 readerIndex += readBytes;
378 return readBytes;
379 }
380
381 public void readBytes(OutputStream out, int length) throws IOException {
382 checkReadableBytes(length);
383 getBytes(readerIndex, out, length);
384 readerIndex += length;
385 }
386
387 public void skipBytes(int length) {
388 int newReaderIndex = readerIndex + length;
389 if (newReaderIndex > writerIndex) {
390 throw new IndexOutOfBoundsException("Readable bytes exceeded - Need "
391 + newReaderIndex + ", maximum is " + writerIndex);
392 }
393 readerIndex = newReaderIndex;
394 }
395
396 @Deprecated
397 public int skipBytes(ChannelBufferIndexFinder firstIndexFinder) {
398 int oldReaderIndex = readerIndex;
399 int newReaderIndex = indexOf(oldReaderIndex, writerIndex, firstIndexFinder);
400 if (newReaderIndex < 0) {
401 throw new NoSuchElementException();
402 }
403 readerIndex(newReaderIndex);
404 return newReaderIndex - oldReaderIndex;
405 }
406
407 public void writeByte(int value) {
408 setByte(writerIndex ++, value);
409 }
410
411 public void writeShort(int value) {
412 setShort(writerIndex, value);
413 writerIndex += 2;
414 }
415
416 public void writeMedium(int value) {
417 setMedium(writerIndex, value);
418 writerIndex += 3;
419 }
420
421 public void writeInt(int value) {
422 setInt(writerIndex, value);
423 writerIndex += 4;
424 }
425
426 public void writeLong(long value) {
427 setLong(writerIndex, value);
428 writerIndex += 8;
429 }
430
431 public void writeChar(int value) {
432 writeShort(value);
433 }
434
435 public void writeFloat(float value) {
436 writeInt(Float.floatToRawIntBits(value));
437 }
438
439 public void writeDouble(double value) {
440 writeLong(Double.doubleToRawLongBits(value));
441 }
442
443 public void writeBytes(byte[] src, int srcIndex, int length) {
444 setBytes(writerIndex, src, srcIndex, length);
445 writerIndex += length;
446 }
447
448 public void writeBytes(byte[] src) {
449 writeBytes(src, 0, src.length);
450 }
451
452 public void writeBytes(ChannelBuffer src) {
453 writeBytes(src, src.readableBytes());
454 }
455
456 public void writeBytes(ChannelBuffer src, int length) {
457 if (length > src.readableBytes()) {
458 throw new IndexOutOfBoundsException("Too many bytes to write - Need "
459 + length + ", maximum is " + src.readableBytes());
460 }
461 writeBytes(src, src.readerIndex(), length);
462 src.readerIndex(src.readerIndex() + length);
463 }
464
465 public void writeBytes(ChannelBuffer src, int srcIndex, int length) {
466 setBytes(writerIndex, src, srcIndex, length);
467 writerIndex += length;
468 }
469
470 public void writeBytes(ByteBuffer src) {
471 int length = src.remaining();
472 setBytes(writerIndex, src);
473 writerIndex += length;
474 }
475
476 public int writeBytes(InputStream in, int length)
477 throws IOException {
478 int writtenBytes = setBytes(writerIndex, in, length);
479 if (writtenBytes > 0) {
480 writerIndex += writtenBytes;
481 }
482 return writtenBytes;
483 }
484
485 public int writeBytes(ScatteringByteChannel in, int length)
486 throws IOException {
487 int writtenBytes = setBytes(writerIndex, in, length);
488 if (writtenBytes > 0) {
489 writerIndex += writtenBytes;
490 }
491 return writtenBytes;
492 }
493
494 public void writeZero(int length) {
495 if (length == 0) {
496 return;
497 }
498 if (length < 0) {
499 throw new IllegalArgumentException(
500 "length must be 0 or greater than 0.");
501 }
502 int nLong = length >>> 3;
503 int nBytes = length & 7;
504 for (int i = nLong; i > 0; i --) {
505 writeLong(0);
506 }
507 if (nBytes == 4) {
508 writeInt(0);
509 } else if (nBytes < 4) {
510 for (int i = nBytes; i > 0; i --) {
511 writeByte((byte) 0);
512 }
513 } else {
514 writeInt(0);
515 for (int i = nBytes - 4; i > 0; i --) {
516 writeByte((byte) 0);
517 }
518 }
519 }
520
521 public ChannelBuffer copy() {
522 return copy(readerIndex, readableBytes());
523 }
524
525 public ChannelBuffer slice() {
526 return slice(readerIndex, readableBytes());
527 }
528
529 public ByteBuffer toByteBuffer() {
530 return toByteBuffer(readerIndex, readableBytes());
531 }
532
533 public ByteBuffer[] toByteBuffers() {
534 return toByteBuffers(readerIndex, readableBytes());
535 }
536
537 public ByteBuffer[] toByteBuffers(int index, int length) {
538 return new ByteBuffer[] { toByteBuffer(index, length) };
539 }
540
541 public String toString(Charset charset) {
542 return toString(readerIndex, readableBytes(), charset);
543 }
544
545 public String toString(int index, int length, Charset charset) {
546 if (length == 0) {
547 return "";
548 }
549
550 return ChannelBuffers.decodeString(
551 toByteBuffer(index, length), charset);
552 }
553
554 @Deprecated
555 public String toString(int index, int length, String charsetName,
556 ChannelBufferIndexFinder terminatorFinder) {
557 if (terminatorFinder == null) {
558 return toString(index, length, charsetName);
559 }
560
561 int terminatorIndex = indexOf(index, index + length, terminatorFinder);
562 if (terminatorIndex < 0) {
563 return toString(index, length, charsetName);
564 }
565
566 return toString(index, terminatorIndex - index, charsetName);
567 }
568
569 @Deprecated
570 public String toString(int index, int length, String charsetName) {
571 return toString(index, length, Charset.forName(charsetName));
572 }
573
574 @Deprecated
575 public String toString(String charsetName,
576 ChannelBufferIndexFinder terminatorFinder) {
577 return toString(readerIndex, readableBytes(), charsetName, terminatorFinder);
578 }
579
580 @Deprecated
581 public String toString(String charsetName) {
582 return toString(Charset.forName(charsetName));
583 }
584
585 public int indexOf(int fromIndex, int toIndex, byte value) {
586 return ChannelBuffers.indexOf(this, fromIndex, toIndex, value);
587 }
588
589 public int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
590 return ChannelBuffers.indexOf(this, fromIndex, toIndex, indexFinder);
591 }
592
593 public int bytesBefore(byte value) {
594 return bytesBefore(readerIndex(), readableBytes(), value);
595 }
596
597 public int bytesBefore(ChannelBufferIndexFinder indexFinder) {
598 return bytesBefore(readerIndex(), readableBytes(), indexFinder);
599 }
600
601 public int bytesBefore(int length, byte value) {
602 checkReadableBytes(length);
603 return bytesBefore(readerIndex(), length, value);
604 }
605
606 public int bytesBefore(int length, ChannelBufferIndexFinder indexFinder) {
607 checkReadableBytes(length);
608 return bytesBefore(readerIndex(), length, indexFinder);
609 }
610
611 public int bytesBefore(int index, int length, byte value) {
612 int endIndex = indexOf(index, index + length, value);
613 if (endIndex < 0) {
614 return -1;
615 }
616 return endIndex - index;
617 }
618
619 public int bytesBefore(int index, int length,
620 ChannelBufferIndexFinder indexFinder) {
621 int endIndex = indexOf(index, index + length, indexFinder);
622 if (endIndex < 0) {
623 return -1;
624 }
625 return endIndex - index;
626 }
627
628 @Override
629 public int hashCode() {
630 return ChannelBuffers.hashCode(this);
631 }
632
633 @Override
634 public boolean equals(Object o) {
635 if (!(o instanceof ChannelBuffer)) {
636 return false;
637 }
638 return ChannelBuffers.equals(this, (ChannelBuffer) o);
639 }
640
641 public int compareTo(ChannelBuffer that) {
642 return ChannelBuffers.compare(this, that);
643 }
644
645 @Override
646 public String toString() {
647 return getClass().getSimpleName() + '(' +
648 "ridx=" + readerIndex + ", " +
649 "widx=" + writerIndex + ", " +
650 "cap=" + capacity() +
651 ')';
652 }
653
654
655
656
657
658
659 protected void checkReadableBytes(int minimumReadableBytes) {
660 if (readableBytes() < minimumReadableBytes) {
661 throw new IndexOutOfBoundsException("Not enough readable bytes - Need "
662 + minimumReadableBytes + ", maximum is " + readableBytes());
663 }
664 }
665 }