1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.util;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.DataInput;
21 import java.io.DataInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.nio.ByteBuffer;
26
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.classification.InterfaceStability;
29 import org.apache.hadoop.io.IOUtils;
30 import org.apache.hadoop.io.WritableUtils;
31
32 import sun.nio.ch.DirectBuffer;
33
34
35
36
37
38
39 @SuppressWarnings("restriction")
40 @Deprecated
41 @InterfaceAudience.Public
42 @InterfaceStability.Evolving
43 public final class ByteBufferUtils {
44
45 public final static int VALUE_MASK = 0x7f;
46 public final static int NEXT_BIT_SHIFT = 7;
47 public final static int NEXT_BIT_MASK = 1 << 7;
48 @InterfaceAudience.Private
49 static final boolean UNSAFE_AVAIL = UnsafeAvailChecker.isAvailable();
50 public static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
51
52 private ByteBufferUtils() {
53 }
54
55 static abstract class Comparer {
56 abstract int compareTo(byte [] buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2);
57 abstract int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2);
58 }
59
60 static abstract class Converter {
61 abstract short toShort(ByteBuffer buffer, int offset);
62 abstract int toInt(ByteBuffer buffer);
63 abstract int toInt(ByteBuffer buffer, int offset);
64 abstract long toLong(ByteBuffer buffer, int offset);
65 abstract void putInt(ByteBuffer buffer, int val);
66 abstract int putInt(ByteBuffer buffer, int index, int val);
67 abstract void putShort(ByteBuffer buffer, short val);
68 abstract int putShort(ByteBuffer buffer, int index, short val);
69 abstract void putLong(ByteBuffer buffer, long val);
70 abstract int putLong(ByteBuffer buffer, int index, long val);
71 }
72
73 static class ComparerHolder {
74 static final String UNSAFE_COMPARER_NAME = ComparerHolder.class.getName() + "$UnsafeComparer";
75
76 static final Comparer BEST_COMPARER = getBestComparer();
77
78 static Comparer getBestComparer() {
79 try {
80 Class<?> theClass = Class.forName(UNSAFE_COMPARER_NAME);
81
82 @SuppressWarnings("unchecked")
83 Comparer comparer = (Comparer) theClass.getConstructor().newInstance();
84 return comparer;
85 } catch (Throwable t) {
86 return PureJavaComparer.INSTANCE;
87 }
88 }
89
90 static final class PureJavaComparer extends Comparer {
91 static final PureJavaComparer INSTANCE = new PureJavaComparer();
92
93 private PureJavaComparer() {}
94
95 @Override
96 public int compareTo(byte [] buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
97 int end1 = o1 + l1;
98 int end2 = o2 + l2;
99 for (int i = o1, j = o2; i < end1 && j < end2; i++, j++) {
100 int a = buf1[i] & 0xFF;
101 int b = buf2.get(j) & 0xFF;
102 if (a != b) {
103 return a - b;
104 }
105 }
106 return l1 - l2;
107 }
108
109 @Override
110 public int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
111 int end1 = o1 + l1;
112 int end2 = o2 + l2;
113 for (int i = o1, j = o2; i < end1 && j < end2; i++, j++) {
114 int a = buf1.get(i) & 0xFF;
115 int b = buf2.get(j) & 0xFF;
116 if (a != b) {
117 return a - b;
118 }
119 }
120 return l1 - l2;
121 }
122 }
123
124 static final class UnsafeComparer extends Comparer {
125
126 public UnsafeComparer() {}
127
128 static {
129 if(!UNSAFE_UNALIGNED) {
130 throw new Error();
131 }
132 }
133
134 @Override
135 public int compareTo(byte[] buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
136 long offset2Adj;
137 Object refObj2 = null;
138 if (buf2.isDirect()) {
139 offset2Adj = o2 + ((DirectBuffer)buf2).address();
140 } else {
141 offset2Adj = o2 + buf2.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
142 refObj2 = buf2.array();
143 }
144 return compareToUnsafe(buf1, o1 + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET, l1,
145 refObj2, offset2Adj, l2);
146 }
147
148 @Override
149 public int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
150 long offset1Adj, offset2Adj;
151 Object refObj1 = null, refObj2 = null;
152 if (buf1.isDirect()) {
153 offset1Adj = o1 + ((DirectBuffer) buf1).address();
154 } else {
155 offset1Adj = o1 + buf1.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
156 refObj1 = buf1.array();
157 }
158 if (buf2.isDirect()) {
159 offset2Adj = o2 + ((DirectBuffer) buf2).address();
160 } else {
161 offset2Adj = o2 + buf2.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
162 refObj2 = buf2.array();
163 }
164 return compareToUnsafe(refObj1, offset1Adj, l1, refObj2, offset2Adj, l2);
165 }
166 }
167 }
168
169
170 static class ConverterHolder {
171 static final String UNSAFE_CONVERTER_NAME =
172 ConverterHolder.class.getName() + "$UnsafeConverter";
173 static final Converter BEST_CONVERTER = getBestConverter();
174
175 static Converter getBestConverter() {
176 try {
177 Class<?> theClass = Class.forName(UNSAFE_CONVERTER_NAME);
178
179
180 @SuppressWarnings("unchecked")
181 Converter converter = (Converter) theClass.getConstructor().newInstance();
182 return converter;
183 } catch (Throwable t) {
184 return PureJavaConverter.INSTANCE;
185 }
186 }
187
188 static final class PureJavaConverter extends Converter {
189 static final PureJavaConverter INSTANCE = new PureJavaConverter();
190
191 private PureJavaConverter() {}
192
193 @Override
194 short toShort(ByteBuffer buffer, int offset) {
195 return buffer.getShort(offset);
196 }
197
198 @Override
199 int toInt(ByteBuffer buffer) {
200 return buffer.getInt();
201 }
202
203 @Override
204 int toInt(ByteBuffer buffer, int offset) {
205 return buffer.getInt(offset);
206 }
207
208 @Override
209 long toLong(ByteBuffer buffer, int offset) {
210 return buffer.getLong(offset);
211 }
212
213 @Override
214 void putInt(ByteBuffer buffer, int val) {
215 buffer.putInt(val);
216 }
217
218 @Override
219 int putInt(ByteBuffer buffer, int index, int val) {
220 buffer.putInt(index, val);
221 return index + Bytes.SIZEOF_INT;
222 }
223
224 @Override
225 void putShort(ByteBuffer buffer, short val) {
226 buffer.putShort(val);
227 }
228
229 @Override
230 int putShort(ByteBuffer buffer, int index, short val) {
231 buffer.putShort(index, val);
232 return index + Bytes.SIZEOF_SHORT;
233 }
234
235 @Override
236 void putLong(ByteBuffer buffer, long val) {
237 buffer.putLong(val);
238 }
239
240 @Override
241 int putLong(ByteBuffer buffer, int index, long val) {
242 buffer.putLong(index, val);
243 return index + Bytes.SIZEOF_LONG;
244 }
245 }
246
247 static final class UnsafeConverter extends Converter {
248
249 public UnsafeConverter() {}
250
251 static {
252 if(!UNSAFE_UNALIGNED) {
253 throw new Error();
254 }
255 }
256
257 @Override
258 short toShort(ByteBuffer buffer, int offset) {
259 return UnsafeAccess.toShort(buffer, offset);
260 }
261
262 @Override
263 int toInt(ByteBuffer buffer) {
264 int i = UnsafeAccess.toInt(buffer, buffer.position());
265 buffer.position(buffer.position() + Bytes.SIZEOF_INT);
266 return i;
267 }
268
269 @Override
270 int toInt(ByteBuffer buffer, int offset) {
271 return UnsafeAccess.toInt(buffer, offset);
272 }
273
274 @Override
275 long toLong(ByteBuffer buffer, int offset) {
276 return UnsafeAccess.toLong(buffer, offset);
277 }
278
279 @Override
280 void putInt(ByteBuffer buffer, int val) {
281 int newPos = UnsafeAccess.putInt(buffer, buffer.position(), val);
282 buffer.position(newPos);
283 }
284
285 @Override
286 int putInt(ByteBuffer buffer, int index, int val) {
287 return UnsafeAccess.putInt(buffer, index, val);
288 }
289
290 @Override
291 void putShort(ByteBuffer buffer, short val) {
292 int newPos = UnsafeAccess.putShort(buffer, buffer.position(), val);
293 buffer.position(newPos);
294 }
295
296 @Override
297 int putShort(ByteBuffer buffer, int index, short val) {
298 return UnsafeAccess.putShort(buffer, index, val);
299 }
300
301 @Override
302 void putLong(ByteBuffer buffer, long val) {
303 int newPos = UnsafeAccess.putLong(buffer, buffer.position(), val);
304 buffer.position(newPos);
305 }
306
307 @Override
308 int putLong(ByteBuffer buffer, int index, long val) {
309 return UnsafeAccess.putLong(buffer, index, val);
310 }
311 }
312 }
313
314
315
316
317
318 public static void writeVLong(ByteBuffer out, long i) {
319 if (i >= -112 && i <= 127) {
320 out.put((byte) i);
321 return;
322 }
323
324 int len = -112;
325 if (i < 0) {
326 i ^= -1L;
327 len = -120;
328 }
329
330 long tmp = i;
331 while (tmp != 0) {
332 tmp = tmp >> 8;
333 len--;
334 }
335
336 out.put((byte) len);
337
338 len = (len < -120) ? -(len + 120) : -(len + 112);
339
340 for (int idx = len; idx != 0; idx--) {
341 int shiftbits = (idx - 1) * 8;
342 long mask = 0xFFL << shiftbits;
343 out.put((byte) ((i & mask) >> shiftbits));
344 }
345 }
346
347
348
349
350
351 public static long readVLong(ByteBuffer in) {
352 byte firstByte = in.get();
353 int len = WritableUtils.decodeVIntSize(firstByte);
354 if (len == 1) {
355 return firstByte;
356 }
357 long i = 0;
358 for (int idx = 0; idx < len-1; idx++) {
359 byte b = in.get();
360 i = i << 8;
361 i = i | (b & 0xFF);
362 }
363 return (WritableUtils.isNegativeVInt(firstByte) ? (i ^ -1L) : i);
364 }
365
366
367
368
369
370
371
372
373
374
375
376 public static int putCompressedInt(OutputStream out, final int value)
377 throws IOException {
378 int i = 0;
379 int tmpvalue = value;
380 do {
381 byte b = (byte) (tmpvalue & VALUE_MASK);
382 tmpvalue >>>= NEXT_BIT_SHIFT;
383 if (tmpvalue != 0) {
384 b |= (byte) NEXT_BIT_MASK;
385 }
386 out.write(b);
387 i++;
388 } while (tmpvalue != 0);
389 return i;
390 }
391
392
393
394
395
396
397
398 public static void putInt(OutputStream out, final int value)
399 throws IOException {
400 for (int i = Bytes.SIZEOF_INT - 1; i >= 0; --i) {
401 out.write((byte) (value >>> (i * 8)));
402 }
403 }
404
405 public static byte toByte(ByteBuffer buffer, int offset) {
406 if (UNSAFE_AVAIL) {
407 return UnsafeAccess.toByte(buffer, offset);
408 } else {
409 return buffer.get(offset);
410 }
411 }
412
413
414
415
416
417
418
419 public static void moveBufferToStream(OutputStream out, ByteBuffer in,
420 int length) throws IOException {
421 copyBufferToStream(out, in, in.position(), length);
422 skip(in, length);
423 }
424
425
426
427
428
429
430
431
432
433
434 public static void copyBufferToStream(OutputStream out, ByteBuffer in,
435 int offset, int length) throws IOException {
436 if (in.hasArray()) {
437 out.write(in.array(), in.arrayOffset() + offset, length);
438 } else {
439 for (int i = 0; i < length; ++i) {
440 out.write(toByte(in, offset + i));
441 }
442 }
443 }
444
445 public static int putLong(OutputStream out, final long value,
446 final int fitInBytes) throws IOException {
447 long tmpValue = value;
448 for (int i = 0; i < fitInBytes; ++i) {
449 out.write((byte) (tmpValue & 0xff));
450 tmpValue >>>= 8;
451 }
452 return fitInBytes;
453 }
454
455
456
457
458
459
460 public static int longFitsIn(final long value) {
461 if (value < 0) {
462 return 8;
463 }
464
465 if (value < (1L << (4 * 8))) {
466
467 if (value < (1L << (2 * 8))) {
468 if (value < (1L << (1 * 8))) {
469 return 1;
470 }
471 return 2;
472 }
473 if (value < (1L << (3 * 8))) {
474 return 3;
475 }
476 return 4;
477 }
478
479 if (value < (1L << (6 * 8))) {
480 if (value < (1L << (5 * 8))) {
481 return 5;
482 }
483 return 6;
484 }
485 if (value < (1L << (7 * 8))) {
486 return 7;
487 }
488 return 8;
489 }
490
491
492
493
494
495
496 public static int intFitsIn(final int value) {
497 if (value < 0) {
498 return 4;
499 }
500
501 if (value < (1 << (2 * 8))) {
502 if (value < (1 << (1 * 8))) {
503 return 1;
504 }
505 return 2;
506 }
507 if (value <= (1 << (3 * 8))) {
508 return 3;
509 }
510 return 4;
511 }
512
513
514
515
516
517
518 public static int readCompressedInt(InputStream input)
519 throws IOException {
520 int result = 0;
521 int i = 0;
522 byte b;
523 do {
524 b = (byte) input.read();
525 result += (b & VALUE_MASK) << (NEXT_BIT_SHIFT * i);
526 i++;
527 if (i > Bytes.SIZEOF_INT + 1) {
528 throw new IllegalStateException(
529 "Corrupted compressed int (too long: " + (i + 1) + " bytes)");
530 }
531 } while (0 != (b & NEXT_BIT_MASK));
532 return result;
533 }
534
535
536
537
538
539 public static int readCompressedInt(ByteBuffer buffer) {
540 byte b = buffer.get();
541 if ((b & NEXT_BIT_MASK) != 0) {
542 return (b & VALUE_MASK) + (readCompressedInt(buffer) << NEXT_BIT_SHIFT);
543 }
544 return b & VALUE_MASK;
545 }
546
547
548
549
550
551
552
553 public static long readLong(InputStream in, final int fitInBytes)
554 throws IOException {
555 long tmpLong = 0;
556 for (int i = 0; i < fitInBytes; ++i) {
557 tmpLong |= (in.read() & 0xffL) << (8 * i);
558 }
559 return tmpLong;
560 }
561
562
563
564
565
566
567 public static long readLong(ByteBuffer in, final int fitInBytes) {
568 long tmpLength = 0;
569 for (int i = 0; i < fitInBytes; ++i) {
570 tmpLength |= (in.get() & 0xffL) << (8L * i);
571 }
572 return tmpLength;
573 }
574
575
576
577
578
579
580
581
582 public static void copyFromStreamToBuffer(ByteBuffer out,
583 DataInputStream in, int length) throws IOException {
584 if (out.hasArray()) {
585 in.readFully(out.array(), out.position() + out.arrayOffset(),
586 length);
587 skip(out, length);
588 } else {
589 for (int i = 0; i < length; ++i) {
590 out.put(in.readByte());
591 }
592 }
593 }
594
595
596
597
598 public static ByteBuffer drainInputStreamToBuffer(InputStream is) throws IOException {
599 ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
600 IOUtils.copyBytes(is, baos, 4096, true);
601 ByteBuffer buffer = ByteBuffer.wrap(baos.toByteArray());
602 buffer.rewind();
603 return buffer;
604 }
605
606
607
608
609
610
611
612
613
614
615
616 public static void copyFromBufferToBuffer(ByteBuffer out,
617 ByteBuffer in, int sourceOffset, int length) {
618 if (in.hasArray() && out.hasArray()) {
619 System.arraycopy(in.array(), sourceOffset + in.arrayOffset(),
620 out.array(), out.position() +
621 out.arrayOffset(), length);
622 skip(out, length);
623 } else {
624 for (int i = 0; i < length; ++i) {
625 out.put(in.get(sourceOffset + i));
626 }
627 }
628 }
629
630
631
632
633
634
635
636
637
638
639 public static void copyFromBufferToBuffer(ByteBuffer out, ByteBuffer in, int sourceOffset,
640 int destinationOffset, int length) {
641 if (in.hasArray() && out.hasArray()) {
642 System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out.array(), out.arrayOffset()
643 + destinationOffset, length);
644 } else if (UNSAFE_AVAIL) {
645 UnsafeAccess.copy(in, sourceOffset, out, destinationOffset, length);
646 } else {
647 for (int i = 0; i < length; ++i) {
648 out.put((destinationOffset + i), in.get(sourceOffset + i));
649 }
650 }
651 }
652
653
654
655
656
657
658
659
660
661 public static int findCommonPrefix(ByteBuffer buffer, int offsetLeft,
662 int offsetRight, int limit) {
663 int prefix = 0;
664
665 for (; prefix < limit; ++prefix) {
666 if (buffer.get(offsetLeft + prefix) != buffer.get(offsetRight + prefix)) {
667 break;
668 }
669 }
670
671 return prefix;
672 }
673
674
675
676
677
678
679
680
681
682
683
684 public static int findCommonPrefix(
685 byte[] left, int leftOffset, int leftLength,
686 byte[] right, int rightOffset, int rightLength) {
687 int length = Math.min(leftLength, rightLength);
688 int result = 0;
689
690 while (result < length &&
691 left[leftOffset + result] == right[rightOffset + result]) {
692 result++;
693 }
694
695 return result;
696 }
697
698
699
700
701
702
703
704
705
706
707 public static int findCommonPrefix(ByteBuffer left, int leftOffset, int leftLength,
708 ByteBuffer right, int rightOffset, int rightLength) {
709 int length = Math.min(leftLength, rightLength);
710 int result = 0;
711
712 while (result < length && ByteBufferUtils.toByte(left, leftOffset + result) == ByteBufferUtils
713 .toByte(right, rightOffset + result)) {
714 result++;
715 }
716
717 return result;
718 }
719
720
721
722
723
724
725
726
727
728
729 public static boolean arePartsEqual(ByteBuffer buffer,
730 int offsetLeft, int lengthLeft,
731 int offsetRight, int lengthRight) {
732 if (lengthLeft != lengthRight) {
733 return false;
734 }
735
736 if (buffer.hasArray()) {
737 return 0 == Bytes.compareTo(
738 buffer.array(), buffer.arrayOffset() + offsetLeft, lengthLeft,
739 buffer.array(), buffer.arrayOffset() + offsetRight, lengthRight);
740 }
741
742 for (int i = 0; i < lengthRight; ++i) {
743 if (buffer.get(offsetLeft + i) != buffer.get(offsetRight + i)) {
744 return false;
745 }
746 }
747 return true;
748 }
749
750
751
752
753
754
755 public static void skip(ByteBuffer buffer, int length) {
756 buffer.position(buffer.position() + length);
757 }
758
759 public static void extendLimit(ByteBuffer buffer, int numBytes) {
760 buffer.limit(buffer.limit() + numBytes);
761 }
762
763
764
765
766
767
768
769
770 public static byte[] toBytes(ByteBuffer buffer, int startPosition) {
771 int originalPosition = buffer.position();
772 byte[] output = new byte[buffer.limit() - startPosition];
773 buffer.position(startPosition);
774 buffer.get(output);
775 buffer.position(originalPosition);
776 return output;
777 }
778
779
780
781
782
783
784
785
786 public static byte[] toBytes(ByteBuffer buffer, int offset, int length) {
787 byte[] output = new byte[length];
788 for (int i = 0; i < length; i++) {
789 output[i] = buffer.get(offset + i);
790 }
791 return output;
792 }
793
794 public static int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
795 return ComparerHolder.BEST_COMPARER.compareTo(buf1, o1, l1, buf2, o2, l2);
796 }
797
798 public static boolean equals(ByteBuffer buf1, int o1, int l1, byte[] buf2, int o2, int l2) {
799 if ((l1 == 0) || (l2 == 0)) {
800
801 return l1 == l2;
802 }
803
804
805
806 if (toByte(buf1, o1 + l1 - 1) != buf2[o2 + l2 - 1]) return false;
807 return compareTo(buf1, o1, l1, buf2, o2, l2) == 0;
808 }
809
810
811
812
813
814
815 public static int compareTo(byte [] buf1, int o1, int l1, ByteBuffer buf2, int o2, int l2) {
816 return ComparerHolder.BEST_COMPARER.compareTo(buf1, o1, l1, buf2, o2, l2);
817 }
818
819 public static int compareTo(ByteBuffer buf1, int o1, int l1, byte[] buf2, int o2, int l2) {
820 return compareTo(buf2, o2, l2, buf1, o1, l1)*-1;
821 }
822
823 static int compareToUnsafe(Object obj1, long o1, int l1, Object obj2, long o2, int l2) {
824 final int stride = 8;
825 final int minLength = Math.min(l1, l2);
826 int strideLimit = minLength & ~(stride - 1);
827 int i;
828
829
830
831
832
833
834 for (i = 0; i < strideLimit; i += stride) {
835 long lw = UnsafeAccess.theUnsafe.getLong(obj1, o1 + (long) i);
836 long rw = UnsafeAccess.theUnsafe.getLong(obj2, o2 + (long) i);
837 if (lw != rw) {
838 if (!UnsafeAccess.LITTLE_ENDIAN) {
839 return ((lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE)) ? -1 : 1;
840 }
841
842
843
844
845
846
847
848
849
850 int n = Long.numberOfTrailingZeros(lw ^ rw) & ~0x7;
851 return ((int) ((lw >>> n) & 0xFF)) - ((int) ((rw >>> n) & 0xFF));
852 }
853 }
854
855
856 for (; i < minLength; i++) {
857 int il = (UnsafeAccess.theUnsafe.getByte(obj1, o1 + i) & 0xFF);
858 int ir = (UnsafeAccess.theUnsafe.getByte(obj2, o2 + i) & 0xFF);
859 if (il != ir) {
860 return il - ir;
861 }
862 }
863 return l1 - l2;
864 }
865
866
867
868
869
870
871
872 public static short toShort(ByteBuffer buffer, int offset) {
873 return ConverterHolder.BEST_CONVERTER.toShort(buffer, offset);
874 }
875
876
877
878
879 public static int toInt(ByteBuffer buffer) {
880 return ConverterHolder.BEST_CONVERTER.toInt(buffer);
881 }
882
883
884
885
886
887
888
889 public static int toInt(ByteBuffer buffer, int offset) {
890 return ConverterHolder.BEST_CONVERTER.toInt(buffer, offset);
891 }
892
893
894
895
896
897
898
899 public static long toLong(ByteBuffer buffer, int offset) {
900 return ConverterHolder.BEST_CONVERTER.toLong(buffer, offset);
901 }
902
903
904
905
906
907
908
909 public static void putInt(ByteBuffer buffer, int val) {
910 ConverterHolder.BEST_CONVERTER.putInt(buffer, val);
911 }
912
913 public static int putInt(ByteBuffer buffer, int index, int val) {
914 return ConverterHolder.BEST_CONVERTER.putInt(buffer, index, val);
915 }
916
917
918
919
920
921
922
923 public static void putShort(ByteBuffer buffer, short val) {
924 ConverterHolder.BEST_CONVERTER.putShort(buffer, val);
925 }
926
927 public static int putShort(ByteBuffer buffer, int index, short val) {
928 return ConverterHolder.BEST_CONVERTER.putShort(buffer, index, val);
929 }
930
931
932
933
934
935
936
937 public static void putLong(ByteBuffer buffer, long val) {
938 ConverterHolder.BEST_CONVERTER.putLong(buffer, val);
939 }
940
941 public static int putLong(ByteBuffer buffer, int index, long val) {
942 return ConverterHolder.BEST_CONVERTER.putLong(buffer, index, val);
943 }
944
945
946
947
948
949
950
951
952
953 public static void copyFromArrayToBuffer(ByteBuffer out, int outOffset, byte[] in, int inOffset,
954 int length) {
955 if (out.hasArray()) {
956 System.arraycopy(in, inOffset, out.array(), out.arrayOffset() + outOffset, length);
957 } else if (UNSAFE_AVAIL) {
958 UnsafeAccess.copy(in, inOffset, out, outOffset, length);
959 } else {
960 ByteBuffer outDup = out.duplicate();
961 outDup.position(outOffset);
962 outDup.put(in, inOffset, length);
963 }
964 }
965
966
967
968
969
970
971
972
973
974
975 public static void copyFromBufferToArray(byte[] out, ByteBuffer in, int sourceOffset,
976 int destinationOffset, int length) {
977 if (in.hasArray()) {
978 System.arraycopy(in.array(), sourceOffset + in.arrayOffset(), out, destinationOffset, length);
979 } else if (UNSAFE_AVAIL) {
980 UnsafeAccess.copy(in, sourceOffset, out, destinationOffset, length);
981 } else {
982 ByteBuffer inDup = in.duplicate();
983 inDup.position(sourceOffset);
984 inDup.get(out, destinationOffset, length);
985 }
986 }
987 }