1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.core.buffer;
21
22 import java.io.EOFException;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.ObjectInputStream;
26 import java.io.ObjectOutputStream;
27 import java.io.ObjectStreamClass;
28 import java.io.OutputStream;
29 import java.io.Serializable;
30 import java.io.StreamCorruptedException;
31 import java.nio.BufferOverflowException;
32 import java.nio.BufferUnderflowException;
33 import java.nio.ByteBuffer;
34 import java.nio.ByteOrder;
35 import java.nio.CharBuffer;
36 import java.nio.DoubleBuffer;
37 import java.nio.FloatBuffer;
38 import java.nio.IntBuffer;
39 import java.nio.LongBuffer;
40 import java.nio.ShortBuffer;
41 import java.nio.charset.CharacterCodingException;
42 import java.nio.charset.CharsetDecoder;
43 import java.nio.charset.CharsetEncoder;
44 import java.nio.charset.CoderResult;
45 import java.nio.charset.StandardCharsets;
46 import java.util.EnumSet;
47 import java.util.Set;
48
49
50
51
52
53
54
55
56
57
58 public abstract class AbstractIoBuffer extends IoBuffer {
59
60 private final boolean derived;
61
62
63 private boolean autoExpand;
64
65
66 private boolean autoShrink;
67
68
69 private boolean recapacityAllowed = true;
70
71
72 private int minimumCapacity;
73
74
75 private static final long BYTE_MASK = 0xFFL;
76
77
78 private static final long SHORT_MASK = 0xFFFFL;
79
80
81 private static final long INT_MASK = 0xFFFFFFFFL;
82
83
84
85
86
87 private int mark = -1;
88
89
90
91
92
93
94
95 protected AbstractIoBuffer(IoBufferAllocator allocator, int initialCapacity) {
96 setAllocator(allocator);
97 this.recapacityAllowed = true;
98 this.derived = false;
99 this.minimumCapacity = initialCapacity;
100 }
101
102
103
104
105
106
107
108 protected AbstractIoBuffer../../../../../org/apache/mina/core/buffer/AbstractIoBuffer.html#AbstractIoBuffer">AbstractIoBuffer(AbstractIoBuffer parent) {
109 setAllocator(IoBuffer.getAllocator());
110 this.recapacityAllowed = false;
111 this.derived = true;
112 this.minimumCapacity = parent.minimumCapacity;
113 }
114
115
116
117
118 @Override
119 public final boolean isDirect() {
120 return buf().isDirect();
121 }
122
123
124
125
126 @Override
127 public final boolean isReadOnly() {
128 return buf().isReadOnly();
129 }
130
131
132
133
134
135
136 protected abstract void buf(ByteBuffer newBuf);
137
138
139
140
141 @Override
142 public final int minimumCapacity() {
143 return minimumCapacity;
144 }
145
146
147
148
149 @Override
150 public final IoBuffer minimumCapacity(int minimumCapacity) {
151 if (minimumCapacity < 0) {
152 throw new IllegalArgumentException("minimumCapacity: " + minimumCapacity);
153 }
154 this.minimumCapacity = minimumCapacity;
155 return this;
156 }
157
158
159
160
161 @Override
162 public final int capacity() {
163 return buf().capacity();
164 }
165
166
167
168
169 @Override
170 public final IoBuffer capacity(int newCapacity) {
171 if (!recapacityAllowed) {
172 throw new IllegalStateException("Derived buffers and their parent can't be expanded.");
173 }
174
175
176 if (newCapacity > capacity()) {
177
178
179 int pos = position();
180 int limit = limit();
181 ByteOrder bo = order();
182
183
184 ByteBuffer oldBuf = buf();
185 ByteBuffer newBuf = getAllocator().allocateNioBuffer(newCapacity, isDirect());
186 oldBuf.clear();
187 newBuf.put(oldBuf);
188 buf(newBuf);
189
190
191 buf().limit(limit);
192 if (mark >= 0) {
193 buf().position(mark);
194 buf().mark();
195 }
196 buf().position(pos);
197 buf().order(bo);
198 }
199
200 return this;
201 }
202
203
204
205
206 @Override
207 public final boolean isAutoExpand() {
208 return autoExpand && recapacityAllowed;
209 }
210
211
212
213
214 @Override
215 public final boolean isAutoShrink() {
216 return autoShrink && recapacityAllowed;
217 }
218
219
220
221
222 @Override
223 public final boolean isDerived() {
224 return derived;
225 }
226
227
228
229
230 @Override
231 public final IoBuffer setAutoExpand(boolean autoExpand) {
232 if (!recapacityAllowed) {
233 throw new IllegalStateException("Derived buffers and their parent can't be expanded.");
234 }
235 this.autoExpand = autoExpand;
236 return this;
237 }
238
239
240
241
242 @Override
243 public final IoBuffer setAutoShrink(boolean autoShrink) {
244 if (!recapacityAllowed) {
245 throw new IllegalStateException("Derived buffers and their parent can't be shrinked.");
246 }
247 this.autoShrink = autoShrink;
248 return this;
249 }
250
251
252
253
254 @Override
255 public final IoBuffer expand(int expectedRemaining) {
256 return expand(position(), expectedRemaining, false);
257 }
258
259 private IoBuffer expand(int expectedRemaining, boolean autoExpand) {
260 return expand(position(), expectedRemaining, autoExpand);
261 }
262
263
264
265
266 @Override
267 public final IoBuffer expand(int pos, int expectedRemaining) {
268 return expand(pos, expectedRemaining, false);
269 }
270
271 private IoBuffer expand(int pos, int expectedRemaining, boolean autoExpand) {
272 if (!recapacityAllowed) {
273 throw new IllegalStateException("Derived buffers and their parent can't be expanded.");
274 }
275
276 int end = pos + expectedRemaining;
277 int newCapacity;
278
279 if (autoExpand) {
280 newCapacity = IoBuffer.normalizeCapacity(end);
281 } else {
282 newCapacity = end;
283 }
284 if (newCapacity > capacity()) {
285
286 capacity(newCapacity);
287 }
288
289 if (end > limit()) {
290
291 buf().limit(end);
292 }
293 return this;
294 }
295
296
297
298
299 @Override
300 public final IoBuffer shrink() {
301
302 if (!recapacityAllowed) {
303 throw new IllegalStateException("Derived buffers and their parent can't be expanded.");
304 }
305
306 int position = position();
307 int capacity = capacity();
308 int limit = limit();
309
310 if (capacity == limit) {
311 return this;
312 }
313
314 int newCapacity = capacity;
315 int minCapacity = Math.max(minimumCapacity, limit);
316
317 for (;;) {
318 if (newCapacity >>> 1 < minCapacity) {
319 break;
320 }
321
322 newCapacity >>>= 1;
323
324 if (minCapacity == 0) {
325 break;
326 }
327 }
328
329 newCapacity = Math.max(minCapacity, newCapacity);
330
331 if (newCapacity == capacity) {
332 return this;
333 }
334
335
336
337 ByteOrder bo = order();
338
339
340 ByteBuffer oldBuf = buf();
341 ByteBuffer newBuf = getAllocator().allocateNioBuffer(newCapacity, isDirect());
342 oldBuf.position(0);
343 oldBuf.limit(limit);
344 newBuf.put(oldBuf);
345 buf(newBuf);
346
347
348 buf().position(position);
349 buf().limit(limit);
350 buf().order(bo);
351 mark = -1;
352
353 return this;
354 }
355
356
357
358
359 @Override
360 public final int position() {
361 return buf().position();
362 }
363
364
365
366
367 @Override
368 public final IoBuffer position(int newPosition) {
369 autoExpand(newPosition, 0);
370 buf().position(newPosition);
371
372 if (mark > newPosition) {
373 mark = -1;
374 }
375
376 return this;
377 }
378
379
380
381
382 @Override
383 public final int limit() {
384 return buf().limit();
385 }
386
387
388
389
390 @Override
391 public final IoBuffer limit(int newLimit) {
392 autoExpand(newLimit, 0);
393 buf().limit(newLimit);
394 if (mark > newLimit) {
395 mark = -1;
396 }
397 return this;
398 }
399
400
401
402
403 @Override
404 public final IoBuffer mark() {
405 ByteBuffer byteBuffer = buf();
406 byteBuffer.mark();
407 mark = byteBuffer.position();
408
409 return this;
410 }
411
412
413
414
415 @Override
416 public final int markValue() {
417 return mark;
418 }
419
420
421
422
423 @Override
424 public final IoBuffer reset() {
425 buf().reset();
426 return this;
427 }
428
429
430
431
432 @Override
433 public final IoBuffer clear() {
434 buf().clear();
435 mark = -1;
436 return this;
437 }
438
439
440
441
442 @Override
443 public final IoBuffer sweep() {
444 clear();
445 return fillAndReset(remaining());
446 }
447
448
449
450
451 @Override
452 public final IoBuffer sweep(byte value) {
453 clear();
454 return fillAndReset(value, remaining());
455 }
456
457
458
459
460 @Override
461 public final IoBuffer flip() {
462 buf().flip();
463 mark = -1;
464 return this;
465 }
466
467
468
469
470 @Override
471 public final IoBuffer rewind() {
472 buf().rewind();
473 mark = -1;
474 return this;
475 }
476
477
478
479
480 @Override
481 public final int remaining() {
482 ByteBuffer byteBuffer = buf();
483
484 return byteBuffer.limit() - byteBuffer.position();
485 }
486
487
488
489
490 @Override
491 public final boolean hasRemaining() {
492 ByteBuffer byteBuffer = buf();
493
494 return byteBuffer.limit() > byteBuffer.position();
495 }
496
497
498
499
500 @Override
501 public final byte get() {
502 return buf().get();
503 }
504
505
506
507
508 @Override
509 public final short getUnsigned() {
510 return (short) (get() & 0xff);
511 }
512
513
514
515
516 @Override
517 public final IoBuffer put(byte b) {
518 autoExpand(1);
519 buf().put(b);
520 return this;
521 }
522
523
524
525
526 @Override
527 public IoBuffer putUnsigned(byte value) {
528 autoExpand(1);
529 buf().put((byte) (value & 0xff));
530 return this;
531 }
532
533
534
535
536 @Override
537 public IoBuffer putUnsigned(int index, byte value) {
538 autoExpand(index, 1);
539 buf().put(index, (byte) (value & 0xff));
540 return this;
541 }
542
543
544
545
546 @Override
547 public IoBuffer putUnsigned(short value) {
548 autoExpand(1);
549 buf().put((byte) (value & 0x00ff));
550 return this;
551 }
552
553
554
555
556 @Override
557 public IoBuffer putUnsigned(int index, short value) {
558 autoExpand(index, 1);
559 buf().put(index, (byte) (value & 0x00ff));
560 return this;
561 }
562
563
564
565
566 @Override
567 public IoBuffer putUnsigned(int value) {
568 autoExpand(1);
569 buf().put((byte) (value & 0x000000ff));
570 return this;
571 }
572
573
574
575
576 @Override
577 public IoBuffer putUnsigned(int index, int value) {
578 autoExpand(index, 1);
579 buf().put(index, (byte) (value & 0x000000ff));
580 return this;
581 }
582
583
584
585
586 @Override
587 public IoBuffer putUnsigned(long value) {
588 autoExpand(1);
589 buf().put((byte) (value & 0x00000000000000ffL));
590 return this;
591 }
592
593
594
595
596 @Override
597 public IoBuffer putUnsigned(int index, long value) {
598 autoExpand(index, 1);
599 buf().put(index, (byte) (value & 0x00000000000000ffL));
600 return this;
601 }
602
603
604
605
606 @Override
607 public final byte get(int index) {
608 return buf().get(index);
609 }
610
611
612
613
614 @Override
615 public final short getUnsigned(int index) {
616 return (short) (get(index) & 0xff);
617 }
618
619
620
621
622 @Override
623 public final IoBuffer put(int index, byte b) {
624 autoExpand(index, 1);
625 buf().put(index, b);
626 return this;
627 }
628
629
630
631
632 @Override
633 public final IoBuffer get(byte[] dst, int offset, int length) {
634 buf().get(dst, offset, length);
635 return this;
636 }
637
638
639
640
641 @Override
642 public final IoBuffer put(ByteBuffer src) {
643 autoExpand(src.remaining());
644 buf().put(src);
645 return this;
646 }
647
648
649
650
651 @Override
652 public final IoBuffer put(byte[] src, int offset, int length) {
653 autoExpand(length);
654 buf().put(src, offset, length);
655 return this;
656 }
657
658
659
660
661 @Override
662 public final IoBuffer compact() {
663 int remaining = remaining();
664 int capacity = capacity();
665
666 if (capacity == 0) {
667 return this;
668 }
669
670 if (isAutoShrink() && remaining <= capacity >>> 2 && capacity > minimumCapacity) {
671 int newCapacity = capacity;
672 int minCapacity = Math.max(minimumCapacity, remaining << 1);
673 for (;;) {
674 if (newCapacity >>> 1 < minCapacity) {
675 break;
676 }
677 newCapacity >>>= 1;
678 }
679
680 newCapacity = Math.max(minCapacity, newCapacity);
681
682 if (newCapacity == capacity) {
683 return this;
684 }
685
686
687
688 ByteOrder bo = order();
689
690
691 if (remaining > newCapacity) {
692 throw new IllegalStateException("The amount of the remaining bytes is greater than "
693 + "the new capacity.");
694 }
695
696
697 ByteBuffer oldBuf = buf();
698 ByteBuffer newBuf = getAllocator().allocateNioBuffer(newCapacity, isDirect());
699 newBuf.put(oldBuf);
700 buf(newBuf);
701
702
703 buf().order(bo);
704 } else {
705 buf().compact();
706 }
707 mark = -1;
708 return this;
709 }
710
711
712
713
714 @Override
715 public final ByteOrder order() {
716 return buf().order();
717 }
718
719
720
721
722 @Override
723 public final IoBuffer order(ByteOrder bo) {
724 buf().order(bo);
725 return this;
726 }
727
728
729
730
731 @Override
732 public final char getChar() {
733 return buf().getChar();
734 }
735
736
737
738
739 @Override
740 public final IoBuffer putChar(char value) {
741 autoExpand(2);
742 buf().putChar(value);
743 return this;
744 }
745
746
747
748
749 @Override
750 public final char getChar(int index) {
751 return buf().getChar(index);
752 }
753
754
755
756
757 @Override
758 public final IoBuffer putChar(int index, char value) {
759 autoExpand(index, 2);
760 buf().putChar(index, value);
761 return this;
762 }
763
764
765
766
767 @Override
768 public final CharBuffer asCharBuffer() {
769 return buf().asCharBuffer();
770 }
771
772
773
774
775 @Override
776 public final short getShort() {
777 return buf().getShort();
778 }
779
780
781
782
783 @Override
784 public final IoBuffer putShort(short value) {
785 autoExpand(2);
786 buf().putShort(value);
787 return this;
788 }
789
790
791
792
793 @Override
794 public final short getShort(int index) {
795 return buf().getShort(index);
796 }
797
798
799
800
801 @Override
802 public final IoBuffer putShort(int index, short value) {
803 autoExpand(index, 2);
804 buf().putShort(index, value);
805 return this;
806 }
807
808
809
810
811 @Override
812 public final ShortBuffer asShortBuffer() {
813 return buf().asShortBuffer();
814 }
815
816
817
818
819 @Override
820 public final int getInt() {
821 return buf().getInt();
822 }
823
824
825
826
827 @Override
828 public final IoBuffer putInt(int value) {
829 autoExpand(4);
830 buf().putInt(value);
831 return this;
832 }
833
834
835
836
837 @Override
838 public final IoBuffer putUnsignedInt(byte value) {
839 autoExpand(4);
840 buf().putInt(value & 0x00ff);
841 return this;
842 }
843
844
845
846
847 @Override
848 public final IoBuffer putUnsignedInt(int index, byte value) {
849 autoExpand(index, 4);
850 buf().putInt(index, value & 0x00ff);
851 return this;
852 }
853
854
855
856
857 @Override
858 public final IoBuffer putUnsignedInt(short value) {
859 autoExpand(4);
860 buf().putInt(value & 0x0000ffff);
861 return this;
862 }
863
864
865
866
867 @Override
868 public final IoBuffer putUnsignedInt(int index, short value) {
869 autoExpand(index, 4);
870 buf().putInt(index, value & 0x0000ffff);
871 return this;
872 }
873
874
875
876
877 @Override
878 public final IoBuffer putUnsignedInt(int value) {
879 return putInt(value);
880 }
881
882
883
884
885 @Override
886 public final IoBuffer putUnsignedInt(int index, int value) {
887 return putInt(index, value);
888 }
889
890
891
892
893 @Override
894 public final IoBuffer putUnsignedInt(long value) {
895 autoExpand(4);
896 buf().putInt((int) (value & 0x00000000ffffffff));
897 return this;
898 }
899
900
901
902
903 @Override
904 public final IoBuffer putUnsignedInt(int index, long value) {
905 autoExpand(index, 4);
906 buf().putInt(index, (int) (value & 0x00000000ffffffffL));
907 return this;
908 }
909
910
911
912
913 @Override
914 public final IoBuffer putUnsignedShort(byte value) {
915 autoExpand(2);
916 buf().putShort((short) (value & 0x00ff));
917 return this;
918 }
919
920
921
922
923 @Override
924 public final IoBuffer putUnsignedShort(int index, byte value) {
925 autoExpand(index, 2);
926 buf().putShort(index, (short) (value & 0x00ff));
927 return this;
928 }
929
930
931
932
933 @Override
934 public final IoBuffer putUnsignedShort(short value) {
935 return putShort(value);
936 }
937
938
939
940
941 @Override
942 public final IoBuffer putUnsignedShort(int index, short value) {
943 return putShort(index, value);
944 }
945
946
947
948
949 @Override
950 public final IoBuffer putUnsignedShort(int value) {
951 autoExpand(2);
952 buf().putShort((short) value);
953 return this;
954 }
955
956
957
958
959 @Override
960 public final IoBuffer putUnsignedShort(int index, int value) {
961 autoExpand(index, 2);
962 buf().putShort(index, (short) value);
963 return this;
964 }
965
966
967
968
969 @Override
970 public final IoBuffer putUnsignedShort(long value) {
971 autoExpand(2);
972 buf().putShort((short) (value));
973 return this;
974 }
975
976
977
978
979 @Override
980 public final IoBuffer putUnsignedShort(int index, long value) {
981 autoExpand(index, 2);
982 buf().putShort(index, (short) (value));
983 return this;
984 }
985
986
987
988
989 @Override
990 public final int getInt(int index) {
991 return buf().getInt(index);
992 }
993
994
995
996
997 @Override
998 public final IoBuffer putInt(int index, int value) {
999 autoExpand(index, 4);
1000 buf().putInt(index, value);
1001 return this;
1002 }
1003
1004
1005
1006
1007 @Override
1008 public final IntBuffer asIntBuffer() {
1009 return buf().asIntBuffer();
1010 }
1011
1012
1013
1014
1015 @Override
1016 public final long getLong() {
1017 return buf().getLong();
1018 }
1019
1020
1021
1022
1023 @Override
1024 public final IoBuffer putLong(long value) {
1025 autoExpand(8);
1026 buf().putLong(value);
1027 return this;
1028 }
1029
1030
1031
1032
1033 @Override
1034 public final long getLong(int index) {
1035 return buf().getLong(index);
1036 }
1037
1038
1039
1040
1041 @Override
1042 public final IoBuffer putLong(int index, long value) {
1043 autoExpand(index, 8);
1044 buf().putLong(index, value);
1045 return this;
1046 }
1047
1048
1049
1050
1051 @Override
1052 public final LongBuffer asLongBuffer() {
1053 return buf().asLongBuffer();
1054 }
1055
1056
1057
1058
1059 @Override
1060 public final float getFloat() {
1061 return buf().getFloat();
1062 }
1063
1064
1065
1066
1067 @Override
1068 public final IoBuffer putFloat(float value) {
1069 autoExpand(4);
1070 buf().putFloat(value);
1071 return this;
1072 }
1073
1074
1075
1076
1077 @Override
1078 public final float getFloat(int index) {
1079 return buf().getFloat(index);
1080 }
1081
1082
1083
1084
1085 @Override
1086 public final IoBuffer putFloat(int index, float value) {
1087 autoExpand(index, 4);
1088 buf().putFloat(index, value);
1089 return this;
1090 }
1091
1092
1093
1094
1095 @Override
1096 public final FloatBuffer asFloatBuffer() {
1097 return buf().asFloatBuffer();
1098 }
1099
1100
1101
1102
1103 @Override
1104 public final double getDouble() {
1105 return buf().getDouble();
1106 }
1107
1108
1109
1110
1111 @Override
1112 public final IoBuffer putDouble(double value) {
1113 autoExpand(8);
1114 buf().putDouble(value);
1115 return this;
1116 }
1117
1118
1119
1120
1121 @Override
1122 public final double getDouble(int index) {
1123 return buf().getDouble(index);
1124 }
1125
1126
1127
1128
1129 @Override
1130 public final IoBuffer putDouble(int index, double value) {
1131 autoExpand(index, 8);
1132 buf().putDouble(index, value);
1133 return this;
1134 }
1135
1136
1137
1138
1139 @Override
1140 public final DoubleBuffer asDoubleBuffer() {
1141 return buf().asDoubleBuffer();
1142 }
1143
1144
1145
1146
1147 @Override
1148 public final IoBuffer asReadOnlyBuffer() {
1149 recapacityAllowed = false;
1150 return asReadOnlyBuffer0();
1151 }
1152
1153
1154
1155
1156
1157
1158
1159 protected abstract IoBuffer asReadOnlyBuffer0();
1160
1161
1162
1163
1164 @Override
1165 public final IoBuffer duplicate() {
1166 recapacityAllowed = false;
1167 return duplicate0();
1168 }
1169
1170
1171
1172
1173
1174
1175
1176 protected abstract IoBuffer duplicate0();
1177
1178
1179
1180
1181 @Override
1182 public final IoBuffer slice() {
1183 recapacityAllowed = false;
1184 return slice0();
1185 }
1186
1187
1188
1189
1190 @Override
1191 public final IoBuffer getSlice(int index, int length) {
1192 if (length < 0) {
1193 throw new IllegalArgumentException("length: " + length);
1194 }
1195
1196 int pos = position();
1197 int limit = limit();
1198
1199 if (index > limit) {
1200 throw new IllegalArgumentException("index: " + index);
1201 }
1202
1203 int endIndex = index + length;
1204
1205 if (endIndex > limit) {
1206 throw new IndexOutOfBoundsException("index + length (" + endIndex + ") is greater " + "than limit ("
1207 + limit + ").");
1208 }
1209
1210 clear();
1211 limit(endIndex);
1212 position(index);
1213
1214 IoBuffer slice = slice();
1215 limit(limit);
1216 position(pos);
1217
1218 return slice;
1219 }
1220
1221
1222
1223
1224 @Override
1225 public final IoBuffer getSlice(int length) {
1226 if (length < 0) {
1227 throw new IllegalArgumentException("length: " + length);
1228 }
1229 int pos = position();
1230 int limit = limit();
1231 int nextPos = pos + length;
1232 if (limit < nextPos) {
1233 throw new IndexOutOfBoundsException("position + length (" + nextPos + ") is greater " + "than limit ("
1234 + limit + ").");
1235 }
1236
1237 limit(pos + length);
1238 IoBuffer slice = slice();
1239 position(nextPos);
1240 limit(limit);
1241 return slice;
1242 }
1243
1244
1245
1246
1247
1248
1249
1250 protected abstract IoBuffer slice0();
1251
1252
1253
1254
1255 @Override
1256 public int hashCode() {
1257 int h = 1;
1258 int p = position();
1259 for (int i = limit() - 1; i >= p; i--) {
1260 h = 31 * h + get(i);
1261 }
1262 return h;
1263 }
1264
1265
1266
1267
1268 @Override
1269 public boolean equals(Object o) {
1270 if (!(o instanceof IoBuffer)) {
1271 return false;
1272 }
1273
1274 IoBuffer../../../../../org/apache/mina/core/buffer/IoBuffer.html#IoBuffer">IoBuffer that = (IoBuffer) o;
1275 if (this.remaining() != that.remaining()) {
1276 return false;
1277 }
1278
1279 int p = this.position();
1280 for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
1281 byte v1 = this.get(i);
1282 byte v2 = that.get(j);
1283 if (v1 != v2) {
1284 return false;
1285 }
1286 }
1287 return true;
1288 }
1289
1290
1291
1292
1293 @Override
1294 public int compareTo(IoBuffer that) {
1295 int n = this.position() + Math.min(this.remaining(), that.remaining());
1296 for (int i = this.position(), j = that.position(); i < n; i++, j++) {
1297 byte v1 = this.get(i);
1298 byte v2 = that.get(j);
1299 if (v1 == v2) {
1300 continue;
1301 }
1302 if (v1 < v2) {
1303 return -1;
1304 }
1305
1306 return +1;
1307 }
1308 return this.remaining() - that.remaining();
1309 }
1310
1311
1312
1313
1314 @Override
1315 public String toString() {
1316 StringBuilder buf = new StringBuilder();
1317 if (isDirect()) {
1318 buf.append("DirectBuffer");
1319 } else {
1320 buf.append("HeapBuffer");
1321 }
1322 buf.append("[pos=");
1323 buf.append(position());
1324 buf.append(" lim=");
1325 buf.append(limit());
1326 buf.append(" cap=");
1327 buf.append(capacity());
1328 buf.append(": ");
1329 buf.append(getHexDump(16));
1330 buf.append(']');
1331 return buf.toString();
1332 }
1333
1334
1335
1336
1337 @Override
1338 public IoBuffer get(byte[] dst) {
1339 return get(dst, 0, dst.length);
1340 }
1341
1342
1343
1344
1345 @Override
1346 public IoBufferef="../../../../../org/apache/mina/core/buffer/IoBuffer.html#IoBuffer">IoBuffer put(IoBuffer src) {
1347 return put(src.buf());
1348 }
1349
1350
1351
1352
1353 @Override
1354 public IoBuffer put(byte[] src) {
1355 return put(src, 0, src.length);
1356 }
1357
1358
1359
1360
1361 @Override
1362 public int getUnsignedShort() {
1363 return getShort() & 0xffff;
1364 }
1365
1366
1367
1368
1369 @Override
1370 public int getUnsignedShort(int index) {
1371 return getShort(index) & 0xffff;
1372 }
1373
1374
1375
1376
1377 @Override
1378 public long getUnsignedInt() {
1379 return getInt() & 0xffffffffL;
1380 }
1381
1382
1383
1384
1385 @Override
1386 public int getMediumInt() {
1387 byte b1 = get();
1388 byte b2 = get();
1389 byte b3 = get();
1390 if (ByteOrder.BIG_ENDIAN.equals(order())) {
1391 return getMediumInt(b1, b2, b3);
1392 }
1393
1394 return getMediumInt(b3, b2, b1);
1395 }
1396
1397
1398
1399
1400 @Override
1401 public int getUnsignedMediumInt() {
1402 int b1 = getUnsigned();
1403 int b2 = getUnsigned();
1404 int b3 = getUnsigned();
1405 if (ByteOrder.BIG_ENDIAN.equals(order())) {
1406 return b1 << 16 | b2 << 8 | b3;
1407 }
1408
1409 return b3 << 16 | b2 << 8 | b1;
1410 }
1411
1412
1413
1414
1415 @Override
1416 public int getMediumInt(int index) {
1417 byte b1 = get(index);
1418 byte b2 = get(index + 1);
1419 byte b3 = get(index + 2);
1420 if (ByteOrder.BIG_ENDIAN.equals(order())) {
1421 return getMediumInt(b1, b2, b3);
1422 }
1423
1424 return getMediumInt(b3, b2, b1);
1425 }
1426
1427
1428
1429
1430 @Override
1431 public int getUnsignedMediumInt(int index) {
1432 int b1 = getUnsigned(index);
1433 int b2 = getUnsigned(index + 1);
1434 int b3 = getUnsigned(index + 2);
1435
1436 if (ByteOrder.BIG_ENDIAN.equals(order())) {
1437 return b1 << 16 | b2 << 8 | b3;
1438 }
1439
1440 return b3 << 16 | b2 << 8 | b1;
1441 }
1442
1443 private int getMediumInt(byte b1, byte b2, byte b3) {
1444 int ret = b1 << 16 & 0xff0000 | b2 << 8 & 0xff00 | b3 & 0xff;
1445
1446 if ((b1 & 0x80) == 0x80) {
1447
1448 ret |= 0xff000000;
1449 }
1450 return ret;
1451 }
1452
1453
1454
1455
1456 @Override
1457 public IoBuffer putMediumInt(int value) {
1458 byte b1 = (byte) (value >> 16);
1459 byte b2 = (byte) (value >> 8);
1460 byte b3 = (byte) value;
1461
1462 if (ByteOrder.BIG_ENDIAN.equals(order())) {
1463 put(b1).put(b2).put(b3);
1464 } else {
1465 put(b3).put(b2).put(b1);
1466 }
1467
1468 return this;
1469 }
1470
1471
1472
1473
1474 @Override
1475 public IoBuffer putMediumInt(int index, int value) {
1476 byte b1 = (byte) (value >> 16);
1477 byte b2 = (byte) (value >> 8);
1478 byte b3 = (byte) value;
1479
1480 if (ByteOrder.BIG_ENDIAN.equals(order())) {
1481 put(index, b1).put(index + 1, b2).put(index + 2, b3);
1482 } else {
1483 put(index, b3).put(index + 1, b2).put(index + 2, b1);
1484 }
1485
1486 return this;
1487 }
1488
1489
1490
1491
1492 @Override
1493 public long getUnsignedInt(int index) {
1494 return getInt(index) & 0xffffffffL;
1495 }
1496
1497
1498
1499
1500 @Override
1501 public InputStream asInputStream() {
1502 return new InputStream() {
1503 @Override
1504 public int available() {
1505 return AbstractIoBuffer.this.remaining();
1506 }
1507
1508 @Override
1509 public synchronized void mark(int readlimit) {
1510 AbstractIoBuffer.this.mark();
1511 }
1512
1513 @Override
1514 public boolean markSupported() {
1515 return true;
1516 }
1517
1518 @Override
1519 public int read() {
1520 if (AbstractIoBuffer.this.hasRemaining()) {
1521 return AbstractIoBuffer.this.get() & 0xff;
1522 }
1523
1524 return -1;
1525 }
1526
1527 @Override
1528 public int read(byte[] b, int off, int len) {
1529 int remaining = AbstractIoBuffer.this.remaining();
1530 if (remaining > 0) {
1531 int readBytes = Math.min(remaining, len);
1532 AbstractIoBuffer.this.get(b, off, readBytes);
1533 return readBytes;
1534 }
1535
1536 return -1;
1537 }
1538
1539 @Override
1540 public synchronized void reset() {
1541 AbstractIoBuffer.this.reset();
1542 }
1543
1544 @Override
1545 public long skip(long n) {
1546 int bytes;
1547 if (n > Integer.MAX_VALUE) {
1548 bytes = AbstractIoBuffer.this.remaining();
1549 } else {
1550 bytes = Math.min(AbstractIoBuffer.this.remaining(), (int) n);
1551 }
1552 AbstractIoBuffer.this.skip(bytes);
1553 return bytes;
1554 }
1555 };
1556 }
1557
1558
1559
1560
1561 @Override
1562 public OutputStream asOutputStream() {
1563 return new OutputStream() {
1564 @Override
1565 public void write(byte[] b, int off, int len) {
1566 AbstractIoBuffer.this.put(b, off, len);
1567 }
1568
1569 @Override
1570 public void write(int b) {
1571 AbstractIoBuffer.this.put((byte) b);
1572 }
1573 };
1574 }
1575
1576
1577
1578
1579 @Override
1580 public String getHexDump() {
1581 return this.getHexDump(Integer.MAX_VALUE);
1582 }
1583
1584
1585
1586
1587 @Override
1588 public String getHexDump(int lengthLimit) {
1589 return IoBufferHexDumper.getHexdump(this, lengthLimit);
1590 }
1591
1592
1593
1594
1595 @Override
1596 public String getString(CharsetDecoder decoder) throws CharacterCodingException {
1597 if (!hasRemaining()) {
1598 return "";
1599 }
1600
1601 boolean utf16 =
1602 decoder.charset().equals(StandardCharsets.UTF_16) ||
1603 decoder.charset().equals(StandardCharsets.UTF_16BE) ||
1604 decoder.charset().equals(StandardCharsets.UTF_16LE);
1605
1606 int oldPos = position();
1607 int oldLimit = limit();
1608 int end = -1;
1609 int newPos;
1610
1611 if (!utf16) {
1612 end = indexOf((byte) 0x00);
1613 if (end < 0) {
1614 newPos = end = oldLimit;
1615 } else {
1616 newPos = end + 1;
1617 }
1618 } else {
1619 int i = oldPos;
1620 for (;;) {
1621 boolean wasZero = get(i) == 0;
1622 i++;
1623
1624 if (i >= oldLimit) {
1625 break;
1626 }
1627
1628 if (get(i) != 0) {
1629 i++;
1630 if (i >= oldLimit) {
1631 break;
1632 }
1633
1634 continue;
1635 }
1636
1637 if (wasZero) {
1638 end = i - 1;
1639 break;
1640 }
1641 }
1642
1643 if (end < 0) {
1644 newPos = end = oldPos + (oldLimit - oldPos & 0xFFFFFFFE);
1645 } else {
1646 if (end + 2 <= oldLimit) {
1647 newPos = end + 2;
1648 } else {
1649 newPos = end;
1650 }
1651 }
1652 }
1653
1654 if (oldPos == end) {
1655 position(newPos);
1656 return "";
1657 }
1658
1659 limit(end);
1660 decoder.reset();
1661
1662 int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1;
1663 CharBuffer out = CharBuffer.allocate(expectedLength);
1664 for (;;) {
1665 CoderResult cr;
1666 if (hasRemaining()) {
1667 cr = decoder.decode(buf(), out, true);
1668 } else {
1669 cr = decoder.flush(out);
1670 }
1671
1672 if (cr.isUnderflow()) {
1673 break;
1674 }
1675
1676 if (cr.isOverflow()) {
1677 CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength);
1678 out.flip();
1679 o.put(out);
1680 out = o;
1681 continue;
1682 }
1683
1684 if (cr.isError()) {
1685
1686 limit(oldLimit);
1687 position(oldPos);
1688 cr.throwException();
1689 }
1690 }
1691
1692 limit(oldLimit);
1693 position(newPos);
1694 return out.flip().toString();
1695 }
1696
1697
1698
1699
1700 @Override
1701 public String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException {
1702 checkFieldSize(fieldSize);
1703
1704 if (fieldSize == 0) {
1705 return "";
1706 }
1707
1708 if (!hasRemaining()) {
1709 return "";
1710 }
1711
1712 boolean utf16 = decoder.charset().equals(StandardCharsets.UTF_16) ||
1713 decoder.charset().equals(StandardCharsets.UTF_16BE) ||
1714 decoder.charset().equals(StandardCharsets.UTF_16LE);
1715
1716 if (utf16 && (fieldSize & 1) != 0) {
1717 throw new IllegalArgumentException("fieldSize is not even.");
1718 }
1719
1720 int oldPos = position();
1721 int oldLimit = limit();
1722 int end = oldPos + fieldSize;
1723
1724 if (oldLimit < end) {
1725 throw new BufferUnderflowException();
1726 }
1727
1728 int i;
1729
1730 if (!utf16) {
1731 for (i = oldPos; i < end; i++) {
1732 if (get(i) == 0) {
1733 break;
1734 }
1735 }
1736
1737 if (i == end) {
1738 limit(end);
1739 } else {
1740 limit(i);
1741 }
1742 } else {
1743 for (i = oldPos; i < end; i += 2) {
1744 if (get(i) == 0 && get(i + 1) == 0) {
1745 break;
1746 }
1747 }
1748
1749 if (i == end) {
1750 limit(end);
1751 } else {
1752 limit(i);
1753 }
1754 }
1755
1756 if (!hasRemaining()) {
1757 limit(oldLimit);
1758 position(end);
1759 return "";
1760 }
1761 decoder.reset();
1762
1763 int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1;
1764 CharBuffer out = CharBuffer.allocate(expectedLength);
1765 for (;;) {
1766 CoderResult cr;
1767 if (hasRemaining()) {
1768 cr = decoder.decode(buf(), out, true);
1769 } else {
1770 cr = decoder.flush(out);
1771 }
1772
1773 if (cr.isUnderflow()) {
1774 break;
1775 }
1776
1777 if (cr.isOverflow()) {
1778 CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength);
1779 out.flip();
1780 o.put(out);
1781 out = o;
1782 continue;
1783 }
1784
1785 if (cr.isError()) {
1786
1787 limit(oldLimit);
1788 position(oldPos);
1789 cr.throwException();
1790 }
1791 }
1792
1793 limit(oldLimit);
1794 position(end);
1795 return out.flip().toString();
1796 }
1797
1798
1799
1800
1801 @Override
1802 public IoBuffer putString(CharSequence val, CharsetEncoder encoder) throws CharacterCodingException {
1803 if (val.length() == 0) {
1804 return this;
1805 }
1806
1807 CharBuffer in = CharBuffer.wrap(val);
1808 encoder.reset();
1809
1810 int expandedState = 0;
1811
1812 for (;;) {
1813 CoderResult cr;
1814 if (in.hasRemaining()) {
1815 cr = encoder.encode(in, buf(), true);
1816 } else {
1817 cr = encoder.flush(buf());
1818 }
1819
1820 if (cr.isUnderflow()) {
1821 break;
1822 }
1823 if (cr.isOverflow()) {
1824 if (isAutoExpand()) {
1825 switch (expandedState) {
1826 case 0:
1827 autoExpand((int) Math.ceil(in.remaining() * encoder.averageBytesPerChar()));
1828 expandedState++;
1829 break;
1830 case 1:
1831 autoExpand((int) Math.ceil(in.remaining() * encoder.maxBytesPerChar()));
1832 expandedState++;
1833 break;
1834 default:
1835 throw new RuntimeException("Expanded by "
1836 + (int) Math.ceil(in.remaining() * encoder.maxBytesPerChar())
1837 + " but that wasn't enough for '" + val + "'");
1838 }
1839 continue;
1840 }
1841 } else {
1842 expandedState = 0;
1843 }
1844 cr.throwException();
1845 }
1846 return this;
1847 }
1848
1849
1850
1851
1852 @Override
1853 public IoBuffer putString(CharSequence val, int fieldSize, CharsetEncoder encoder) throws CharacterCodingException {
1854 checkFieldSize(fieldSize);
1855
1856 if (fieldSize == 0) {
1857 return this;
1858 }
1859
1860 autoExpand(fieldSize);
1861
1862 boolean utf16 = encoder.charset().equals(StandardCharsets.UTF_16) ||
1863 encoder.charset().equals(StandardCharsets.UTF_16BE) ||
1864 encoder.charset().equals(StandardCharsets.UTF_16LE);
1865
1866
1867 if (utf16 && (fieldSize & 1) != 0) {
1868 throw new IllegalArgumentException("fieldSize is not even.");
1869 }
1870
1871 int oldLimit = limit();
1872 int end = position() + fieldSize;
1873
1874 if (oldLimit < end) {
1875 throw new BufferOverflowException();
1876 }
1877
1878 if (val.length() == 0) {
1879 if (!utf16) {
1880 put((byte) 0x00);
1881 } else {
1882 put((byte) 0x00);
1883 put((byte) 0x00);
1884 }
1885 position(end);
1886 return this;
1887 }
1888
1889 CharBuffer in = CharBuffer.wrap(val);
1890 limit(end);
1891 encoder.reset();
1892
1893 for (;;) {
1894 CoderResult cr;
1895 if (in.hasRemaining()) {
1896 cr = encoder.encode(in, buf(), true);
1897 } else {
1898 cr = encoder.flush(buf());
1899 }
1900
1901 if (cr.isUnderflow() || cr.isOverflow()) {
1902 break;
1903 }
1904 cr.throwException();
1905 }
1906
1907 limit(oldLimit);
1908
1909 if (position() < end) {
1910 if (!utf16) {
1911 put((byte) 0x00);
1912 } else {
1913 put((byte) 0x00);
1914 put((byte) 0x00);
1915 }
1916 }
1917
1918 position(end);
1919 return this;
1920 }
1921
1922
1923
1924
1925 @Override
1926 public String getPrefixedString(CharsetDecoder decoder) throws CharacterCodingException {
1927 return getPrefixedString(2, decoder);
1928 }
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940 @Override
1941 public String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException {
1942 if (!prefixedDataAvailable(prefixLength)) {
1943 throw new BufferUnderflowException();
1944 }
1945
1946 int fieldSize = 0;
1947
1948 switch (prefixLength) {
1949 case 1:
1950 fieldSize = getUnsigned();
1951 break;
1952 case 2:
1953 fieldSize = getUnsignedShort();
1954 break;
1955 case 4:
1956 fieldSize = getInt();
1957 break;
1958 }
1959
1960 if (fieldSize == 0) {
1961 return "";
1962 }
1963
1964 boolean utf16 = decoder.charset().equals(StandardCharsets.UTF_16) ||
1965 decoder.charset().equals(StandardCharsets.UTF_16BE) ||
1966 decoder.charset().equals(StandardCharsets.UTF_16LE);
1967
1968
1969 if (utf16 && (fieldSize & 1) != 0) {
1970 throw new BufferDataException("fieldSize is not even for a UTF-16 string.");
1971 }
1972
1973 int oldLimit = limit();
1974 int end = position() + fieldSize;
1975
1976 if (oldLimit < end) {
1977 throw new BufferUnderflowException();
1978 }
1979
1980 limit(end);
1981 decoder.reset();
1982
1983 int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1;
1984 CharBuffer out = CharBuffer.allocate(expectedLength);
1985 for (;;) {
1986 CoderResult cr;
1987 if (hasRemaining()) {
1988 cr = decoder.decode(buf(), out, true);
1989 } else {
1990 cr = decoder.flush(out);
1991 }
1992
1993 if (cr.isUnderflow()) {
1994 break;
1995 }
1996
1997 if (cr.isOverflow()) {
1998 CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength);
1999 out.flip();
2000 o.put(out);
2001 out = o;
2002 continue;
2003 }
2004
2005 cr.throwException();
2006 }
2007
2008 limit(oldLimit);
2009 position(end);
2010 return out.flip().toString();
2011 }
2012
2013
2014
2015
2016 @Override
2017 public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException {
2018 return putPrefixedString(in, 2, 0, encoder);
2019 }
2020
2021
2022
2023
2024 @Override
2025 public IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder)
2026 throws CharacterCodingException {
2027 return putPrefixedString(in, prefixLength, 0, encoder);
2028 }
2029
2030
2031
2032
2033 @Override
2034 public IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder)
2035 throws CharacterCodingException {
2036 return putPrefixedString(in, prefixLength, padding, (byte) 0, encoder);
2037 }
2038
2039
2040
2041
2042 @Override
2043 public IoBuffer putPrefixedString(CharSequence val, int prefixLength, int padding, byte padValue,
2044 CharsetEncoder encoder) throws CharacterCodingException {
2045 int maxLength;
2046 switch (prefixLength) {
2047 case 1:
2048 maxLength = 255;
2049 break;
2050 case 2:
2051 maxLength = 65535;
2052 break;
2053 case 4:
2054 maxLength = Integer.MAX_VALUE;
2055 break;
2056 default:
2057 throw new IllegalArgumentException("prefixLength: " + prefixLength);
2058 }
2059
2060 if (val.length() > maxLength) {
2061 throw new IllegalArgumentException("The specified string is too long.");
2062 }
2063 if (val.length() == 0) {
2064 switch (prefixLength) {
2065 case 1:
2066 put((byte) 0);
2067 break;
2068 case 2:
2069 putShort((short) 0);
2070 break;
2071 case 4:
2072 putInt(0);
2073 break;
2074 }
2075 return this;
2076 }
2077
2078 int padMask;
2079 switch (padding) {
2080 case 0:
2081 case 1:
2082 padMask = 0;
2083 break;
2084 case 2:
2085 padMask = 1;
2086 break;
2087 case 4:
2088 padMask = 3;
2089 break;
2090 default:
2091 throw new IllegalArgumentException("padding: " + padding);
2092 }
2093
2094 CharBuffer in = CharBuffer.wrap(val);
2095 skip(prefixLength);
2096 int oldPos = position();
2097 encoder.reset();
2098
2099 int expandedState = 0;
2100
2101 for (;;) {
2102 CoderResult cr;
2103 if (in.hasRemaining()) {
2104 cr = encoder.encode(in, buf(), true);
2105 } else {
2106 cr = encoder.flush(buf());
2107 }
2108
2109 if (position() - oldPos > maxLength) {
2110 throw new IllegalArgumentException("The specified string is too long.");
2111 }
2112
2113 if (cr.isUnderflow()) {
2114 break;
2115 }
2116 if (cr.isOverflow()) {
2117 if (isAutoExpand()) {
2118 switch (expandedState) {
2119 case 0:
2120 autoExpand((int) Math.ceil(in.remaining() * encoder.averageBytesPerChar()));
2121 expandedState++;
2122 break;
2123 case 1:
2124 autoExpand((int) Math.ceil(in.remaining() * encoder.maxBytesPerChar()));
2125 expandedState++;
2126 break;
2127 default:
2128 throw new RuntimeException("Expanded by "
2129 + (int) Math.ceil(in.remaining() * encoder.maxBytesPerChar())
2130 + " but that wasn't enough for '" + val + "'");
2131 }
2132 continue;
2133 }
2134 } else {
2135 expandedState = 0;
2136 }
2137 cr.throwException();
2138 }
2139
2140
2141 fill(padValue, padding - (position() - oldPos & padMask));
2142 int length = position() - oldPos;
2143 switch (prefixLength) {
2144 case 1:
2145 put(oldPos - 1, (byte) length);
2146 break;
2147 case 2:
2148 putShort(oldPos - 2, (short) length);
2149 break;
2150 case 4:
2151 putInt(oldPos - 4, length);
2152 break;
2153 }
2154 return this;
2155 }
2156
2157
2158
2159
2160 @Override
2161 public Object getObject() throws ClassNotFoundException {
2162 return getObject(Thread.currentThread().getContextClassLoader());
2163 }
2164
2165
2166
2167
2168 @Override
2169 public Object getObject(final ClassLoader classLoader) throws ClassNotFoundException {
2170 if (!prefixedDataAvailable(4)) {
2171 throw new BufferUnderflowException();
2172 }
2173
2174 int length = getInt();
2175 if (length <= 4) {
2176 throw new BufferDataException("Object length should be greater than 4: " + length);
2177 }
2178
2179 int oldLimit = limit();
2180 limit(position() + length);
2181
2182 try (ObjectInputStream in = new ObjectInputStream(asInputStream()) {
2183 @Override
2184 protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
2185 int type = read();
2186 if (type < 0) {
2187 throw new EOFException();
2188 }
2189 switch (type) {
2190 case 0:
2191 return super.readClassDescriptor();
2192 case 1:
2193 String className = readUTF();
2194 Class<?> clazz = Class.forName(className, true, classLoader);
2195 return ObjectStreamClass.lookup(clazz);
2196 default:
2197 throw new StreamCorruptedException("Unexpected class descriptor type: " + type);
2198 }
2199 }
2200
2201 @Override
2202 protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
2203 Class<?> clazz = desc.forClass();
2204
2205 if (clazz == null) {
2206 String name = desc.getName();
2207 try {
2208 return Class.forName(name, false, classLoader);
2209 } catch (ClassNotFoundException ex) {
2210 return super.resolveClass(desc);
2211 }
2212 } else {
2213 return clazz;
2214 }
2215 }
2216 }) {
2217 return in.readObject();
2218 } catch (IOException e) {
2219 throw new BufferDataException(e);
2220 } finally {
2221 limit(oldLimit);
2222 }
2223 }
2224
2225
2226
2227
2228 @Override
2229 public IoBuffer putObject(Object o) {
2230 int oldPos = position();
2231 skip(4);
2232
2233 try (ObjectOutputStream out = new ObjectOutputStream(asOutputStream()) {
2234 @Override
2235 protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
2236 Class<?> clazz = desc.forClass();
2237
2238 if (clazz.isArray() || clazz.isPrimitive() || !Serializable.class.isAssignableFrom(clazz)) {
2239 write(0);
2240 super.writeClassDescriptor(desc);
2241 } else {
2242
2243 write(1);
2244 writeUTF(desc.getName());
2245 }
2246 }
2247 }) {
2248 out.writeObject(o);
2249 out.flush();
2250 } catch (IOException e) {
2251 throw new BufferDataException(e);
2252 }
2253
2254
2255 int newPos = position();
2256 position(oldPos);
2257 putInt(newPos - oldPos - 4);
2258 position(newPos);
2259 return this;
2260 }
2261
2262
2263
2264
2265 @Override
2266 public boolean prefixedDataAvailable(int prefixLength) {
2267 return prefixedDataAvailable(prefixLength, Integer.MAX_VALUE);
2268 }
2269
2270
2271
2272
2273 @Override
2274 public boolean prefixedDataAvailable(int prefixLength, int maxDataLength) {
2275 if (remaining() < prefixLength) {
2276 return false;
2277 }
2278
2279 int dataLength;
2280 switch (prefixLength) {
2281 case 1:
2282 dataLength = getUnsigned(position());
2283 break;
2284 case 2:
2285 dataLength = getUnsignedShort(position());
2286 break;
2287 case 4:
2288 dataLength = getInt(position());
2289 break;
2290 default:
2291 throw new IllegalArgumentException("prefixLength: " + prefixLength);
2292 }
2293
2294 if (dataLength < 0 || dataLength > maxDataLength) {
2295 throw new BufferDataException("dataLength: " + dataLength);
2296 }
2297
2298 return remaining() - prefixLength >= dataLength;
2299 }
2300
2301
2302
2303
2304 @Override
2305 public int indexOf(byte b) {
2306 if (hasArray()) {
2307 int arrayOffset = arrayOffset();
2308 int beginPos = arrayOffset + position();
2309 int limit = arrayOffset + limit();
2310 byte[] array = array();
2311
2312 for (int i = beginPos; i < limit; i++) {
2313 if (array[i] == b) {
2314 return i - arrayOffset;
2315 }
2316 }
2317 } else {
2318 int beginPos = position();
2319 int limit = limit();
2320
2321 for (int i = beginPos; i < limit; i++) {
2322 if (get(i) == b) {
2323 return i;
2324 }
2325 }
2326 }
2327
2328 return -1;
2329 }
2330
2331
2332
2333
2334 @Override
2335 public IoBuffer skip(int size) {
2336 autoExpand(size);
2337 return position(position() + size);
2338 }
2339
2340
2341
2342
2343 @Override
2344 public IoBuffer fill(byte value, int size) {
2345 autoExpand(size);
2346 int q = size >>> 3;
2347 int r = size & 7;
2348
2349 if (q > 0) {
2350 int intValue = value & 0x000000FF | ( value << 8 ) & 0x0000FF00 | ( value << 16 ) & 0x00FF0000 | value << 24;
2351 long longValue = intValue & 0x00000000FFFFFFFFL | (long)intValue << 32;
2352
2353 for (int i = q; i > 0; i--) {
2354 putLong(longValue);
2355 }
2356 }
2357
2358 q = r >>> 2;
2359 r = r & 3;
2360
2361 if (q > 0) {
2362 int intValue = value & 0x000000FF | ( value << 8 ) & 0x0000FF00 | ( value << 16 ) & 0x00FF0000 | value << 24;
2363 putInt(intValue);
2364 }
2365
2366 q = r >> 1;
2367 r = r & 1;
2368
2369 if (q > 0) {
2370 short shortValue = (short) (value & 0x000FF | value << 8);
2371 putShort(shortValue);
2372 }
2373
2374 if (r > 0) {
2375 put(value);
2376 }
2377
2378 return this;
2379 }
2380
2381
2382
2383
2384 @Override
2385 public IoBuffer fillAndReset(byte value, int size) {
2386 autoExpand(size);
2387 int pos = position();
2388 try {
2389 fill(value, size);
2390 } finally {
2391 position(pos);
2392 }
2393 return this;
2394 }
2395
2396
2397
2398
2399 @Override
2400 public IoBuffer fill(int size) {
2401 autoExpand(size);
2402 int q = size >>> 3;
2403 int r = size & 7;
2404
2405 for (int i = q; i > 0; i--) {
2406 putLong(0L);
2407 }
2408
2409 q = r >>> 2;
2410 r = r & 3;
2411
2412 if (q > 0) {
2413 putInt(0);
2414 }
2415
2416 q = r >> 1;
2417 r = r & 1;
2418
2419 if (q > 0) {
2420 putShort((short) 0);
2421 }
2422
2423 if (r > 0) {
2424 put((byte) 0);
2425 }
2426
2427 return this;
2428 }
2429
2430
2431
2432
2433 @Override
2434 public IoBuffer fillAndReset(int size) {
2435 autoExpand(size);
2436 int pos = position();
2437 try {
2438 fill(size);
2439 } finally {
2440 position(pos);
2441 }
2442
2443 return this;
2444 }
2445
2446
2447
2448
2449 @Override
2450 public <E extends Enum<E>> E getEnum(Class<E> enumClass) {
2451 return toEnum(enumClass, getUnsigned());
2452 }
2453
2454
2455
2456
2457 @Override
2458 public <E extends Enum<E>> E getEnum(int index, Class<E> enumClass) {
2459 return toEnum(enumClass, getUnsigned(index));
2460 }
2461
2462
2463
2464
2465 @Override
2466 public <E extends Enum<E>> E getEnumShort(Class<E> enumClass) {
2467 return toEnum(enumClass, getUnsignedShort());
2468 }
2469
2470
2471
2472
2473 @Override
2474 public <E extends Enum<E>> E getEnumShort(int index, Class<E> enumClass) {
2475 return toEnum(enumClass, getUnsignedShort(index));
2476 }
2477
2478
2479
2480
2481 @Override
2482 public <E extends Enum<E>> E getEnumInt(Class<E> enumClass) {
2483 return toEnum(enumClass, getInt());
2484 }
2485
2486
2487
2488
2489 @Override
2490 public <E extends Enum<E>> E getEnumInt(int index, Class<E> enumClass) {
2491 return toEnum(enumClass, getInt(index));
2492 }
2493
2494
2495
2496
2497 @Override
2498 public IoBuffer putEnum(Enum<?> e) {
2499 if (e.ordinal() > BYTE_MASK) {
2500 throw new IllegalArgumentException(enumConversionErrorMessage(e, "byte"));
2501 }
2502 return put((byte) e.ordinal());
2503 }
2504
2505
2506
2507
2508 @Override
2509 public IoBuffer putEnum(int index, Enum<?> e) {
2510 if (e.ordinal() > BYTE_MASK) {
2511 throw new IllegalArgumentException(enumConversionErrorMessage(e, "byte"));
2512 }
2513 return put(index, (byte) e.ordinal());
2514 }
2515
2516
2517
2518
2519 @Override
2520 public IoBuffer putEnumShort(Enum<?> e) {
2521 if (e.ordinal() > SHORT_MASK) {
2522 throw new IllegalArgumentException(enumConversionErrorMessage(e, "short"));
2523 }
2524 return putShort((short) e.ordinal());
2525 }
2526
2527
2528
2529
2530 @Override
2531 public IoBuffer putEnumShort(int index, Enum<?> e) {
2532 if (e.ordinal() > SHORT_MASK) {
2533 throw new IllegalArgumentException(enumConversionErrorMessage(e, "short"));
2534 }
2535 return putShort(index, (short) e.ordinal());
2536 }
2537
2538
2539
2540
2541 @Override
2542 public IoBuffer putEnumInt(Enum<?> e) {
2543 return putInt(e.ordinal());
2544 }
2545
2546
2547
2548
2549 @Override
2550 public IoBuffer putEnumInt(int index, Enum<?> e) {
2551 return putInt(index, e.ordinal());
2552 }
2553
2554 private <E> E toEnum(Class<E> enumClass, int i) {
2555 E[] enumConstants = enumClass.getEnumConstants();
2556 if (i > enumConstants.length) {
2557 throw new IndexOutOfBoundsException(String.format(
2558 "%d is too large of an ordinal to convert to the enum %s", i, enumClass.getName()));
2559 }
2560 return enumConstants[i];
2561 }
2562
2563 private String enumConversionErrorMessage(Enum<?> e, String type) {
2564 return String.format("%s.%s has an ordinal value too large for a %s", e.getClass().getName(), e.name(), type);
2565 }
2566
2567
2568
2569
2570 @Override
2571 public <E extends Enum<E>> Set<E> getEnumSet(Class<E> enumClass) {
2572 return toEnumSet(enumClass, get() & BYTE_MASK);
2573 }
2574
2575
2576
2577
2578 @Override
2579 public <E extends Enum<E>> Set<E> getEnumSet(int index, Class<E> enumClass) {
2580 return toEnumSet(enumClass, get(index) & BYTE_MASK);
2581 }
2582
2583
2584
2585
2586 @Override
2587 public <E extends Enum<E>> Set<E> getEnumSetShort(Class<E> enumClass) {
2588 return toEnumSet(enumClass, getShort() & SHORT_MASK);
2589 }
2590
2591
2592
2593
2594 @Override
2595 public <E extends Enum<E>> Set<E> getEnumSetShort(int index, Class<E> enumClass) {
2596 return toEnumSet(enumClass, getShort(index) & SHORT_MASK);
2597 }
2598
2599
2600
2601
2602 @Override
2603 public <E extends Enum<E>> Set<E> getEnumSetInt(Class<E> enumClass) {
2604 return toEnumSet(enumClass, getInt() & INT_MASK);
2605 }
2606
2607
2608
2609
2610 @Override
2611 public <E extends Enum<E>> Set<E> getEnumSetInt(int index, Class<E> enumClass) {
2612 return toEnumSet(enumClass, getInt(index) & INT_MASK);
2613 }
2614
2615
2616
2617
2618 @Override
2619 public <E extends Enum<E>> Set<E> getEnumSetLong(Class<E> enumClass) {
2620 return toEnumSet(enumClass, getLong());
2621 }
2622
2623
2624
2625
2626 @Override
2627 public <E extends Enum<E>> Set<E> getEnumSetLong(int index, Class<E> enumClass) {
2628 return toEnumSet(enumClass, getLong(index));
2629 }
2630
2631 private <E extends Enum<E>> EnumSet<E> toEnumSet(Class<E> clazz, long vector) {
2632 EnumSet<E> set = EnumSet.noneOf(clazz);
2633 long mask = 1;
2634 for (E e : clazz.getEnumConstants()) {
2635 if ((mask & vector) == mask) {
2636 set.add(e);
2637 }
2638 mask <<= 1;
2639 }
2640 return set;
2641 }
2642
2643
2644
2645
2646 @Override
2647 public <E extends Enum<E>> IoBuffer putEnumSet(Set<E> set) {
2648 long vector = toLong(set);
2649 if ((vector & ~BYTE_MASK) != 0) {
2650 throw new IllegalArgumentException("The enum set is too large to fit in a byte: " + set);
2651 }
2652 return put((byte) vector);
2653 }
2654
2655
2656
2657
2658 @Override
2659 public <E extends Enum<E>> IoBuffer putEnumSet(int index, Set<E> set) {
2660 long vector = toLong(set);
2661 if ((vector & ~BYTE_MASK) != 0) {
2662 throw new IllegalArgumentException("The enum set is too large to fit in a byte: " + set);
2663 }
2664 return put(index, (byte) vector);
2665 }
2666
2667
2668
2669
2670 @Override
2671 public <E extends Enum<E>> IoBuffer putEnumSetShort(Set<E> set) {
2672 long vector = toLong(set);
2673 if ((vector & ~SHORT_MASK) != 0) {
2674 throw new IllegalArgumentException("The enum set is too large to fit in a short: " + set);
2675 }
2676 return putShort((short) vector);
2677 }
2678
2679
2680
2681
2682 @Override
2683 public <E extends Enum<E>> IoBuffer putEnumSetShort(int index, Set<E> set) {
2684 long vector = toLong(set);
2685 if ((vector & ~SHORT_MASK) != 0) {
2686 throw new IllegalArgumentException("The enum set is too large to fit in a short: " + set);
2687 }
2688 return putShort(index, (short) vector);
2689 }
2690
2691
2692
2693
2694 @Override
2695 public <E extends Enum<E>> IoBuffer putEnumSetInt(Set<E> set) {
2696 long vector = toLong(set);
2697 if ((vector & ~INT_MASK) != 0) {
2698 throw new IllegalArgumentException("The enum set is too large to fit in an int: " + set);
2699 }
2700 return putInt((int) vector);
2701 }
2702
2703
2704
2705
2706 @Override
2707 public <E extends Enum<E>> IoBuffer putEnumSetInt(int index, Set<E> set) {
2708 long vector = toLong(set);
2709 if ((vector & ~INT_MASK) != 0) {
2710 throw new IllegalArgumentException("The enum set is too large to fit in an int: " + set);
2711 }
2712 return putInt(index, (int) vector);
2713 }
2714
2715
2716
2717
2718 @Override
2719 public <E extends Enum<E>> IoBuffer putEnumSetLong(Set<E> set) {
2720 return putLong(toLong(set));
2721 }
2722
2723
2724
2725
2726 @Override
2727 public <E extends Enum<E>> IoBuffer putEnumSetLong(int index, Set<E> set) {
2728 return putLong(index, toLong(set));
2729 }
2730
2731 private <E extends Enum<E>> long toLong(Set<E> set) {
2732 long vector = 0;
2733 for (E e : set) {
2734 if (e.ordinal() >= Long.SIZE) {
2735 throw new IllegalArgumentException("The enum set is too large to fit in a bit vector: " + set);
2736 }
2737 vector |= 1L << e.ordinal();
2738 }
2739 return vector;
2740 }
2741
2742
2743
2744
2745
2746 private IoBuffer autoExpand(int expectedRemaining) {
2747 if (isAutoExpand()) {
2748 expand(expectedRemaining, true);
2749 }
2750 return this;
2751 }
2752
2753
2754
2755
2756
2757 private IoBuffer autoExpand(int pos, int expectedRemaining) {
2758 if (isAutoExpand()) {
2759 expand(pos, expectedRemaining, true);
2760 }
2761 return this;
2762 }
2763
2764 private static void checkFieldSize(int fieldSize) {
2765 if (fieldSize < 0) {
2766 throw new IllegalArgumentException("fieldSize cannot be negative: " + fieldSize);
2767 }
2768 }
2769 }