1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.buffer;
17
18 import org.jboss.netty.util.CharsetUtil;
19
20 import java.nio.ByteBuffer;
21 import java.nio.ByteOrder;
22 import java.nio.CharBuffer;
23 import java.nio.charset.CharacterCodingException;
24 import java.nio.charset.Charset;
25 import java.nio.charset.CharsetDecoder;
26 import java.nio.charset.CharsetEncoder;
27 import java.nio.charset.CoderResult;
28 import java.util.ArrayList;
29 import java.util.List;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public final class ChannelBuffers {
89
90
91
92
93 public static final ByteOrder BIG_ENDIAN = ByteOrder.BIG_ENDIAN;
94
95
96
97
98 public static final ByteOrder LITTLE_ENDIAN = ByteOrder.LITTLE_ENDIAN;
99
100
101
102
103 public static final ChannelBuffer EMPTY_BUFFER = new EmptyChannelBuffer();
104
105 private static final char[] HEXDUMP_TABLE = new char[256 * 4];
106
107 static {
108 final char[] DIGITS = "0123456789abcdef".toCharArray();
109 for (int i = 0; i < 256; i ++) {
110 HEXDUMP_TABLE[i << 1] = DIGITS[i >>> 4 & 0x0F];
111 HEXDUMP_TABLE[(i << 1) + 1] = DIGITS[i & 0x0F];
112 }
113 }
114
115
116
117
118
119
120 public static ChannelBuffer buffer(int capacity) {
121 return buffer(BIG_ENDIAN, capacity);
122 }
123
124
125
126
127
128
129 public static ChannelBuffer buffer(ByteOrder endianness, int capacity) {
130 if (endianness == BIG_ENDIAN) {
131 if (capacity == 0) {
132 return EMPTY_BUFFER;
133 }
134 return new BigEndianHeapChannelBuffer(capacity);
135 } else if (endianness == LITTLE_ENDIAN) {
136 if (capacity == 0) {
137 return EMPTY_BUFFER;
138 }
139 return new LittleEndianHeapChannelBuffer(capacity);
140 } else {
141 throw new NullPointerException("endianness");
142 }
143 }
144
145
146
147
148
149
150 public static ChannelBuffer directBuffer(int capacity) {
151 return directBuffer(BIG_ENDIAN, capacity);
152 }
153
154
155
156
157
158
159 public static ChannelBuffer directBuffer(ByteOrder endianness, int capacity) {
160 if (endianness == null) {
161 throw new NullPointerException("endianness");
162 }
163 if (capacity == 0) {
164 return EMPTY_BUFFER;
165 }
166
167 ChannelBuffer buffer = new ByteBufferBackedChannelBuffer(
168 ByteBuffer.allocateDirect(capacity).order(endianness));
169 buffer.clear();
170 return buffer;
171 }
172
173
174
175
176
177
178 public static ChannelBuffer dynamicBuffer() {
179 return dynamicBuffer(BIG_ENDIAN, 256);
180 }
181
182 public static ChannelBuffer dynamicBuffer(ChannelBufferFactory factory) {
183 if (factory == null) {
184 throw new NullPointerException("factory");
185 }
186
187 return new DynamicChannelBuffer(factory.getDefaultOrder(), 256, factory);
188 }
189
190
191
192
193
194
195
196 public static ChannelBuffer dynamicBuffer(int estimatedLength) {
197 return dynamicBuffer(BIG_ENDIAN, estimatedLength);
198 }
199
200
201
202
203
204
205
206 public static ChannelBuffer dynamicBuffer(ByteOrder endianness, int estimatedLength) {
207 return new DynamicChannelBuffer(endianness, estimatedLength);
208 }
209
210
211
212
213
214
215
216 public static ChannelBuffer dynamicBuffer(int estimatedLength, ChannelBufferFactory factory) {
217 if (factory == null) {
218 throw new NullPointerException("factory");
219 }
220
221 return new DynamicChannelBuffer(factory.getDefaultOrder(), estimatedLength, factory);
222 }
223
224
225
226
227
228
229
230 public static ChannelBuffer dynamicBuffer(
231 ByteOrder endianness, int estimatedLength, ChannelBufferFactory factory) {
232 return new DynamicChannelBuffer(endianness, estimatedLength, factory);
233 }
234
235
236
237
238
239
240 public static ChannelBuffer wrappedBuffer(byte[] array) {
241 return wrappedBuffer(BIG_ENDIAN, array);
242 }
243
244
245
246
247
248
249 public static ChannelBuffer wrappedBuffer(ByteOrder endianness, byte[] array) {
250 if (endianness == BIG_ENDIAN) {
251 if (array.length == 0) {
252 return EMPTY_BUFFER;
253 }
254 return new BigEndianHeapChannelBuffer(array);
255 } else if (endianness == LITTLE_ENDIAN) {
256 if (array.length == 0) {
257 return EMPTY_BUFFER;
258 }
259 return new LittleEndianHeapChannelBuffer(array);
260 } else {
261 throw new NullPointerException("endianness");
262 }
263 }
264
265
266
267
268
269
270 public static ChannelBuffer wrappedBuffer(byte[] array, int offset, int length) {
271 return wrappedBuffer(BIG_ENDIAN, array, offset, length);
272 }
273
274
275
276
277
278
279 public static ChannelBuffer wrappedBuffer(ByteOrder endianness, byte[] array, int offset, int length) {
280 if (endianness == null) {
281 throw new NullPointerException("endianness");
282 }
283 if (offset == 0) {
284 if (length == array.length) {
285 return wrappedBuffer(endianness, array);
286 } else {
287 if (length == 0) {
288 return EMPTY_BUFFER;
289 } else {
290 return new TruncatedChannelBuffer(wrappedBuffer(endianness, array), length);
291 }
292 }
293 } else {
294 if (length == 0) {
295 return EMPTY_BUFFER;
296 } else {
297 return new SlicedChannelBuffer(wrappedBuffer(endianness, array), offset, length);
298 }
299 }
300 }
301
302
303
304
305
306
307 public static ChannelBuffer wrappedBuffer(ByteBuffer buffer) {
308 if (!buffer.hasRemaining()) {
309 return EMPTY_BUFFER;
310 }
311 if (buffer.hasArray()) {
312 return wrappedBuffer(
313 buffer.order(), buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
314 } else {
315 return new ByteBufferBackedChannelBuffer(buffer);
316 }
317 }
318
319
320
321
322
323
324 public static ChannelBuffer wrappedBuffer(ChannelBuffer buffer) {
325 if (buffer.readable()) {
326 return buffer.slice();
327 } else {
328 return EMPTY_BUFFER;
329 }
330 }
331
332
333
334
335
336
337 public static ChannelBuffer wrappedBuffer(byte[]... arrays) {
338 return wrappedBuffer(BIG_ENDIAN, arrays);
339 }
340
341
342
343
344
345
346
347
348 public static ChannelBuffer wrappedBuffer(ByteOrder endianness, byte[]... arrays) {
349 switch (arrays.length) {
350 case 0:
351 break;
352 case 1:
353 if (arrays[0].length != 0) {
354 return wrappedBuffer(endianness, arrays[0]);
355 }
356 break;
357 default:
358
359 final List<ChannelBuffer> components = new ArrayList<ChannelBuffer>(arrays.length);
360 for (byte[] a: arrays) {
361 if (a == null) {
362 break;
363 }
364 if (a.length > 0) {
365 components.add(wrappedBuffer(endianness, a));
366 }
367 }
368 return compositeBuffer(endianness, components, false);
369 }
370
371 return EMPTY_BUFFER;
372 }
373
374 private static ChannelBuffer compositeBuffer(
375 ByteOrder endianness, List<ChannelBuffer> components, boolean gathering) {
376 switch (components.size()) {
377 case 0:
378 return EMPTY_BUFFER;
379 case 1:
380 return components.get(0);
381 default:
382 return new CompositeChannelBuffer(endianness, components, gathering);
383 }
384 }
385
386
387
388
389
390
391
392
393
394
395 public static ChannelBuffer wrappedBuffer(ChannelBuffer... buffers) {
396 return wrappedBuffer(false, buffers);
397 }
398
399
400
401
402
403
404
405
406
407
408
409 public static ChannelBuffer wrappedBuffer(boolean gathering, ChannelBuffer... buffers) {
410 switch (buffers.length) {
411 case 0:
412 break;
413 case 1:
414 if (buffers[0].readable()) {
415 return wrappedBuffer(buffers[0]);
416 }
417 break;
418 default:
419 ByteOrder order = null;
420 final List<ChannelBuffer> components = new ArrayList<ChannelBuffer>(buffers.length);
421 for (ChannelBuffer c: buffers) {
422 if (c == null) {
423 break;
424 }
425 if (c.readable()) {
426 if (order != null) {
427 if (!order.equals(c.order())) {
428 throw new IllegalArgumentException(
429 "inconsistent byte order");
430 }
431 } else {
432 order = c.order();
433 }
434 if (c instanceof CompositeChannelBuffer) {
435
436 components.addAll(
437 ((CompositeChannelBuffer) c).decompose(
438 c.readerIndex(), c.readableBytes()));
439 } else {
440
441 components.add(c.slice());
442 }
443 }
444 }
445 return compositeBuffer(order, components, gathering);
446 }
447 return EMPTY_BUFFER;
448 }
449
450
451
452
453
454
455
456
457
458
459 public static ChannelBuffer wrappedBuffer(ByteBuffer... buffers) {
460 return wrappedBuffer(false, buffers);
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474 public static ChannelBuffer wrappedBuffer(boolean gathering, ByteBuffer... buffers) {
475 switch (buffers.length) {
476 case 0:
477 break;
478 case 1:
479 if (buffers[0].hasRemaining()) {
480 return wrappedBuffer(buffers[0]);
481 }
482 break;
483 default:
484 ByteOrder order = null;
485 final List<ChannelBuffer> components = new ArrayList<ChannelBuffer>(buffers.length);
486 for (ByteBuffer b: buffers) {
487 if (b == null) {
488 break;
489 }
490 if (b.hasRemaining()) {
491 if (order != null) {
492 if (!order.equals(b.order())) {
493 throw new IllegalArgumentException(
494 "inconsistent byte order");
495 }
496 } else {
497 order = b.order();
498 }
499 components.add(wrappedBuffer(b));
500 }
501 }
502 return compositeBuffer(order, components, gathering);
503 }
504
505 return EMPTY_BUFFER;
506 }
507
508
509
510
511
512
513 public static ChannelBuffer copiedBuffer(byte[] array) {
514 return copiedBuffer(BIG_ENDIAN, array);
515 }
516
517
518
519
520
521
522
523 public static ChannelBuffer copiedBuffer(ByteOrder endianness, byte[] array) {
524 if (endianness == BIG_ENDIAN) {
525 if (array.length == 0) {
526 return EMPTY_BUFFER;
527 }
528 return new BigEndianHeapChannelBuffer(array.clone());
529 } else if (endianness == LITTLE_ENDIAN) {
530 if (array.length == 0) {
531 return EMPTY_BUFFER;
532 }
533 return new LittleEndianHeapChannelBuffer(array.clone());
534 } else {
535 throw new NullPointerException("endianness");
536 }
537 }
538
539
540
541
542
543
544
545 public static ChannelBuffer copiedBuffer(byte[] array, int offset, int length) {
546 return copiedBuffer(BIG_ENDIAN, array, offset, length);
547 }
548
549
550
551
552
553
554
555 public static ChannelBuffer copiedBuffer(ByteOrder endianness, byte[] array, int offset, int length) {
556 if (endianness == null) {
557 throw new NullPointerException("endianness");
558 }
559 if (length == 0) {
560 return EMPTY_BUFFER;
561 }
562 byte[] copy = new byte[length];
563 System.arraycopy(array, offset, copy, 0, length);
564 return wrappedBuffer(endianness, copy);
565 }
566
567
568
569
570
571
572
573 public static ChannelBuffer copiedBuffer(ByteBuffer buffer) {
574 int length = buffer.remaining();
575 if (length == 0) {
576 return EMPTY_BUFFER;
577 }
578 byte[] copy = new byte[length];
579 int position = buffer.position();
580 try {
581 buffer.get(copy);
582 } finally {
583 buffer.position(position);
584 }
585 return wrappedBuffer(buffer.order(), copy);
586 }
587
588
589
590
591
592
593
594 public static ChannelBuffer copiedBuffer(ChannelBuffer buffer) {
595 if (buffer.readable()) {
596 return buffer.copy();
597 } else {
598 return EMPTY_BUFFER;
599 }
600 }
601
602
603
604
605
606
607
608 public static ChannelBuffer copiedBuffer(byte[]... arrays) {
609 return copiedBuffer(BIG_ENDIAN, arrays);
610 }
611
612
613
614
615
616
617
618 public static ChannelBuffer copiedBuffer(ByteOrder endianness, byte[]... arrays) {
619 switch (arrays.length) {
620 case 0:
621 return EMPTY_BUFFER;
622 case 1:
623 if (arrays[0].length == 0) {
624 return EMPTY_BUFFER;
625 } else {
626 return copiedBuffer(endianness, arrays[0]);
627 }
628 }
629
630
631 int length = 0;
632 for (byte[] a: arrays) {
633 if (Integer.MAX_VALUE - length < a.length) {
634 throw new IllegalArgumentException(
635 "The total length of the specified arrays is too big.");
636 }
637 length += a.length;
638 }
639
640 if (length == 0) {
641 return EMPTY_BUFFER;
642 }
643
644 byte[] mergedArray = new byte[length];
645 for (int i = 0, j = 0; i < arrays.length; i ++) {
646 byte[] a = arrays[i];
647 System.arraycopy(a, 0, mergedArray, j, a.length);
648 j += a.length;
649 }
650
651 return wrappedBuffer(endianness, mergedArray);
652 }
653
654
655
656
657
658
659
660
661
662
663
664 public static ChannelBuffer copiedBuffer(ChannelBuffer... buffers) {
665 switch (buffers.length) {
666 case 0:
667 return EMPTY_BUFFER;
668 case 1:
669 return copiedBuffer(buffers[0]);
670 }
671
672 ChannelBuffer[] copiedBuffers = new ChannelBuffer[buffers.length];
673 for (int i = 0; i < buffers.length; i ++) {
674 copiedBuffers[i] = copiedBuffer(buffers[i]);
675 }
676 return wrappedBuffer(false, copiedBuffers);
677 }
678
679
680
681
682
683
684
685
686
687
688
689 public static ChannelBuffer copiedBuffer(ByteBuffer... buffers) {
690 switch (buffers.length) {
691 case 0:
692 return EMPTY_BUFFER;
693 case 1:
694 return copiedBuffer(buffers[0]);
695 }
696
697 ChannelBuffer[] copiedBuffers = new ChannelBuffer[buffers.length];
698 for (int i = 0; i < buffers.length; i ++) {
699 copiedBuffers[i] = copiedBuffer(buffers[i]);
700 }
701 return wrappedBuffer(false, copiedBuffers);
702 }
703
704
705
706
707
708
709
710 public static ChannelBuffer copiedBuffer(CharSequence string, Charset charset) {
711 return copiedBuffer(BIG_ENDIAN, string, charset);
712 }
713
714
715
716
717
718
719
720 public static ChannelBuffer copiedBuffer(
721 CharSequence string, int offset, int length, Charset charset) {
722 return copiedBuffer(BIG_ENDIAN, string, offset, length, charset);
723 }
724
725
726
727
728
729
730
731
732 public static ChannelBuffer copiedBuffer(ByteOrder endianness, CharSequence string, Charset charset) {
733 if (string == null) {
734 throw new NullPointerException("string");
735 }
736
737 if (string instanceof CharBuffer) {
738 return copiedBuffer(endianness, (CharBuffer) string, charset);
739 }
740
741 return copiedBuffer(endianness, CharBuffer.wrap(string), charset);
742 }
743
744
745
746
747
748
749
750
751 public static ChannelBuffer copiedBuffer(
752 ByteOrder endianness, CharSequence string, int offset, int length, Charset charset) {
753 if (string == null) {
754 throw new NullPointerException("string");
755 }
756 if (length == 0) {
757 return EMPTY_BUFFER;
758 }
759
760 if (string instanceof CharBuffer) {
761 CharBuffer buf = (CharBuffer) string;
762 if (buf.hasArray()) {
763 return copiedBuffer(
764 endianness,
765 buf.array(),
766 buf.arrayOffset() + buf.position() + offset,
767 length, charset);
768 }
769
770 buf = buf.slice();
771 buf.limit(length);
772 buf.position(offset);
773 return copiedBuffer(endianness, buf, charset);
774 }
775
776 return copiedBuffer(
777 endianness, CharBuffer.wrap(string, offset, offset + length),
778 charset);
779 }
780
781
782
783
784
785
786
787 public static ChannelBuffer copiedBuffer(char[] array, Charset charset) {
788 return copiedBuffer(BIG_ENDIAN, array, 0, array.length, charset);
789 }
790
791
792
793
794
795
796
797 public static ChannelBuffer copiedBuffer(
798 char[] array, int offset, int length, Charset charset) {
799 return copiedBuffer(BIG_ENDIAN, array, offset, length, charset);
800 }
801
802
803
804
805
806
807
808
809 public static ChannelBuffer copiedBuffer(ByteOrder endianness, char[] array, Charset charset) {
810 return copiedBuffer(endianness, array, 0, array.length, charset);
811 }
812
813
814
815
816
817
818
819
820 public static ChannelBuffer copiedBuffer(
821 ByteOrder endianness, char[] array, int offset, int length, Charset charset) {
822 if (array == null) {
823 throw new NullPointerException("array");
824 }
825 if (length == 0) {
826 return EMPTY_BUFFER;
827 }
828 return copiedBuffer(
829 endianness, CharBuffer.wrap(array, offset, length), charset);
830 }
831
832 private static ChannelBuffer copiedBuffer(ByteOrder endianness, CharBuffer buffer, Charset charset) {
833 CharBuffer src = buffer;
834 ByteBuffer dst = encodeString(src, charset);
835 ChannelBuffer result = wrappedBuffer(endianness, dst.array());
836 result.writerIndex(dst.remaining());
837 return result;
838 }
839
840
841
842
843 @Deprecated
844 public static ChannelBuffer copiedBuffer(String string, String charsetName) {
845 return copiedBuffer(string, Charset.forName(charsetName));
846 }
847
848
849
850
851 @Deprecated
852 public static ChannelBuffer copiedBuffer(ByteOrder endianness, String string, String charsetName) {
853 return copiedBuffer(endianness, string, Charset.forName(charsetName));
854 }
855
856
857
858
859
860
861
862 public static ChannelBuffer unmodifiableBuffer(ChannelBuffer buffer) {
863 if (buffer instanceof ReadOnlyChannelBuffer) {
864 buffer = ((ReadOnlyChannelBuffer) buffer).unwrap();
865 }
866 return new ReadOnlyChannelBuffer(buffer);
867 }
868
869
870
871
872 public static ChannelBuffer hexDump(String hexString) {
873 int len = hexString.length();
874 byte[] hexData = new byte[len / 2];
875 for (int i = 0; i < len; i += 2) {
876 hexData[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
877 + Character.digit(hexString.charAt(i + 1), 16));
878 }
879 return wrappedBuffer(hexData);
880 }
881
882
883
884
885
886 public static String hexDump(ChannelBuffer buffer) {
887 return hexDump(buffer, buffer.readerIndex(), buffer.readableBytes());
888 }
889
890
891
892
893
894 public static String hexDump(ChannelBuffer buffer, int fromIndex, int length) {
895 if (length < 0) {
896 throw new IllegalArgumentException("length: " + length);
897 }
898 if (length == 0) {
899 return "";
900 }
901
902 int endIndex = fromIndex + length;
903 char[] buf = new char[length << 1];
904
905 int srcIdx = fromIndex;
906 int dstIdx = 0;
907 for (; srcIdx < endIndex; srcIdx ++, dstIdx += 2) {
908 System.arraycopy(
909 HEXDUMP_TABLE, buffer.getUnsignedByte(srcIdx) << 1,
910 buf, dstIdx, 2);
911 }
912
913 return new String(buf);
914 }
915
916
917
918
919
920 public static int hashCode(ChannelBuffer buffer) {
921 final int aLen = buffer.readableBytes();
922 final int intCount = aLen >>> 2;
923 final int byteCount = aLen & 3;
924
925 int hashCode = 1;
926 int arrayIndex = buffer.readerIndex();
927 if (buffer.order() == BIG_ENDIAN) {
928 for (int i = intCount; i > 0; i --) {
929 hashCode = 31 * hashCode + buffer.getInt(arrayIndex);
930 arrayIndex += 4;
931 }
932 } else {
933 for (int i = intCount; i > 0; i --) {
934 hashCode = 31 * hashCode + swapInt(buffer.getInt(arrayIndex));
935 arrayIndex += 4;
936 }
937 }
938
939 for (int i = byteCount; i > 0; i --) {
940 hashCode = 31 * hashCode + buffer.getByte(arrayIndex ++);
941 }
942
943 if (hashCode == 0) {
944 hashCode = 1;
945 }
946
947 return hashCode;
948 }
949
950
951
952
953
954
955 public static boolean equals(ChannelBuffer bufferA, ChannelBuffer bufferB) {
956 final int aLen = bufferA.readableBytes();
957 if (aLen != bufferB.readableBytes()) {
958 return false;
959 }
960
961 final int longCount = aLen >>> 3;
962 final int byteCount = aLen & 7;
963
964 int aIndex = bufferA.readerIndex();
965 int bIndex = bufferB.readerIndex();
966
967 if (bufferA.order() == bufferB.order()) {
968 for (int i = longCount; i > 0; i --) {
969 if (bufferA.getLong(aIndex) != bufferB.getLong(bIndex)) {
970 return false;
971 }
972 aIndex += 8;
973 bIndex += 8;
974 }
975 } else {
976 for (int i = longCount; i > 0; i --) {
977 if (bufferA.getLong(aIndex) != swapLong(bufferB.getLong(bIndex))) {
978 return false;
979 }
980 aIndex += 8;
981 bIndex += 8;
982 }
983 }
984
985 for (int i = byteCount; i > 0; i --) {
986 if (bufferA.getByte(aIndex) != bufferB.getByte(bIndex)) {
987 return false;
988 }
989 aIndex ++;
990 bIndex ++;
991 }
992
993 return true;
994 }
995
996
997
998
999
1000 public static int compare(ChannelBuffer bufferA, ChannelBuffer bufferB) {
1001 final int aLen = bufferA.readableBytes();
1002 final int bLen = bufferB.readableBytes();
1003 final int minLength = Math.min(aLen, bLen);
1004 final int uintCount = minLength >>> 2;
1005 final int byteCount = minLength & 3;
1006
1007 int aIndex = bufferA.readerIndex();
1008 int bIndex = bufferB.readerIndex();
1009
1010 if (bufferA.order() == bufferB.order()) {
1011 for (int i = uintCount; i > 0; i --) {
1012 long va = bufferA.getUnsignedInt(aIndex);
1013 long vb = bufferB.getUnsignedInt(bIndex);
1014 if (va > vb) {
1015 return 1;
1016 }
1017 if (va < vb) {
1018 return -1;
1019 }
1020 aIndex += 4;
1021 bIndex += 4;
1022 }
1023 } else {
1024 for (int i = uintCount; i > 0; i --) {
1025 long va = bufferA.getUnsignedInt(aIndex);
1026 long vb = swapInt(bufferB.getInt(bIndex)) & 0xFFFFFFFFL;
1027 if (va > vb) {
1028 return 1;
1029 }
1030 if (va < vb) {
1031 return -1;
1032 }
1033 aIndex += 4;
1034 bIndex += 4;
1035 }
1036 }
1037
1038 for (int i = byteCount; i > 0; i --) {
1039 short va = bufferA.getUnsignedByte(aIndex);
1040 short vb = bufferB.getUnsignedByte(bIndex);
1041 if (va > vb) {
1042 return 1;
1043 }
1044 if (va < vb) {
1045 return -1;
1046 }
1047 aIndex ++;
1048 bIndex ++;
1049 }
1050
1051 return aLen - bLen;
1052 }
1053
1054
1055
1056
1057
1058 public static int indexOf(ChannelBuffer buffer, int fromIndex, int toIndex, byte value) {
1059 if (fromIndex <= toIndex) {
1060 return firstIndexOf(buffer, fromIndex, toIndex, value);
1061 } else {
1062 return lastIndexOf(buffer, fromIndex, toIndex, value);
1063 }
1064 }
1065
1066
1067
1068
1069
1070 public static int indexOf(
1071 ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
1072 if (fromIndex <= toIndex) {
1073 return firstIndexOf(buffer, fromIndex, toIndex, indexFinder);
1074 } else {
1075 return lastIndexOf(buffer, fromIndex, toIndex, indexFinder);
1076 }
1077 }
1078
1079
1080
1081
1082 public static short swapShort(short value) {
1083 return (short) (value << 8 | value >>> 8 & 0xff);
1084 }
1085
1086
1087
1088
1089 public static int swapMedium(int value) {
1090 return value << 16 & 0xff0000 | value & 0xff00 | value >>> 16 & 0xff;
1091 }
1092
1093
1094
1095
1096 public static int swapInt(int value) {
1097 return swapShort((short) value) << 16 |
1098 swapShort((short) (value >>> 16)) & 0xffff;
1099 }
1100
1101
1102
1103
1104 public static long swapLong(long value) {
1105 return (long) swapInt((int) value) << 32 |
1106 swapInt((int) (value >>> 32)) & 0xffffffffL;
1107 }
1108
1109 private static int firstIndexOf(ChannelBuffer buffer, int fromIndex, int toIndex, byte value) {
1110 fromIndex = Math.max(fromIndex, 0);
1111 if (fromIndex >= toIndex || buffer.capacity() == 0) {
1112 return -1;
1113 }
1114
1115 for (int i = fromIndex; i < toIndex; i ++) {
1116 if (buffer.getByte(i) == value) {
1117 return i;
1118 }
1119 }
1120
1121 return -1;
1122 }
1123
1124 private static int lastIndexOf(ChannelBuffer buffer, int fromIndex, int toIndex, byte value) {
1125 fromIndex = Math.min(fromIndex, buffer.capacity());
1126 if (fromIndex < 0 || buffer.capacity() == 0) {
1127 return -1;
1128 }
1129
1130 for (int i = fromIndex - 1; i >= toIndex; i --) {
1131 if (buffer.getByte(i) == value) {
1132 return i;
1133 }
1134 }
1135
1136 return -1;
1137 }
1138
1139 private static int firstIndexOf(
1140 ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
1141 fromIndex = Math.max(fromIndex, 0);
1142 if (fromIndex >= toIndex || buffer.capacity() == 0) {
1143 return -1;
1144 }
1145
1146 for (int i = fromIndex; i < toIndex; i ++) {
1147 if (indexFinder.find(buffer, i)) {
1148 return i;
1149 }
1150 }
1151
1152 return -1;
1153 }
1154
1155 private static int lastIndexOf(
1156 ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
1157 fromIndex = Math.min(fromIndex, buffer.capacity());
1158 if (fromIndex < 0 || buffer.capacity() == 0) {
1159 return -1;
1160 }
1161
1162 for (int i = fromIndex - 1; i >= toIndex; i --) {
1163 if (indexFinder.find(buffer, i)) {
1164 return i;
1165 }
1166 }
1167
1168 return -1;
1169 }
1170
1171 static ByteBuffer encodeString(CharBuffer src, Charset charset) {
1172 final CharsetEncoder encoder = CharsetUtil.getEncoder(charset);
1173 final ByteBuffer dst = ByteBuffer.allocate(
1174 (int) ((double) src.remaining() * encoder.maxBytesPerChar()));
1175 try {
1176 CoderResult cr = encoder.encode(src, dst, true);
1177 if (!cr.isUnderflow()) {
1178 cr.throwException();
1179 }
1180 cr = encoder.flush(dst);
1181 if (!cr.isUnderflow()) {
1182 cr.throwException();
1183 }
1184 } catch (CharacterCodingException x) {
1185 throw new IllegalStateException(x);
1186 }
1187 dst.flip();
1188 return dst;
1189 }
1190
1191 static String decodeString(ByteBuffer src, Charset charset) {
1192 final CharsetDecoder decoder = CharsetUtil.getDecoder(charset);
1193 final CharBuffer dst = CharBuffer.allocate(
1194 (int) ((double) src.remaining() * decoder.maxCharsPerByte()));
1195 try {
1196 CoderResult cr = decoder.decode(src, dst, true);
1197 if (!cr.isUnderflow()) {
1198 cr.throwException();
1199 }
1200 cr = decoder.flush(dst);
1201 if (!cr.isUnderflow()) {
1202 cr.throwException();
1203 }
1204 } catch (CharacterCodingException x) {
1205 throw new IllegalStateException(x);
1206 }
1207 return dst.flip().toString();
1208 }
1209
1210 private ChannelBuffers() {
1211
1212 }
1213 }