• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.nio;
28 
29 import java.io.FileDescriptor;
30 
31 import dalvik.system.VMRuntime;
32 import libcore.io.Memory;
33 import libcore.io.SizeOf;
34 import sun.misc.Cleaner;
35 import sun.nio.ch.DirectBuffer;
36 
37 /** @hide */
38 public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer {
39 
40     /**
41      * Stores the details of the memory backing a DirectByteBuffer. This could be a pointer
42      * (passed through from JNI or resulting from a mapping) or a non-movable byte array allocated
43      * from Java. Each MemoryRef also has an isAccessible associated with it, which determines
44      * whether the underlying memory is "accessible". The notion of "accessibility" is usually
45      * defined by the allocator of the reference, and is separate from the accessibility of the
46      * memory as defined by the underlying system.
47      *
48      * A single MemoryRef instance is shared across all slices and duplicates of a given buffer.
49      */
50     static class MemoryRef {
51         byte[] buffer;
52         long allocatedAddress;
53         final int offset;
54         boolean isAccessible;
55 
MemoryRef(int capacity)56         MemoryRef(int capacity) {
57             VMRuntime runtime = VMRuntime.getRuntime();
58             buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7);
59             allocatedAddress = runtime.addressOf(buffer);
60             // Offset is set to handle the alignment: http://b/16449607
61             offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress);
62             isAccessible = true;
63         }
64 
MemoryRef(long allocatedAddress)65         MemoryRef(long allocatedAddress) {
66             buffer = null;
67             this.allocatedAddress = allocatedAddress;
68             this.offset = 0;
69             isAccessible = true;
70         }
71 
free()72         void free() {
73             buffer = null;
74             allocatedAddress = 0;
75             isAccessible = false;
76         }
77     }
78 
79     final Cleaner cleaner;
80     final MemoryRef memoryRef;
81 
DirectByteBuffer(int capacity, MemoryRef memoryRef)82     DirectByteBuffer(int capacity, MemoryRef memoryRef) {
83         super(-1, 0, capacity, capacity, memoryRef.buffer, memoryRef.offset);
84         // Only have references to java objects, no need for a cleaner since the GC will do all
85         // the work.
86         this.memoryRef = memoryRef;
87         this.address = memoryRef.allocatedAddress + memoryRef.offset;
88         cleaner = null;
89         this.isReadOnly = false;
90     }
91 
92     // Invoked only by JNI: NewDirectByteBuffer(void*, long)
93     //
DirectByteBuffer(long addr, int cap)94     private DirectByteBuffer(long addr, int cap) {
95         super(-1, 0, cap, cap);
96         memoryRef = new MemoryRef(addr);
97         address = addr;
98         cleaner = null;
99     }
100 
101     /** @hide */
DirectByteBuffer(int cap, long addr, FileDescriptor fd, Runnable unmapper, boolean isReadOnly)102     public DirectByteBuffer(int cap, long addr,
103                             FileDescriptor fd,
104                             Runnable unmapper,
105                             boolean isReadOnly) {
106         super(-1, 0, cap, cap, fd);
107         this.isReadOnly = isReadOnly;
108         memoryRef = new MemoryRef(addr);
109         address = addr;
110         cleaner = Cleaner.create(memoryRef, unmapper);
111     }
112 
113     // For duplicates and slices
114     //
DirectByteBuffer(MemoryRef memoryRef, int mark, int pos, int lim, int cap, int off)115     DirectByteBuffer(MemoryRef memoryRef,         // package-private
116                      int mark, int pos, int lim, int cap,
117                      int off) {
118         this(memoryRef, mark, pos, lim, cap, off, false);
119     }
120 
DirectByteBuffer(MemoryRef memoryRef, int mark, int pos, int lim, int cap, int off, boolean isReadOnly)121     DirectByteBuffer(MemoryRef memoryRef,         // package-private
122                      int mark, int pos, int lim, int cap,
123                      int off, boolean isReadOnly) {
124         super(mark, pos, lim, cap, memoryRef.buffer, off);
125         this.isReadOnly = isReadOnly;
126         this.memoryRef = memoryRef;
127         address = memoryRef.allocatedAddress + off;
128         cleaner = null;
129     }
130 
131     @Override
attachment()132     public Object attachment() {
133         return memoryRef;
134     }
135 
136     @Override
cleaner()137     public Cleaner cleaner() {
138         return cleaner;
139     }
140 
slice()141     public ByteBuffer slice() {
142         if (!memoryRef.isAccessible) {
143             throw new IllegalStateException("buffer is inaccessible");
144         }
145         int pos = position();
146         int lim = limit();
147         assert (pos <= lim);
148         int rem = (pos <= lim ? lim - pos : 0);
149         int off = pos + offset;
150         assert (off >= 0);
151         return new DirectByteBuffer(memoryRef, -1, 0, rem, rem, off, isReadOnly);
152     }
153 
duplicate()154     public ByteBuffer duplicate() {
155         if (!memoryRef.isAccessible) {
156             throw new IllegalStateException("buffer is inaccessible");
157         }
158         return new DirectByteBuffer(memoryRef,
159                 this.markValue(),
160                 this.position(),
161                 this.limit(),
162                 this.capacity(),
163                 offset,
164                 isReadOnly);
165     }
166 
asReadOnlyBuffer()167     public ByteBuffer asReadOnlyBuffer() {
168         if (!memoryRef.isAccessible) {
169             throw new IllegalStateException("buffer is inaccessible");
170         }
171         return new DirectByteBuffer(memoryRef,
172                 this.markValue(),
173                 this.position(),
174                 this.limit(),
175                 this.capacity(),
176                 offset,
177                 true);
178     }
179 
180     @Override
address()181     public long address() {
182         return address;
183     }
184 
ix(int i)185     private long ix(int i) {
186         return address + i;
187     }
188 
get(long a)189     private byte get(long a) {
190         return Memory.peekByte(a);
191     }
192 
get()193     public byte get() {
194         if (!memoryRef.isAccessible) {
195             throw new IllegalStateException("buffer is inaccessible");
196         }
197         return get(ix(nextGetIndex()));
198     }
199 
get(int i)200     public byte get(int i) {
201         if (!memoryRef.isAccessible) {
202             throw new IllegalStateException("buffer is inaccessible");
203         }
204         return get(ix(checkIndex(i)));
205     }
206 
get(byte[] dst, int dstOffset, int length)207     public ByteBuffer get(byte[] dst, int dstOffset, int length) {
208         if (!memoryRef.isAccessible) {
209             throw new IllegalStateException("buffer is inaccessible");
210         }
211         checkBounds(dstOffset, length, dst.length);
212         int pos = position();
213         int lim = limit();
214         assert (pos <= lim);
215         int rem = (pos <= lim ? lim - pos : 0);
216         if (length > rem)
217             throw new BufferUnderflowException();
218         Memory.peekByteArray(ix(pos),
219                 dst, dstOffset, length);
220         position = pos + length;
221         return this;
222     }
223 
put(long a, byte x)224     public ByteBuffer put(long a, byte x) {
225         Memory.pokeByte(a, x);
226         return this;
227     }
228 
put(byte x)229     public ByteBuffer put(byte x) {
230         if (isReadOnly) {
231             throw new ReadOnlyBufferException();
232         }
233         if (!memoryRef.isAccessible) {
234             throw new IllegalStateException("buffer is inaccessible");
235         }
236         put(ix(nextPutIndex()), x);
237         return this;
238     }
239 
put(int i, byte x)240     public ByteBuffer put(int i, byte x) {
241         if (isReadOnly) {
242             throw new ReadOnlyBufferException();
243         }
244         if (!memoryRef.isAccessible) {
245             throw new IllegalStateException("buffer is inaccessible");
246         }
247         put(ix(checkIndex(i)), x);
248         return this;
249     }
250 
put(byte[] src, int srcOffset, int length)251     public ByteBuffer put(byte[] src, int srcOffset, int length) {
252         if (isReadOnly) {
253             throw new ReadOnlyBufferException();
254         }
255         if (!memoryRef.isAccessible) {
256             throw new IllegalStateException("buffer is inaccessible");
257         }
258         checkBounds(srcOffset, length, src.length);
259         int pos = position();
260         int lim = limit();
261         assert (pos <= lim);
262         int rem = (pos <= lim ? lim - pos : 0);
263         if (length > rem)
264             throw new BufferOverflowException();
265         Memory.pokeByteArray(ix(pos),
266                 src, srcOffset, length);
267         position = pos + length;
268         return this;
269     }
270 
compact()271     public ByteBuffer compact() {
272         if (isReadOnly) {
273             throw new ReadOnlyBufferException();
274         }
275         if (!memoryRef.isAccessible) {
276             throw new IllegalStateException("buffer is inaccessible");
277         }
278         int pos = position();
279         int lim = limit();
280         assert (pos <= lim);
281         int rem = (pos <= lim ? lim - pos : 0);
282         System.arraycopy(hb, position + offset, hb, offset, remaining());
283         position(rem);
284         limit(capacity());
285         discardMark();
286         return this;
287     }
288 
isDirect()289     public boolean isDirect() {
290         return true;
291     }
292 
isReadOnly()293     public boolean isReadOnly() {
294         return isReadOnly;
295     }
296 
_get(int i)297     byte _get(int i) {                          // package-private
298         return get(i);
299     }
300 
_put(int i, byte b)301     void _put(int i, byte b) {                  // package-private
302         put(i, b);
303     }
304 
getChar(long a)305     private char getChar(long a) {
306         if (!memoryRef.isAccessible) {
307             throw new IllegalStateException("buffer is inaccessible");
308         }
309         return (char) Memory.peekShort(position, !nativeByteOrder);
310     }
311 
getChar()312     public char getChar() {
313         if (!memoryRef.isAccessible) {
314             throw new IllegalStateException("buffer is inaccessible");
315         }
316         int newPosition = position + SizeOf.CHAR;
317         if (newPosition > limit()) {
318             throw new BufferUnderflowException();
319         }
320         char x = (char) Memory.peekShort(ix(position), !nativeByteOrder);
321         position = newPosition;
322         return x;
323     }
324 
getChar(int i)325     public char getChar(int i) {
326         if (!memoryRef.isAccessible) {
327             throw new IllegalStateException("buffer is inaccessible");
328         }
329         checkIndex(i, SizeOf.CHAR);
330         char x = (char) Memory.peekShort(ix(i), !nativeByteOrder);
331         return x;
332     }
333 
getCharUnchecked(int i)334     char getCharUnchecked(int i) {
335         return (char) Memory.peekShort(ix(i), !nativeByteOrder);
336     }
337 
getUnchecked(int pos, char[] dst, int dstOffset, int length)338     void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
339         Memory.peekCharArray(ix(pos),
340                 dst, dstOffset, length, !nativeByteOrder);
341     }
342 
343 
putChar(long a, char x)344     private ByteBuffer putChar(long a, char x) {
345         Memory.pokeShort(a, (short) x, !nativeByteOrder);
346         return this;
347     }
348 
putChar(char x)349     public ByteBuffer putChar(char x) {
350         if (isReadOnly) {
351             throw new ReadOnlyBufferException();
352         }
353         if (!memoryRef.isAccessible) {
354             throw new IllegalStateException("buffer is inaccessible");
355         }
356         putChar(ix(nextPutIndex(SizeOf.CHAR)), x);
357         return this;
358     }
359 
putChar(int i, char x)360     public ByteBuffer putChar(int i, char x) {
361         if (isReadOnly) {
362             throw new ReadOnlyBufferException();
363         }
364         if (!memoryRef.isAccessible) {
365             throw new IllegalStateException("buffer is inaccessible");
366         }
367         putChar(ix(checkIndex(i, SizeOf.CHAR)), x);
368         return this;
369     }
370 
putCharUnchecked(int i, char x)371     void putCharUnchecked(int i, char x) {
372         putChar(ix(i), x);
373     }
374 
putUnchecked(int pos, char[] src, int srcOffset, int length)375     void putUnchecked(int pos, char[] src, int srcOffset, int length) {
376         Memory.pokeCharArray(ix(pos),
377                 src, srcOffset, length, !nativeByteOrder);
378     }
379 
asCharBuffer()380     public CharBuffer asCharBuffer() {
381         if (!memoryRef.isAccessible) {
382             throw new IllegalStateException("buffer is inaccessible");
383         }
384         int off = this.position();
385         int lim = this.limit();
386         assert (off <= lim);
387         int rem = (off <= lim ? lim - off : 0);
388         int size = rem >> 1;
389         return (CharBuffer) (new ByteBufferAsCharBuffer(this,
390                 -1,
391                 0,
392                 size,
393                 size,
394                 off,
395                 order()));
396     }
397 
getShort(long a)398     private short getShort(long a) {
399         return Memory.peekShort(a, !nativeByteOrder);
400     }
401 
getShort()402     public short getShort() {
403         if (!memoryRef.isAccessible) {
404             throw new IllegalStateException("buffer is inaccessible");
405         }
406         return getShort(ix(nextGetIndex(SizeOf.SHORT)));
407     }
408 
getShort(int i)409     public short getShort(int i) {
410         if (!memoryRef.isAccessible) {
411             throw new IllegalStateException("buffer is inaccessible");
412         }
413         return getShort(ix(checkIndex(i, SizeOf.SHORT)));
414     }
415 
getShortUnchecked(int i)416     short getShortUnchecked(int i) {
417         return getShort(ix(i));
418     }
419 
getUnchecked(int pos, short[] dst, int dstOffset, int length)420     void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
421         Memory.peekShortArray(ix(pos),
422                 dst, dstOffset, length, !nativeByteOrder);
423     }
424 
425 
putShort(long a, short x)426     private ByteBuffer putShort(long a, short x) {
427         Memory.pokeShort(a, x, !nativeByteOrder);
428         return this;
429     }
430 
putShort(short x)431     public ByteBuffer putShort(short x) {
432         if (isReadOnly) {
433             throw new ReadOnlyBufferException();
434         }
435         if (!memoryRef.isAccessible) {
436             throw new IllegalStateException("buffer is inaccessible");
437         }
438         putShort(ix(nextPutIndex(SizeOf.SHORT)), x);
439         return this;
440     }
441 
putShort(int i, short x)442     public ByteBuffer putShort(int i, short x) {
443         if (isReadOnly) {
444             throw new ReadOnlyBufferException();
445         }
446         if (!memoryRef.isAccessible) {
447             throw new IllegalStateException("buffer is inaccessible");
448         }
449         putShort(ix(checkIndex(i, SizeOf.SHORT)), x);
450         return this;
451     }
452 
putShortUnchecked(int i, short x)453     void putShortUnchecked(int i, short x) {
454         putShort(ix(i), x);
455     }
456 
putUnchecked(int pos, short[] src, int srcOffset, int length)457     void putUnchecked(int pos, short[] src, int srcOffset, int length) {
458         Memory.pokeShortArray(ix(pos),
459                 src, srcOffset, length, !nativeByteOrder);
460     }
461 
asShortBuffer()462     public ShortBuffer asShortBuffer() {
463         if (!memoryRef.isAccessible) {
464             throw new IllegalStateException("buffer is inaccessible");
465         }
466         int off = this.position();
467         int lim = this.limit();
468         assert (off <= lim);
469         int rem = (off <= lim ? lim - off : 0);
470         int size = rem >> 1;
471         return (ShortBuffer) (new ByteBufferAsShortBuffer(this,
472                 -1,
473                 0,
474                 size,
475                 size,
476                 off,
477                 order()));
478     }
479 
getInt(long a)480     private int getInt(long a) {
481         return Memory.peekInt(a, !nativeByteOrder);
482     }
483 
getInt()484     public int getInt() {
485         if (!memoryRef.isAccessible) {
486             throw new IllegalStateException("buffer is inaccessible");
487         }
488         return getInt(ix(nextGetIndex(SizeOf.INT)));
489     }
490 
getInt(int i)491     public int getInt(int i) {
492         if (!memoryRef.isAccessible) {
493             throw new IllegalStateException("buffer is inaccessible");
494         }
495         return getInt(ix(checkIndex(i, (SizeOf.INT))));
496     }
497 
getIntUnchecked(int i)498     int getIntUnchecked(int i) {
499         return getInt(ix(i));
500     }
501 
getUnchecked(int pos, int[] dst, int dstOffset, int length)502     void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
503         Memory.peekIntArray(ix(pos),
504                 dst, dstOffset, length, !nativeByteOrder);
505     }
506 
putInt(long a, int x)507     private ByteBuffer putInt(long a, int x) {
508         Memory.pokeInt(a, x, !nativeByteOrder);
509         return this;
510     }
511 
putInt(int x)512     public ByteBuffer putInt(int x) {
513         if (isReadOnly) {
514             throw new ReadOnlyBufferException();
515         }
516         if (!memoryRef.isAccessible) {
517             throw new IllegalStateException("buffer is inaccessible");
518         }
519         putInt(ix(nextPutIndex(SizeOf.INT)), x);
520         return this;
521     }
522 
putInt(int i, int x)523     public ByteBuffer putInt(int i, int x) {
524         if (isReadOnly) {
525             throw new ReadOnlyBufferException();
526         }
527         if (!memoryRef.isAccessible) {
528             throw new IllegalStateException("buffer is inaccessible");
529         }
530         putInt(ix(checkIndex(i, SizeOf.INT)), x);
531         return this;
532     }
533 
putIntUnchecked(int i, int x)534     void putIntUnchecked(int i, int x) {
535         putInt(ix(i), x);
536     }
537 
putUnchecked(int pos, int[] src, int srcOffset, int length)538     void putUnchecked(int pos, int[] src, int srcOffset, int length) {
539         Memory.pokeIntArray(ix(pos),
540                 src, srcOffset, length, !nativeByteOrder);
541     }
542 
543 
asIntBuffer()544     public IntBuffer asIntBuffer() {
545         if (!memoryRef.isAccessible) {
546             throw new IllegalStateException("buffer is inaccessible");
547         }
548         int off = this.position();
549         int lim = this.limit();
550         assert (off <= lim);
551         int rem = (off <= lim ? lim - off : 0);
552         int size = rem >> 2;
553         return (IntBuffer) (new ByteBufferAsIntBuffer(this,
554                 -1,
555                 0,
556                 size,
557                 size,
558                 off,
559                 order()));
560     }
561 
getLong(long a)562     private long getLong(long a) {
563         return Memory.peekLong(a, !nativeByteOrder);
564     }
565 
getLong()566     public long getLong() {
567         if (!memoryRef.isAccessible) {
568             throw new IllegalStateException("buffer is inaccessible");
569         }
570         return getLong(ix(nextGetIndex(SizeOf.LONG)));
571     }
572 
getLong(int i)573     public long getLong(int i) {
574         if (!memoryRef.isAccessible) {
575             throw new IllegalStateException("buffer is inaccessible");
576         }
577         return getLong(ix(checkIndex(i, SizeOf.LONG)));
578     }
579 
getLongUnchecked(int i)580     long getLongUnchecked(int i) {
581         return getLong(ix(i));
582     }
583 
getUnchecked(int pos, long[] dst, int dstOffset, int length)584     void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
585         Memory.peekLongArray(ix(pos),
586                 dst, dstOffset, length, !nativeByteOrder);
587     }
588 
putLong(long a, long x)589     private ByteBuffer putLong(long a, long x) {
590         Memory.pokeLong(a, x, !nativeByteOrder);
591         return this;
592     }
593 
putLong(long x)594     public ByteBuffer putLong(long x) {
595         if (isReadOnly) {
596             throw new ReadOnlyBufferException();
597         }
598         if (!memoryRef.isAccessible) {
599             throw new IllegalStateException("buffer is inaccessible");
600         }
601         putLong(ix(nextPutIndex(SizeOf.LONG)), x);
602         return this;
603     }
604 
putLong(int i, long x)605     public ByteBuffer putLong(int i, long x) {
606         if (isReadOnly) {
607             throw new ReadOnlyBufferException();
608         }
609         if (!memoryRef.isAccessible) {
610             throw new IllegalStateException("buffer is inaccessible");
611         }
612         putLong(ix(checkIndex(i, SizeOf.LONG)), x);
613         return this;
614     }
615 
putLongUnchecked(int i, long x)616     void putLongUnchecked(int i, long x) {
617         putLong(ix(i), x);
618     }
619 
putUnchecked(int pos, long[] src, int srcOffset, int length)620     void putUnchecked(int pos, long[] src, int srcOffset, int length) {
621         Memory.pokeLongArray(ix(pos),
622                 src, srcOffset, length, !nativeByteOrder);
623     }
624 
625 
asLongBuffer()626     public LongBuffer asLongBuffer() {
627         if (!memoryRef.isAccessible) {
628             throw new IllegalStateException("buffer is inaccessible");
629         }
630         int off = this.position();
631         int lim = this.limit();
632         assert (off <= lim);
633         int rem = (off <= lim ? lim - off : 0);
634         int size = rem >> 3;
635         return (LongBuffer) (new ByteBufferAsLongBuffer(this,
636                 -1,
637                 0,
638                 size,
639                 size,
640                 off,
641                 order()));
642     }
643 
getFloat(long a)644     private float getFloat(long a) {
645         int x = Memory.peekInt(a, !nativeByteOrder);
646         return Float.intBitsToFloat(x);
647     }
648 
getFloat()649     public float getFloat() {
650         if (!memoryRef.isAccessible) {
651             throw new IllegalStateException("buffer is inaccessible");
652         }
653         return getFloat(ix(nextGetIndex(SizeOf.FLOAT)));
654     }
655 
getFloat(int i)656     public float getFloat(int i) {
657         if (!memoryRef.isAccessible) {
658             throw new IllegalStateException("buffer is inaccessible");
659         }
660         return getFloat(ix(checkIndex(i, SizeOf.FLOAT)));
661     }
662 
getFloatUnchecked(int i)663     float getFloatUnchecked(int i) {
664         return getFloat(ix(i));
665     }
666 
getUnchecked(int pos, float[] dst, int dstOffset, int length)667     void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
668         Memory.peekFloatArray(ix(pos),
669                 dst, dstOffset, length, !nativeByteOrder);
670     }
671 
putFloat(long a, float x)672     private ByteBuffer putFloat(long a, float x) {
673         int y = Float.floatToRawIntBits(x);
674         Memory.pokeInt(a, y, !nativeByteOrder);
675         return this;
676     }
677 
putFloat(float x)678     public ByteBuffer putFloat(float x) {
679         if (isReadOnly) {
680             throw new ReadOnlyBufferException();
681         }
682         if (!memoryRef.isAccessible) {
683             throw new IllegalStateException("buffer is inaccessible");
684         }
685         putFloat(ix(nextPutIndex(SizeOf.FLOAT)), x);
686         return this;
687     }
688 
putFloat(int i, float x)689     public ByteBuffer putFloat(int i, float x) {
690         if (isReadOnly) {
691             throw new ReadOnlyBufferException();
692         }
693         if (!memoryRef.isAccessible) {
694             throw new IllegalStateException("buffer is inaccessible");
695         }
696         putFloat(ix(checkIndex(i, SizeOf.FLOAT)), x);
697         return this;
698     }
699 
putFloatUnchecked(int i, float x)700     void putFloatUnchecked(int i, float x) {
701         putFloat(ix(i), x);
702     }
703 
putUnchecked(int pos, float[] src, int srcOffset, int length)704     void putUnchecked(int pos, float[] src, int srcOffset, int length) {
705         Memory.pokeFloatArray(ix(pos),
706                 src, srcOffset, length, !nativeByteOrder);
707     }
708 
asFloatBuffer()709     public FloatBuffer asFloatBuffer() {
710         if (!memoryRef.isAccessible) {
711             throw new IllegalStateException("buffer is inaccessible");
712         }
713         int off = this.position();
714         int lim = this.limit();
715         assert (off <= lim);
716         int rem = (off <= lim ? lim - off : 0);
717         int size = rem >> 2;
718         return (FloatBuffer) (new ByteBufferAsFloatBuffer(this,
719                 -1,
720                 0,
721                 size,
722                 size,
723                 off,
724                 order()));
725     }
726 
getDouble(long a)727     private double getDouble(long a) {
728         long x = Memory.peekLong(a, !nativeByteOrder);
729         return Double.longBitsToDouble(x);
730     }
731 
getDouble()732     public double getDouble() {
733         if (!memoryRef.isAccessible) {
734             throw new IllegalStateException("buffer is inaccessible");
735         }
736         return getDouble(ix(nextGetIndex(SizeOf.DOUBLE)));
737     }
738 
getDouble(int i)739     public double getDouble(int i) {
740         if (!memoryRef.isAccessible) {
741             throw new IllegalStateException("buffer is inaccessible");
742         }
743         return getDouble(ix(checkIndex(i, SizeOf.DOUBLE)));
744     }
745 
getDoubleUnchecked(int i)746     double getDoubleUnchecked(int i) {
747         return getDouble(ix(i));
748     }
749 
getUnchecked(int pos, double[] dst, int dstOffset, int length)750     void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
751         Memory.peekDoubleArray(ix(pos),
752                 dst, dstOffset, length, !nativeByteOrder);
753     }
754 
putDouble(long a, double x)755     private ByteBuffer putDouble(long a, double x) {
756         long y = Double.doubleToRawLongBits(x);
757         Memory.pokeLong(a, y, !nativeByteOrder);
758         return this;
759     }
760 
putDouble(double x)761     public ByteBuffer putDouble(double x) {
762         if (isReadOnly) {
763             throw new ReadOnlyBufferException();
764         }
765         if (!memoryRef.isAccessible) {
766             throw new IllegalStateException("buffer is inaccessible");
767         }
768         putDouble(ix(nextPutIndex(SizeOf.DOUBLE)), x);
769         return this;
770     }
771 
putDouble(int i, double x)772     public ByteBuffer putDouble(int i, double x) {
773         if (isReadOnly) {
774             throw new ReadOnlyBufferException();
775         }
776         if (!memoryRef.isAccessible) {
777             throw new IllegalStateException("buffer is inaccessible");
778         }
779         putDouble(ix(checkIndex(i, SizeOf.DOUBLE)), x);
780         return this;
781     }
782 
putDoubleUnchecked(int i, double x)783     void putDoubleUnchecked(int i, double x) {
784         putDouble(ix(i), x);
785     }
786 
putUnchecked(int pos, double[] src, int srcOffset, int length)787     void putUnchecked(int pos, double[] src, int srcOffset, int length) {
788         Memory.pokeDoubleArray(ix(pos),
789                 src, srcOffset, length, !nativeByteOrder);
790     }
791 
asDoubleBuffer()792     public DoubleBuffer asDoubleBuffer() {
793         if (!memoryRef.isAccessible) {
794             throw new IllegalStateException("buffer is inaccessible");
795         }
796         int off = this.position();
797         int lim = this.limit();
798         assert (off <= lim);
799         int rem = (off <= lim ? lim - off : 0);
800 
801         int size = rem >> 3;
802         return (DoubleBuffer) (new ByteBufferAsDoubleBuffer(this,
803                 -1,
804                 0,
805                 size,
806                 size,
807                 off,
808                 order()));
809     }
810 
isAccessible()811     public boolean isAccessible() {
812         return memoryRef.isAccessible;
813     }
814 
setAccessible(boolean value)815     public void setAccessible(boolean value) {
816         memoryRef.isAccessible = value;
817     }
818 }
819