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