1
16 package io.netty.buffer;
17
18 import io.netty.util.internal.PlatformDependent;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25 import java.nio.ReadOnlyBufferException;
26
27 import static io.netty.util.internal.MathUtil.isOutOfBounds;
28 import static io.netty.util.internal.ObjectUtil.checkNotNull;
29 import static io.netty.util.internal.PlatformDependent.BIG_ENDIAN_NATIVE_ORDER;
30
31
34 final class UnsafeByteBufUtil {
35 private static final boolean UNALIGNED = PlatformDependent.isUnaligned();
36 private static final byte ZERO = 0;
37
38 static byte getByte(long address) {
39 return PlatformDependent.getByte(address);
40 }
41
42 static short getShort(long address) {
43 if (UNALIGNED) {
44 short v = PlatformDependent.getShort(address);
45 return BIG_ENDIAN_NATIVE_ORDER ? v : Short.reverseBytes(v);
46 }
47 return (short) (PlatformDependent.getByte(address) << 8 | PlatformDependent.getByte(address + 1) & 0xff);
48 }
49
50 static short getShortLE(long address) {
51 if (UNALIGNED) {
52 short v = PlatformDependent.getShort(address);
53 return BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes(v) : v;
54 }
55 return (short) (PlatformDependent.getByte(address) & 0xff | PlatformDependent.getByte(address + 1) << 8);
56 }
57
58 static int getUnsignedMedium(long address) {
59 if (UNALIGNED) {
60 return (PlatformDependent.getByte(address) & 0xff) << 16 |
61 (BIG_ENDIAN_NATIVE_ORDER ? PlatformDependent.getShort(address + 1)
62 : Short.reverseBytes(PlatformDependent.getShort(address + 1))) & 0xffff;
63 }
64 return (PlatformDependent.getByte(address) & 0xff) << 16 |
65 (PlatformDependent.getByte(address + 1) & 0xff) << 8 |
66 PlatformDependent.getByte(address + 2) & 0xff;
67 }
68
69 static int getUnsignedMediumLE(long address) {
70 if (UNALIGNED) {
71 return (PlatformDependent.getByte(address) & 0xff) |
72 ((BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes(PlatformDependent.getShort(address + 1))
73 : PlatformDependent.getShort(address + 1)) & 0xffff) << 8;
74 }
75 return PlatformDependent.getByte(address) & 0xff |
76 (PlatformDependent.getByte(address + 1) & 0xff) << 8 |
77 (PlatformDependent.getByte(address + 2) & 0xff) << 16;
78 }
79
80 static int getInt(long address) {
81 if (UNALIGNED) {
82 int v = PlatformDependent.getInt(address);
83 return BIG_ENDIAN_NATIVE_ORDER ? v : Integer.reverseBytes(v);
84 }
85 return PlatformDependent.getByte(address) << 24 |
86 (PlatformDependent.getByte(address + 1) & 0xff) << 16 |
87 (PlatformDependent.getByte(address + 2) & 0xff) << 8 |
88 PlatformDependent.getByte(address + 3) & 0xff;
89 }
90
91 static int getIntLE(long address) {
92 if (UNALIGNED) {
93 int v = PlatformDependent.getInt(address);
94 return BIG_ENDIAN_NATIVE_ORDER ? Integer.reverseBytes(v) : v;
95 }
96 return PlatformDependent.getByte(address) & 0xff |
97 (PlatformDependent.getByte(address + 1) & 0xff) << 8 |
98 (PlatformDependent.getByte(address + 2) & 0xff) << 16 |
99 PlatformDependent.getByte(address + 3) << 24;
100 }
101
102 static long getLong(long address) {
103 if (UNALIGNED) {
104 long v = PlatformDependent.getLong(address);
105 return BIG_ENDIAN_NATIVE_ORDER ? v : Long.reverseBytes(v);
106 }
107 return ((long) PlatformDependent.getByte(address)) << 56 |
108 (PlatformDependent.getByte(address + 1) & 0xffL) << 48 |
109 (PlatformDependent.getByte(address + 2) & 0xffL) << 40 |
110 (PlatformDependent.getByte(address + 3) & 0xffL) << 32 |
111 (PlatformDependent.getByte(address + 4) & 0xffL) << 24 |
112 (PlatformDependent.getByte(address + 5) & 0xffL) << 16 |
113 (PlatformDependent.getByte(address + 6) & 0xffL) << 8 |
114 (PlatformDependent.getByte(address + 7)) & 0xffL;
115 }
116
117 static long getLongLE(long address) {
118 if (UNALIGNED) {
119 long v = PlatformDependent.getLong(address);
120 return BIG_ENDIAN_NATIVE_ORDER ? Long.reverseBytes(v) : v;
121 }
122 return (PlatformDependent.getByte(address)) & 0xffL |
123 (PlatformDependent.getByte(address + 1) & 0xffL) << 8 |
124 (PlatformDependent.getByte(address + 2) & 0xffL) << 16 |
125 (PlatformDependent.getByte(address + 3) & 0xffL) << 24 |
126 (PlatformDependent.getByte(address + 4) & 0xffL) << 32 |
127 (PlatformDependent.getByte(address + 5) & 0xffL) << 40 |
128 (PlatformDependent.getByte(address + 6) & 0xffL) << 48 |
129 ((long) PlatformDependent.getByte(address + 7)) << 56;
130 }
131
132 static void setByte(long address, int value) {
133 PlatformDependent.putByte(address, (byte) value);
134 }
135
136 static void setShort(long address, int value) {
137 if (UNALIGNED) {
138 PlatformDependent.putShort(
139 address, BIG_ENDIAN_NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
140 } else {
141 PlatformDependent.putByte(address, (byte) (value >>> 8));
142 PlatformDependent.putByte(address + 1, (byte) value);
143 }
144 }
145
146 static void setShortLE(long address, int value) {
147 if (UNALIGNED) {
148 PlatformDependent.putShort(
149 address, BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes((short) value) : (short) value);
150 } else {
151 PlatformDependent.putByte(address, (byte) value);
152 PlatformDependent.putByte(address + 1, (byte) (value >>> 8));
153 }
154 }
155
156 static void setMedium(long address, int value) {
157 PlatformDependent.putByte(address, (byte) (value >>> 16));
158 if (UNALIGNED) {
159 PlatformDependent.putShort(address + 1, BIG_ENDIAN_NATIVE_ORDER ? (short) value
160 : Short.reverseBytes((short) value));
161 } else {
162 PlatformDependent.putByte(address + 1, (byte) (value >>> 8));
163 PlatformDependent.putByte(address + 2, (byte) value);
164 }
165 }
166
167 static void setMediumLE(long address, int value) {
168 PlatformDependent.putByte(address, (byte) value);
169 if (UNALIGNED) {
170 PlatformDependent.putShort(address + 1, BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes((short) (value >>> 8))
171 : (short) (value >>> 8));
172 } else {
173 PlatformDependent.putByte(address + 1, (byte) (value >>> 8));
174 PlatformDependent.putByte(address + 2, (byte) (value >>> 16));
175 }
176 }
177
178 static void setInt(long address, int value) {
179 if (UNALIGNED) {
180 PlatformDependent.putInt(address, BIG_ENDIAN_NATIVE_ORDER ? value : Integer.reverseBytes(value));
181 } else {
182 PlatformDependent.putByte(address, (byte) (value >>> 24));
183 PlatformDependent.putByte(address + 1, (byte) (value >>> 16));
184 PlatformDependent.putByte(address + 2, (byte) (value >>> 8));
185 PlatformDependent.putByte(address + 3, (byte) value);
186 }
187 }
188
189 static void setIntLE(long address, int value) {
190 if (UNALIGNED) {
191 PlatformDependent.putInt(address, BIG_ENDIAN_NATIVE_ORDER ? Integer.reverseBytes(value) : value);
192 } else {
193 PlatformDependent.putByte(address, (byte) value);
194 PlatformDependent.putByte(address + 1, (byte) (value >>> 8));
195 PlatformDependent.putByte(address + 2, (byte) (value >>> 16));
196 PlatformDependent.putByte(address + 3, (byte) (value >>> 24));
197 }
198 }
199
200 static void setLong(long address, long value) {
201 if (UNALIGNED) {
202 PlatformDependent.putLong(address, BIG_ENDIAN_NATIVE_ORDER ? value : Long.reverseBytes(value));
203 } else {
204 PlatformDependent.putByte(address, (byte) (value >>> 56));
205 PlatformDependent.putByte(address + 1, (byte) (value >>> 48));
206 PlatformDependent.putByte(address + 2, (byte) (value >>> 40));
207 PlatformDependent.putByte(address + 3, (byte) (value >>> 32));
208 PlatformDependent.putByte(address + 4, (byte) (value >>> 24));
209 PlatformDependent.putByte(address + 5, (byte) (value >>> 16));
210 PlatformDependent.putByte(address + 6, (byte) (value >>> 8));
211 PlatformDependent.putByte(address + 7, (byte) value);
212 }
213 }
214
215 static void setLongLE(long address, long value) {
216 if (UNALIGNED) {
217 PlatformDependent.putLong(address, BIG_ENDIAN_NATIVE_ORDER ? Long.reverseBytes(value) : value);
218 } else {
219 PlatformDependent.putByte(address, (byte) value);
220 PlatformDependent.putByte(address + 1, (byte) (value >>> 8));
221 PlatformDependent.putByte(address + 2, (byte) (value >>> 16));
222 PlatformDependent.putByte(address + 3, (byte) (value >>> 24));
223 PlatformDependent.putByte(address + 4, (byte) (value >>> 32));
224 PlatformDependent.putByte(address + 5, (byte) (value >>> 40));
225 PlatformDependent.putByte(address + 6, (byte) (value >>> 48));
226 PlatformDependent.putByte(address + 7, (byte) (value >>> 56));
227 }
228 }
229
230 static byte getByte(byte[] array, int index) {
231 return PlatformDependent.getByte(array, index);
232 }
233
234 static short getShort(byte[] array, int index) {
235 if (UNALIGNED) {
236 short v = PlatformDependent.getShort(array, index);
237 return BIG_ENDIAN_NATIVE_ORDER ? v : Short.reverseBytes(v);
238 }
239 return (short) (PlatformDependent.getByte(array, index) << 8 |
240 PlatformDependent.getByte(array, index + 1) & 0xff);
241 }
242
243 static short getShortLE(byte[] array, int index) {
244 if (UNALIGNED) {
245 short v = PlatformDependent.getShort(array, index);
246 return BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes(v) : v;
247 }
248 return (short) (PlatformDependent.getByte(array, index) & 0xff |
249 PlatformDependent.getByte(array, index + 1) << 8);
250 }
251
252 static int getUnsignedMedium(byte[] array, int index) {
253 if (UNALIGNED) {
254 return (PlatformDependent.getByte(array, index) & 0xff) << 16 |
255 (BIG_ENDIAN_NATIVE_ORDER ? PlatformDependent.getShort(array, index + 1)
256 : Short.reverseBytes(PlatformDependent.getShort(array, index + 1)))
257 & 0xffff;
258 }
259 return (PlatformDependent.getByte(array, index) & 0xff) << 16 |
260 (PlatformDependent.getByte(array, index + 1) & 0xff) << 8 |
261 PlatformDependent.getByte(array, index + 2) & 0xff;
262 }
263
264 static int getUnsignedMediumLE(byte[] array, int index) {
265 if (UNALIGNED) {
266 return (PlatformDependent.getByte(array, index) & 0xff) |
267 ((BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes(PlatformDependent.getShort(array, index + 1))
268 : PlatformDependent.getShort(array, index + 1)) & 0xffff) << 8;
269 }
270 return PlatformDependent.getByte(array, index) & 0xff |
271 (PlatformDependent.getByte(array, index + 1) & 0xff) << 8 |
272 (PlatformDependent.getByte(array, index + 2) & 0xff) << 16;
273 }
274
275 static int getInt(byte[] array, int index) {
276 if (UNALIGNED) {
277 int v = PlatformDependent.getInt(array, index);
278 return BIG_ENDIAN_NATIVE_ORDER ? v : Integer.reverseBytes(v);
279 }
280 return PlatformDependent.getByte(array, index) << 24 |
281 (PlatformDependent.getByte(array, index + 1) & 0xff) << 16 |
282 (PlatformDependent.getByte(array, index + 2) & 0xff) << 8 |
283 PlatformDependent.getByte(array, index + 3) & 0xff;
284 }
285
286 static int getIntLE(byte[] array, int index) {
287 if (UNALIGNED) {
288 int v = PlatformDependent.getInt(array, index);
289 return BIG_ENDIAN_NATIVE_ORDER ? Integer.reverseBytes(v) : v;
290 }
291 return PlatformDependent.getByte(array, index) & 0xff |
292 (PlatformDependent.getByte(array, index + 1) & 0xff) << 8 |
293 (PlatformDependent.getByte(array, index + 2) & 0xff) << 16 |
294 PlatformDependent.getByte(array, index + 3) << 24;
295 }
296
297 static long getLong(byte[] array, int index) {
298 if (UNALIGNED) {
299 long v = PlatformDependent.getLong(array, index);
300 return BIG_ENDIAN_NATIVE_ORDER ? v : Long.reverseBytes(v);
301 }
302 return ((long) PlatformDependent.getByte(array, index)) << 56 |
303 (PlatformDependent.getByte(array, index + 1) & 0xffL) << 48 |
304 (PlatformDependent.getByte(array, index + 2) & 0xffL) << 40 |
305 (PlatformDependent.getByte(array, index + 3) & 0xffL) << 32 |
306 (PlatformDependent.getByte(array, index + 4) & 0xffL) << 24 |
307 (PlatformDependent.getByte(array, index + 5) & 0xffL) << 16 |
308 (PlatformDependent.getByte(array, index + 6) & 0xffL) << 8 |
309 (PlatformDependent.getByte(array, index + 7)) & 0xffL;
310 }
311
312 static long getLongLE(byte[] array, int index) {
313 if (UNALIGNED) {
314 long v = PlatformDependent.getLong(array, index);
315 return BIG_ENDIAN_NATIVE_ORDER ? Long.reverseBytes(v) : v;
316 }
317 return PlatformDependent.getByte(array, index) & 0xffL |
318 (PlatformDependent.getByte(array, index + 1) & 0xffL) << 8 |
319 (PlatformDependent.getByte(array, index + 2) & 0xffL) << 16 |
320 (PlatformDependent.getByte(array, index + 3) & 0xffL) << 24 |
321 (PlatformDependent.getByte(array, index + 4) & 0xffL) << 32 |
322 (PlatformDependent.getByte(array, index + 5) & 0xffL) << 40 |
323 (PlatformDependent.getByte(array, index + 6) & 0xffL) << 48 |
324 ((long) PlatformDependent.getByte(array, index + 7)) << 56;
325 }
326
327 static void setByte(byte[] array, int index, int value) {
328 PlatformDependent.putByte(array, index, (byte) value);
329 }
330
331 static void setShort(byte[] array, int index, int value) {
332 if (UNALIGNED) {
333 PlatformDependent.putShort(array, index,
334 BIG_ENDIAN_NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
335 } else {
336 PlatformDependent.putByte(array, index, (byte) (value >>> 8));
337 PlatformDependent.putByte(array, index + 1, (byte) value);
338 }
339 }
340
341 static void setShortLE(byte[] array, int index, int value) {
342 if (UNALIGNED) {
343 PlatformDependent.putShort(array, index,
344 BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes((short) value) : (short) value);
345 } else {
346 PlatformDependent.putByte(array, index, (byte) value);
347 PlatformDependent.putByte(array, index + 1, (byte) (value >>> 8));
348 }
349 }
350
351 static void setMedium(byte[] array, int index, int value) {
352 PlatformDependent.putByte(array, index, (byte) (value >>> 16));
353 if (UNALIGNED) {
354 PlatformDependent.putShort(array, index + 1,
355 BIG_ENDIAN_NATIVE_ORDER ? (short) value
356 : Short.reverseBytes((short) value));
357 } else {
358 PlatformDependent.putByte(array, index + 1, (byte) (value >>> 8));
359 PlatformDependent.putByte(array, index + 2, (byte) value);
360 }
361 }
362
363 static void setMediumLE(byte[] array, int index, int value) {
364 PlatformDependent.putByte(array, index, (byte) value);
365 if (UNALIGNED) {
366 PlatformDependent.putShort(array, index + 1,
367 BIG_ENDIAN_NATIVE_ORDER ? Short.reverseBytes((short) (value >>> 8))
368 : (short) (value >>> 8));
369 } else {
370 PlatformDependent.putByte(array, index + 1, (byte) (value >>> 8));
371 PlatformDependent.putByte(array, index + 2, (byte) (value >>> 16));
372 }
373 }
374
375 static void setInt(byte[] array, int index, int value) {
376 if (UNALIGNED) {
377 PlatformDependent.putInt(array, index, BIG_ENDIAN_NATIVE_ORDER ? value : Integer.reverseBytes(value));
378 } else {
379 PlatformDependent.putByte(array, index, (byte) (value >>> 24));
380 PlatformDependent.putByte(array, index + 1, (byte) (value >>> 16));
381 PlatformDependent.putByte(array, index + 2, (byte) (value >>> 8));
382 PlatformDependent.putByte(array, index + 3, (byte) value);
383 }
384 }
385
386 static void setIntLE(byte[] array, int index, int value) {
387 if (UNALIGNED) {
388 PlatformDependent.putInt(array, index, BIG_ENDIAN_NATIVE_ORDER ? Integer.reverseBytes(value) : value);
389 } else {
390 PlatformDependent.putByte(array, index, (byte) value);
391 PlatformDependent.putByte(array, index + 1, (byte) (value >>> 8));
392 PlatformDependent.putByte(array, index + 2, (byte) (value >>> 16));
393 PlatformDependent.putByte(array, index + 3, (byte) (value >>> 24));
394 }
395 }
396
397 static void setLong(byte[] array, int index, long value) {
398 if (UNALIGNED) {
399 PlatformDependent.putLong(array, index, BIG_ENDIAN_NATIVE_ORDER ? value : Long.reverseBytes(value));
400 } else {
401 PlatformDependent.putByte(array, index, (byte) (value >>> 56));
402 PlatformDependent.putByte(array, index + 1, (byte) (value >>> 48));
403 PlatformDependent.putByte(array, index + 2, (byte) (value >>> 40));
404 PlatformDependent.putByte(array, index + 3, (byte) (value >>> 32));
405 PlatformDependent.putByte(array, index + 4, (byte) (value >>> 24));
406 PlatformDependent.putByte(array, index + 5, (byte) (value >>> 16));
407 PlatformDependent.putByte(array, index + 6, (byte) (value >>> 8));
408 PlatformDependent.putByte(array, index + 7, (byte) value);
409 }
410 }
411
412 static void setLongLE(byte[] array, int index, long value) {
413 if (UNALIGNED) {
414 PlatformDependent.putLong(array, index, BIG_ENDIAN_NATIVE_ORDER ? Long.reverseBytes(value) : value);
415 } else {
416 PlatformDependent.putByte(array, index, (byte) value);
417 PlatformDependent.putByte(array, index + 1, (byte) (value >>> 8));
418 PlatformDependent.putByte(array, index + 2, (byte) (value >>> 16));
419 PlatformDependent.putByte(array, index + 3, (byte) (value >>> 24));
420 PlatformDependent.putByte(array, index + 4, (byte) (value >>> 32));
421 PlatformDependent.putByte(array, index + 5, (byte) (value >>> 40));
422 PlatformDependent.putByte(array, index + 6, (byte) (value >>> 48));
423 PlatformDependent.putByte(array, index + 7, (byte) (value >>> 56));
424 }
425 }
426
427 static void setZero(byte[] array, int index, int length) {
428 if (length == 0) {
429 return;
430 }
431 PlatformDependent.setMemory(array, index, length, ZERO);
432 }
433
434 static ByteBuf copy(AbstractByteBuf buf, long addr, int index, int length) {
435 buf.checkIndex(index, length);
436 ByteBuf copy = buf.alloc().directBuffer(length, buf.maxCapacity());
437 if (length != 0) {
438 if (copy.hasMemoryAddress()) {
439 PlatformDependent.copyMemory(addr, copy.memoryAddress(), length);
440 copy.setIndex(0, length);
441 } else {
442 copy.writeBytes(buf, index, length);
443 }
444 }
445 return copy;
446 }
447
448 static int setBytes(AbstractByteBuf buf, long addr, int index, InputStream in, int length) throws IOException {
449 buf.checkIndex(index, length);
450 ByteBuf tmpBuf = buf.alloc().heapBuffer(length);
451 try {
452 byte[] tmp = tmpBuf.array();
453 int offset = tmpBuf.arrayOffset();
454 int readBytes = in.read(tmp, offset, length);
455 if (readBytes > 0) {
456 PlatformDependent.copyMemory(tmp, offset, addr, readBytes);
457 }
458 return readBytes;
459 } finally {
460 tmpBuf.release();
461 }
462 }
463
464 static void getBytes(AbstractByteBuf buf, long addr, int index, ByteBuf dst, int dstIndex, int length) {
465 buf.checkIndex(index, length);
466 checkNotNull(dst, "dst");
467 if (isOutOfBounds(dstIndex, length, dst.capacity())) {
468 throw new IndexOutOfBoundsException("dstIndex: " + dstIndex);
469 }
470
471 if (dst.hasMemoryAddress()) {
472 PlatformDependent.copyMemory(addr, dst.memoryAddress() + dstIndex, length);
473 } else if (dst.hasArray()) {
474 PlatformDependent.copyMemory(addr, dst.array(), dst.arrayOffset() + dstIndex, length);
475 } else {
476 dst.setBytes(dstIndex, buf, index, length);
477 }
478 }
479
480 static void getBytes(AbstractByteBuf buf, long addr, int index, byte[] dst, int dstIndex, int length) {
481 buf.checkIndex(index, length);
482 checkNotNull(dst, "dst");
483 if (isOutOfBounds(dstIndex, length, dst.length)) {
484 throw new IndexOutOfBoundsException("dstIndex: " + dstIndex);
485 }
486 if (length != 0) {
487 PlatformDependent.copyMemory(addr, dst, dstIndex, length);
488 }
489 }
490
491 static void getBytes(AbstractByteBuf buf, long addr, int index, ByteBuffer dst) {
492 buf.checkIndex(index, dst.remaining());
493 if (dst.remaining() == 0) {
494 return;
495 }
496
497 if (dst.isDirect()) {
498 if (dst.isReadOnly()) {
499
500 throw new ReadOnlyBufferException();
501 }
502
503 long dstAddress = PlatformDependent.directBufferAddress(dst);
504 PlatformDependent.copyMemory(addr, dstAddress + dst.position(), dst.remaining());
505 dst.position(dst.position() + dst.remaining());
506 } else if (dst.hasArray()) {
507
508 PlatformDependent.copyMemory(addr, dst.array(), dst.arrayOffset() + dst.position(), dst.remaining());
509 dst.position(dst.position() + dst.remaining());
510 } else {
511 dst.put(buf.nioBuffer());
512 }
513 }
514
515 static void setBytes(AbstractByteBuf buf, long addr, int index, ByteBuf src, int srcIndex, int length) {
516 buf.checkIndex(index, length);
517 checkNotNull(src, "src");
518 if (isOutOfBounds(srcIndex, length, src.capacity())) {
519 throw new IndexOutOfBoundsException("srcIndex: " + srcIndex);
520 }
521
522 if (length != 0) {
523 if (src.hasMemoryAddress()) {
524 PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, addr, length);
525 } else if (src.hasArray()) {
526 PlatformDependent.copyMemory(src.array(), src.arrayOffset() + srcIndex, addr, length);
527 } else {
528 src.getBytes(srcIndex, buf, index, length);
529 }
530 }
531 }
532
533 static void setBytes(AbstractByteBuf buf, long addr, int index, byte[] src, int srcIndex, int length) {
534 buf.checkIndex(index, length);
535 if (length != 0) {
536 PlatformDependent.copyMemory(src, srcIndex, addr, length);
537 }
538 }
539
540 static void setBytes(AbstractByteBuf buf, long addr, int index, ByteBuffer src) {
541 final int length = src.remaining();
542 if (length == 0) {
543 return;
544 }
545
546 if (src.isDirect()) {
547 buf.checkIndex(index, length);
548
549 long srcAddress = PlatformDependent.directBufferAddress(src);
550 PlatformDependent.copyMemory(srcAddress + src.position(), addr, length);
551 src.position(src.position() + length);
552 } else if (src.hasArray()) {
553 buf.checkIndex(index, length);
554
555 PlatformDependent.copyMemory(src.array(), src.arrayOffset() + src.position(), addr, length);
556 src.position(src.position() + length);
557 } else {
558 if (length < 8) {
559 setSingleBytes(buf, addr, index, src, length);
560 } else {
561
562 assert buf.nioBufferCount() == 1;
563 final ByteBuffer internalBuffer = buf.internalNioBuffer(index, length);
564 internalBuffer.put(src);
565 }
566 }
567 }
568
569 private static void setSingleBytes(final AbstractByteBuf buf, final long addr, final int index,
570 final ByteBuffer src, final int length) {
571 buf.checkIndex(index, length);
572 final int srcPosition = src.position();
573 final int srcLimit = src.limit();
574 long dstAddr = addr;
575 for (int srcIndex = srcPosition; srcIndex < srcLimit; srcIndex++) {
576 final byte value = src.get(srcIndex);
577 PlatformDependent.putByte(dstAddr, value);
578 dstAddr++;
579 }
580 src.position(srcLimit);
581 }
582
583 static void getBytes(AbstractByteBuf buf, long addr, int index, OutputStream out, int length) throws IOException {
584 buf.checkIndex(index, length);
585 if (length != 0) {
586 int len = Math.min(length, ByteBufUtil.WRITE_CHUNK_SIZE);
587 if (len <= ByteBufUtil.MAX_TL_ARRAY_LEN || !buf.alloc().isDirectBufferPooled()) {
588 getBytes(addr, ByteBufUtil.threadLocalTempArray(len), 0, len, out, length);
589 } else {
590
591 ByteBuf tmpBuf = buf.alloc().heapBuffer(len);
592 try {
593 byte[] tmp = tmpBuf.array();
594 int offset = tmpBuf.arrayOffset();
595 getBytes(addr, tmp, offset, len, out, length);
596 } finally {
597 tmpBuf.release();
598 }
599 }
600 }
601 }
602
603 private static void getBytes(long inAddr, byte[] in, int inOffset, int inLen, OutputStream out, int outLen)
604 throws IOException {
605 do {
606 int len = Math.min(inLen, outLen);
607 PlatformDependent.copyMemory(inAddr, in, inOffset, len);
608 out.write(in, inOffset, len);
609 outLen -= len;
610 inAddr += len;
611 } while (outLen > 0);
612 }
613
614 static void setZero(long addr, int length) {
615 if (length == 0) {
616 return;
617 }
618
619 PlatformDependent.setMemory(addr, length, ZERO);
620 }
621
622 static UnpooledUnsafeDirectByteBuf newUnsafeDirectByteBuf(
623 ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
624 if (PlatformDependent.useDirectBufferNoCleaner()) {
625 return new UnpooledUnsafeNoCleanerDirectByteBuf(alloc, initialCapacity, maxCapacity);
626 }
627 return new UnpooledUnsafeDirectByteBuf(alloc, initialCapacity, maxCapacity);
628 }
629
630 private UnsafeByteBufUtil() { }
631 }
632