View Javadoc
1   /*
2    * Copyright 2015 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
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  /**
32   * All operations get and set as {@link ByteOrder#BIG_ENDIAN}.
33   */
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                 // We need to check if dst is ready-only so we not write something in it by using Unsafe.
500                 throw new ReadOnlyBufferException();
501             }
502             // Copy to direct memory
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             // Copy to array
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         buf.checkIndex(index, src.remaining());
542 
543         int length = src.remaining();
544         if (length == 0) {
545             return;
546         }
547 
548         if (src.isDirect()) {
549             // Copy from direct memory
550             long srcAddress = PlatformDependent.directBufferAddress(src);
551             PlatformDependent.copyMemory(srcAddress + src.position(), addr, src.remaining());
552             src.position(src.position() + length);
553         } else if (src.hasArray()) {
554             // Copy from array
555             PlatformDependent.copyMemory(src.array(), src.arrayOffset() + src.position(), addr, length);
556             src.position(src.position() + length);
557         } else {
558             ByteBuf tmpBuf = buf.alloc().heapBuffer(length);
559             try {
560                 byte[] tmp = tmpBuf.array();
561                 src.get(tmp, tmpBuf.arrayOffset(), length); // moves the src position too
562                 PlatformDependent.copyMemory(tmp, tmpBuf.arrayOffset(), addr, length);
563             } finally {
564                 tmpBuf.release();
565             }
566         }
567     }
568 
569     static void getBytes(AbstractByteBuf buf, long addr, int index, OutputStream out, int length) throws IOException {
570         buf.checkIndex(index, length);
571         if (length != 0) {
572             ByteBuf tmpBuf = buf.alloc().heapBuffer(length);
573             try {
574                 byte[] tmp = tmpBuf.array();
575                 int offset = tmpBuf.arrayOffset();
576                 PlatformDependent.copyMemory(addr, tmp, offset, length);
577                 out.write(tmp, offset, length);
578             } finally {
579                 tmpBuf.release();
580             }
581         }
582     }
583 
584     static void setZero(long addr, int length) {
585         if (length == 0) {
586             return;
587         }
588 
589         PlatformDependent.setMemory(addr, length, ZERO);
590     }
591 
592     static UnpooledUnsafeDirectByteBuf newUnsafeDirectByteBuf(
593             ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
594         if (PlatformDependent.useDirectBufferNoCleaner()) {
595             return new UnpooledUnsafeNoCleanerDirectByteBuf(alloc, initialCapacity, maxCapacity);
596         }
597         return new UnpooledUnsafeDirectByteBuf(alloc, initialCapacity, maxCapacity);
598     }
599 
600     private UnsafeByteBufUtil() { }
601 }