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 import java.util.Objects; 31 32 import dalvik.annotation.codegen.CovariantReturnType; 33 import dalvik.annotation.compat.VersionCodes; 34 import dalvik.system.VMRuntime; 35 import libcore.io.Memory; 36 import sun.misc.Cleaner; 37 import sun.nio.ch.DirectBuffer; 38 39 // Not final because it is extended in tests. 40 /** @hide */ 41 public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer { 42 43 /** 44 * Stores the details of the memory backing a DirectByteBuffer. This could be a pointer 45 * (passed through from JNI or resulting from a mapping) or a non-movable byte array allocated 46 * from Java. Each MemoryRef also has an isAccessible associated with it, which determines 47 * whether the underlying memory is "accessible". The notion of "accessibility" is usually 48 * defined by the allocator of the reference, and is separate from the accessibility of the 49 * memory as defined by the underlying system. 50 * 51 * A single MemoryRef instance is shared across all slices and duplicates of a given buffer. 52 */ 53 final static class MemoryRef { 54 byte[] buffer; 55 long allocatedAddress; 56 final int offset; 57 boolean isAccessible; 58 boolean isFreed; 59 60 61 // Reference to original DirectByteBuffer that held this MemoryRef. The field is set 62 // only for the MemoryRef created through JNI NewDirectByteBuffer(void*, long) function. 63 // This allows users of JNI NewDirectByteBuffer to create a PhantomReference on the 64 // DirectByteBuffer instance that will only be put in the associated ReferenceQueue when 65 // the underlying memory is not referenced by any DirectByteBuffer instance. The 66 // MemoryRef can outlive the original DirectByteBuffer instance if, for example, slice() 67 // or asReadOnlyBuffer() are called and all strong references to the original DirectByteBuffer 68 // are discarded. 69 final Object originalBufferObject; 70 MemoryRef(int capacity)71 MemoryRef(int capacity) { 72 VMRuntime runtime = VMRuntime.getRuntime(); 73 buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7); 74 allocatedAddress = runtime.addressOf(buffer); 75 // Offset is set to handle the alignment: http://b/16449607 76 offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress); 77 isAccessible = true; 78 isFreed = false; 79 originalBufferObject = null; 80 } 81 MemoryRef(long allocatedAddress, Object originalBufferObject)82 MemoryRef(long allocatedAddress, Object originalBufferObject) { 83 buffer = null; 84 this.allocatedAddress = allocatedAddress; 85 this.offset = 0; 86 this.originalBufferObject = originalBufferObject; 87 isAccessible = true; 88 } 89 free()90 void free() { 91 buffer = null; 92 allocatedAddress = 0; 93 isAccessible = false; 94 isFreed = true; 95 } 96 } 97 98 final Cleaner cleaner; 99 final MemoryRef memoryRef; 100 DirectByteBuffer(int capacity, MemoryRef memoryRef)101 DirectByteBuffer(int capacity, MemoryRef memoryRef) { 102 super(-1, 0, capacity, capacity, memoryRef.buffer, memoryRef.offset); 103 // Only have references to java objects, no need for a cleaner since the GC will do all 104 // the work. 105 this.memoryRef = memoryRef; 106 this.address = memoryRef.allocatedAddress + memoryRef.offset; 107 cleaner = null; 108 this.isReadOnly = false; 109 } 110 111 // Invoked only by JNI: NewDirectByteBuffer(void*, long) 112 @SuppressWarnings("unused") DirectByteBuffer(long addr, int cap)113 private DirectByteBuffer(long addr, int cap) { 114 super(-1, 0, cap, cap); 115 memoryRef = new MemoryRef(addr, this); 116 address = addr; 117 cleaner = null; 118 } 119 120 // BEGIN Android-changed: Remove MemorySegmentProxy and merge with read-only buffer. 121 /** @hide */ DirectByteBuffer(int cap, long addr, FileDescriptor fd, Runnable unmapper, boolean isReadOnly)122 public DirectByteBuffer(int cap, long addr, 123 FileDescriptor fd, 124 Runnable unmapper, 125 boolean isReadOnly) { 126 super(-1, 0, cap, cap, fd, false); 127 this.isReadOnly = isReadOnly; 128 memoryRef = new MemoryRef(addr, null); 129 address = addr; 130 cleaner = Cleaner.create(memoryRef, unmapper); 131 } 132 // END Android-changed: Remove MemorySegmentProxy and merge with read-only buffer. 133 134 // BEGIN Android-changed: Android needs MemoryRef for direct allocated buffer. 135 // For duplicates and slices DirectByteBuffer(MemoryRef memoryRef, int mark, int pos, int lim, int cap, int off)136 DirectByteBuffer(MemoryRef memoryRef, // package-private 137 int mark, int pos, int lim, int cap, 138 int off) { 139 this(memoryRef, mark, pos, lim, cap, off, false); 140 } 141 DirectByteBuffer(MemoryRef memoryRef, int mark, int pos, int lim, int cap, int off, boolean isReadOnly)142 DirectByteBuffer(MemoryRef memoryRef, // package-private 143 int mark, int pos, int lim, int cap, 144 int off, boolean isReadOnly) { 145 super(mark, pos, lim, cap, memoryRef.buffer, off); 146 this.isReadOnly = isReadOnly; 147 this.memoryRef = memoryRef; 148 address = memoryRef.allocatedAddress + off; 149 cleaner = null; 150 } 151 // END Android-changed: Android needs MemoryRef for direct allocated buffer. 152 153 @Override attachment()154 public final Object attachment() { 155 return memoryRef; 156 } 157 158 @Override cleaner()159 public final Cleaner cleaner() { 160 return cleaner; 161 } 162 163 @Override base()164 Object base() { 165 return null; 166 } 167 168 @Override slice()169 public final MappedByteBuffer slice() { 170 if (!memoryRef.isAccessible) { 171 throw new IllegalStateException("buffer is inaccessible"); 172 } 173 int pos = position(); 174 int lim = limit(); 175 assert (pos <= lim); 176 int rem = (pos <= lim ? lim - pos : 0); 177 int off = pos + offset; 178 assert (off >= 0); 179 return new DirectByteBuffer(memoryRef, -1, 0, rem, rem, off, isReadOnly); 180 } 181 182 @Override slice(int index, int length)183 public final MappedByteBuffer slice(int index, int length) { 184 if (!memoryRef.isAccessible) { 185 throw new IllegalStateException("buffer is inaccessible"); 186 } 187 Objects.checkFromIndexSize(index, length, limit()); 188 return new DirectByteBuffer(memoryRef, 189 -1, 190 0, 191 length, 192 length, 193 // Android-changed: The constructor's argument means the offset from the allocated address. 194 // index << 0, 195 index + offset, 196 isReadOnly); 197 } 198 199 @Override duplicate()200 public final MappedByteBuffer duplicate() { 201 if (memoryRef.isFreed) { 202 throw new IllegalStateException("buffer has been freed"); 203 } 204 return new DirectByteBuffer(memoryRef, 205 this.markValue(), 206 this.position(), 207 this.limit(), 208 this.capacity(), 209 offset, 210 isReadOnly); 211 } 212 213 @Override asReadOnlyBuffer()214 public final ByteBuffer asReadOnlyBuffer() { 215 if (memoryRef.isFreed) { 216 throw new IllegalStateException("buffer has been freed"); 217 } 218 return new DirectByteBuffer(memoryRef, 219 this.markValue(), 220 this.position(), 221 this.limit(), 222 this.capacity(), 223 offset, 224 true); 225 } 226 227 @Override address()228 public final long address() { 229 return address; 230 } 231 ix(int i)232 private long ix(int i) { 233 return address + i; 234 } 235 get(long a)236 private byte get(long a) { 237 return Memory.peekByte(a); 238 } 239 240 @Override get()241 public final byte get() { 242 if (!memoryRef.isAccessible) { 243 throw new IllegalStateException("buffer is inaccessible"); 244 } 245 return get(ix(nextGetIndex())); 246 } 247 248 @Override get(int i)249 public final byte get(int i) { 250 if (!memoryRef.isAccessible) { 251 throw new IllegalStateException("buffer is inaccessible"); 252 } 253 return get(ix(checkIndex(i))); 254 } 255 256 // This method is not declared final because it is overridden in tests. 257 @Override get(byte[] dst, int dstOffset, int length)258 public ByteBuffer get(byte[] dst, int dstOffset, int length) { 259 if (!memoryRef.isAccessible) { 260 throw new IllegalStateException("buffer is inaccessible"); 261 } 262 checkBounds(dstOffset, length, dst.length); 263 int pos = position(); 264 int lim = limit(); 265 assert (pos <= lim); 266 int rem = (pos <= lim ? lim - pos : 0); 267 if (length > rem) 268 throw new BufferUnderflowException(); 269 Memory.peekByteArray(ix(pos), 270 dst, dstOffset, length); 271 position = pos + length; 272 return this; 273 } 274 put(long a, byte x)275 private ByteBuffer put(long a, byte x) { 276 Memory.pokeByte(a, x); 277 return this; 278 } 279 280 @Override put(ByteBuffer src)281 public ByteBuffer put(ByteBuffer src) { 282 if (!memoryRef.isAccessible) { 283 throw new IllegalStateException("buffer is inaccessible"); 284 } 285 return super.put(src); 286 } 287 288 @Override put(byte x)289 public final ByteBuffer put(byte x) { 290 if (!memoryRef.isAccessible) { 291 throw new IllegalStateException("buffer is inaccessible"); 292 } 293 if (isReadOnly) { 294 throw new ReadOnlyBufferException(); 295 } 296 put(ix(nextPutIndex()), x); 297 return this; 298 } 299 300 @Override put(int i, byte x)301 public final ByteBuffer put(int i, byte x) { 302 if (!memoryRef.isAccessible) { 303 throw new IllegalStateException("buffer is inaccessible"); 304 } 305 if (isReadOnly) { 306 throw new ReadOnlyBufferException(); 307 } 308 put(ix(checkIndex(i)), x); 309 return this; 310 } 311 312 // This method is not declared final because it is overridden in tests. 313 @Override put(byte[] src, int srcOffset, int length)314 public ByteBuffer put(byte[] src, int srcOffset, int length) { 315 if (!memoryRef.isAccessible) { 316 throw new IllegalStateException("buffer is inaccessible"); 317 } 318 if (isReadOnly) { 319 throw new ReadOnlyBufferException(); 320 } 321 checkBounds(srcOffset, length, src.length); 322 int pos = position(); 323 int lim = limit(); 324 assert (pos <= lim); 325 int rem = (pos <= lim ? lim - pos : 0); 326 if (length > rem) 327 throw new BufferOverflowException(); 328 Memory.pokeByteArray(ix(pos), 329 src, srcOffset, length); 330 position = pos + length; 331 return this; 332 } 333 334 // Android-changed: covariant overloads of *Buffer methods that return this. 335 @CovariantReturnType(returnType = MappedByteBuffer.class, presentAfter = 34) 336 @Override compact()337 public final ByteBuffer compact() { 338 if (!memoryRef.isAccessible) { 339 throw new IllegalStateException("buffer is inaccessible"); 340 } 341 if (isReadOnly) { 342 throw new ReadOnlyBufferException(); 343 } 344 int pos = position(); 345 int lim = limit(); 346 assert (pos <= lim); 347 int rem = (pos <= lim ? lim - pos : 0); 348 System.arraycopy(hb, position + offset, hb, offset, remaining()); 349 position(rem); 350 limit(capacity()); 351 discardMark(); 352 return this; 353 } 354 355 @Override isDirect()356 public final boolean isDirect() { 357 return true; 358 } 359 360 @Override isReadOnly()361 public final boolean isReadOnly() { 362 return isReadOnly; 363 } 364 365 // Used by java.nio.Bits 366 @Override _get(int i)367 final byte _get(int i) { // package-private 368 return get(i); 369 } 370 371 // Used by java.nio.Bits 372 @Override _put(int i, byte b)373 final void _put(int i, byte b) { // package-private 374 put(i, b); 375 } 376 377 @Override getChar()378 public final char getChar() { 379 if (!memoryRef.isAccessible) { 380 throw new IllegalStateException("buffer is inaccessible"); 381 } 382 int newPosition = position + Character.BYTES; 383 if (newPosition > limit()) { 384 throw new BufferUnderflowException(); 385 } 386 char x = (char) Memory.peekShort(ix(position), !nativeByteOrder); 387 position = newPosition; 388 return x; 389 } 390 391 @Override getChar(int i)392 public final char getChar(int i) { 393 if (!memoryRef.isAccessible) { 394 throw new IllegalStateException("buffer is inaccessible"); 395 } 396 checkIndex(i, Character.BYTES); 397 return (char) Memory.peekShort(ix(i), !nativeByteOrder); 398 } 399 400 @Override getCharUnchecked(int i)401 char getCharUnchecked(int i) { 402 if (!memoryRef.isAccessible) { 403 throw new IllegalStateException("buffer is inaccessible"); 404 } 405 return (char) Memory.peekShort(ix(i), !nativeByteOrder); 406 } 407 408 @Override getUnchecked(int pos, char[] dst, int dstOffset, int length)409 void getUnchecked(int pos, char[] dst, int dstOffset, int length) { 410 if (!memoryRef.isAccessible) { 411 throw new IllegalStateException("buffer is inaccessible"); 412 } 413 Memory.peekCharArray(ix(pos), 414 dst, dstOffset, length, !nativeByteOrder); 415 } 416 putChar(long a, char x)417 private ByteBuffer putChar(long a, char x) { 418 Memory.pokeShort(a, (short) x, !nativeByteOrder); 419 return this; 420 } 421 422 @Override putChar(char x)423 public final ByteBuffer putChar(char x) { 424 if (!memoryRef.isAccessible) { 425 throw new IllegalStateException("buffer is inaccessible"); 426 } 427 if (isReadOnly) { 428 throw new ReadOnlyBufferException(); 429 } 430 putChar(ix(nextPutIndex(Character.BYTES)), x); 431 return this; 432 } 433 434 @Override putChar(int i, char x)435 public final ByteBuffer putChar(int i, char x) { 436 if (!memoryRef.isAccessible) { 437 throw new IllegalStateException("buffer is inaccessible"); 438 } 439 if (isReadOnly) { 440 throw new ReadOnlyBufferException(); 441 } 442 putChar(ix(checkIndex(i, Character.BYTES)), x); 443 return this; 444 } 445 446 @Override putCharUnchecked(int i, char x)447 void putCharUnchecked(int i, char x) { 448 if (!memoryRef.isAccessible) { 449 throw new IllegalStateException("buffer is inaccessible"); 450 } 451 putChar(ix(i), x); 452 } 453 454 @Override putUnchecked(int pos, char[] src, int srcOffset, int length)455 void putUnchecked(int pos, char[] src, int srcOffset, int length) { 456 if (!memoryRef.isAccessible) { 457 throw new IllegalStateException("buffer is inaccessible"); 458 } 459 Memory.pokeCharArray(ix(pos), 460 src, srcOffset, length, !nativeByteOrder); 461 } 462 463 @Override asCharBuffer()464 public final CharBuffer asCharBuffer() { 465 if (memoryRef.isFreed) { 466 throw new IllegalStateException("buffer has been freed"); 467 } 468 int off = this.position(); 469 int lim = this.limit(); 470 assert (off <= lim); 471 int rem = (off <= lim ? lim - off : 0); 472 int size = rem >> 1; 473 return new ByteBufferAsCharBuffer(this, 474 -1, 475 0, 476 size, 477 size, 478 off, 479 order()); 480 } 481 getShort(long a)482 private short getShort(long a) { 483 return Memory.peekShort(a, !nativeByteOrder); 484 } 485 486 @Override getShort()487 public final short getShort() { 488 if (!memoryRef.isAccessible) { 489 throw new IllegalStateException("buffer is inaccessible"); 490 } 491 return getShort(ix(nextGetIndex(Short.BYTES))); 492 } 493 494 @Override getShort(int i)495 public final short getShort(int i) { 496 if (!memoryRef.isAccessible) { 497 throw new IllegalStateException("buffer is inaccessible"); 498 } 499 return getShort(ix(checkIndex(i, Short.BYTES))); 500 } 501 502 @Override getShortUnchecked(int i)503 short getShortUnchecked(int i) { 504 if (!memoryRef.isAccessible) { 505 throw new IllegalStateException("buffer is inaccessible"); 506 } 507 return getShort(ix(i)); 508 } 509 510 @Override getUnchecked(int pos, short[] dst, int dstOffset, int length)511 void getUnchecked(int pos, short[] dst, int dstOffset, int length) { 512 if (!memoryRef.isAccessible) { 513 throw new IllegalStateException("buffer is inaccessible"); 514 } 515 Memory.peekShortArray(ix(pos), 516 dst, dstOffset, length, !nativeByteOrder); 517 } 518 putShort(long a, short x)519 private ByteBuffer putShort(long a, short x) { 520 Memory.pokeShort(a, x, !nativeByteOrder); 521 return this; 522 } 523 524 @Override putShort(short x)525 public final ByteBuffer putShort(short x) { 526 if (!memoryRef.isAccessible) { 527 throw new IllegalStateException("buffer is inaccessible"); 528 } 529 if (isReadOnly) { 530 throw new ReadOnlyBufferException(); 531 } 532 putShort(ix(nextPutIndex(Short.BYTES)), x); 533 return this; 534 } 535 536 @Override putShort(int i, short x)537 public final ByteBuffer putShort(int i, short x) { 538 if (!memoryRef.isAccessible) { 539 throw new IllegalStateException("buffer is inaccessible"); 540 } 541 if (isReadOnly) { 542 throw new ReadOnlyBufferException(); 543 } 544 putShort(ix(checkIndex(i, Short.BYTES)), x); 545 return this; 546 } 547 548 @Override putShortUnchecked(int i, short x)549 void putShortUnchecked(int i, short x) { 550 if (!memoryRef.isAccessible) { 551 throw new IllegalStateException("buffer is inaccessible"); 552 } 553 putShort(ix(i), x); 554 } 555 556 @Override putUnchecked(int pos, short[] src, int srcOffset, int length)557 void putUnchecked(int pos, short[] src, int srcOffset, int length) { 558 if (!memoryRef.isAccessible) { 559 throw new IllegalStateException("buffer is inaccessible"); 560 } 561 Memory.pokeShortArray(ix(pos), 562 src, srcOffset, length, !nativeByteOrder); 563 } 564 565 @Override asShortBuffer()566 public final ShortBuffer asShortBuffer() { 567 if (memoryRef.isFreed) { 568 throw new IllegalStateException("buffer has been freed"); 569 } 570 int off = this.position(); 571 int lim = this.limit(); 572 assert (off <= lim); 573 int rem = (off <= lim ? lim - off : 0); 574 int size = rem >> 1; 575 return new ByteBufferAsShortBuffer(this, 576 -1, 577 0, 578 size, 579 size, 580 off, 581 order()); 582 } 583 getInt(long a)584 private int getInt(long a) { 585 return Memory.peekInt(a, !nativeByteOrder); 586 } 587 588 @Override getInt()589 public int getInt() { 590 if (!memoryRef.isAccessible) { 591 throw new IllegalStateException("buffer is inaccessible"); 592 } 593 return getInt(ix(nextGetIndex(Integer.BYTES))); 594 } 595 596 @Override getInt(int i)597 public int getInt(int i) { 598 if (!memoryRef.isAccessible) { 599 throw new IllegalStateException("buffer is inaccessible"); 600 } 601 return getInt(ix(checkIndex(i, (Integer.BYTES)))); 602 } 603 604 @Override getIntUnchecked(int i)605 final int getIntUnchecked(int i) { 606 if (!memoryRef.isAccessible) { 607 throw new IllegalStateException("buffer is inaccessible"); 608 } 609 return getInt(ix(i)); 610 } 611 612 @Override getUnchecked(int pos, int[] dst, int dstOffset, int length)613 final void getUnchecked(int pos, int[] dst, int dstOffset, int length) { 614 if (!memoryRef.isAccessible) { 615 throw new IllegalStateException("buffer is inaccessible"); 616 } 617 Memory.peekIntArray(ix(pos), 618 dst, dstOffset, length, !nativeByteOrder); 619 } 620 putInt(long a, int x)621 private ByteBuffer putInt(long a, int x) { 622 Memory.pokeInt(a, x, !nativeByteOrder); 623 return this; 624 } 625 626 @Override putInt(int x)627 public final ByteBuffer putInt(int x) { 628 if (!memoryRef.isAccessible) { 629 throw new IllegalStateException("buffer is inaccessible"); 630 } 631 if (isReadOnly) { 632 throw new ReadOnlyBufferException(); 633 } 634 putInt(ix(nextPutIndex(Integer.BYTES)), x); 635 return this; 636 } 637 638 @Override putInt(int i, int x)639 public final ByteBuffer putInt(int i, int x) { 640 if (!memoryRef.isAccessible) { 641 throw new IllegalStateException("buffer is inaccessible"); 642 } 643 if (isReadOnly) { 644 throw new ReadOnlyBufferException(); 645 } 646 putInt(ix(checkIndex(i, Integer.BYTES)), x); 647 return this; 648 } 649 650 @Override putIntUnchecked(int i, int x)651 final void putIntUnchecked(int i, int x) { 652 if (!memoryRef.isAccessible) { 653 throw new IllegalStateException("buffer is inaccessible"); 654 } 655 putInt(ix(i), x); 656 } 657 658 @Override putUnchecked(int pos, int[] src, int srcOffset, int length)659 final void putUnchecked(int pos, int[] src, int srcOffset, int length) { 660 if (!memoryRef.isAccessible) { 661 throw new IllegalStateException("buffer is inaccessible"); 662 } 663 Memory.pokeIntArray(ix(pos), 664 src, srcOffset, length, !nativeByteOrder); 665 } 666 667 @Override asIntBuffer()668 public final IntBuffer asIntBuffer() { 669 if (memoryRef.isFreed) { 670 throw new IllegalStateException("buffer has been freed"); 671 } 672 int off = this.position(); 673 int lim = this.limit(); 674 assert (off <= lim); 675 int rem = (off <= lim ? lim - off : 0); 676 int size = rem >> 2; 677 return new ByteBufferAsIntBuffer(this, 678 -1, 679 0, 680 size, 681 size, 682 off, 683 order()); 684 } 685 getLong(long a)686 private long getLong(long a) { 687 return Memory.peekLong(a, !nativeByteOrder); 688 } 689 690 @Override getLong()691 public final long getLong() { 692 if (!memoryRef.isAccessible) { 693 throw new IllegalStateException("buffer is inaccessible"); 694 } 695 return getLong(ix(nextGetIndex(Long.BYTES))); 696 } 697 698 @Override getLong(int i)699 public final long getLong(int i) { 700 if (!memoryRef.isAccessible) { 701 throw new IllegalStateException("buffer is inaccessible"); 702 } 703 return getLong(ix(checkIndex(i, Long.BYTES))); 704 } 705 706 @Override getLongUnchecked(int i)707 final long getLongUnchecked(int i) { 708 if (!memoryRef.isAccessible) { 709 throw new IllegalStateException("buffer is inaccessible"); 710 } 711 return getLong(ix(i)); 712 } 713 714 @Override getUnchecked(int pos, long[] dst, int dstOffset, int length)715 final void getUnchecked(int pos, long[] dst, int dstOffset, int length) { 716 if (!memoryRef.isAccessible) { 717 throw new IllegalStateException("buffer is inaccessible"); 718 } 719 Memory.peekLongArray(ix(pos), 720 dst, dstOffset, length, !nativeByteOrder); 721 } 722 putLong(long a, long x)723 private ByteBuffer putLong(long a, long x) { 724 Memory.pokeLong(a, x, !nativeByteOrder); 725 return this; 726 } 727 728 @Override putLong(long x)729 public final ByteBuffer putLong(long x) { 730 if (!memoryRef.isAccessible) { 731 throw new IllegalStateException("buffer is inaccessible"); 732 } 733 if (isReadOnly) { 734 throw new ReadOnlyBufferException(); 735 } 736 putLong(ix(nextPutIndex(Long.BYTES)), x); 737 return this; 738 } 739 740 @Override putLong(int i, long x)741 public final ByteBuffer putLong(int i, long x) { 742 if (!memoryRef.isAccessible) { 743 throw new IllegalStateException("buffer is inaccessible"); 744 } 745 if (isReadOnly) { 746 throw new ReadOnlyBufferException(); 747 } 748 putLong(ix(checkIndex(i, Long.BYTES)), x); 749 return this; 750 } 751 752 @Override putLongUnchecked(int i, long x)753 final void putLongUnchecked(int i, long x) { 754 if (!memoryRef.isAccessible) { 755 throw new IllegalStateException("buffer is inaccessible"); 756 } 757 putLong(ix(i), x); 758 } 759 760 @Override putUnchecked(int pos, long[] src, int srcOffset, int length)761 final void putUnchecked(int pos, long[] src, int srcOffset, int length) { 762 if (!memoryRef.isAccessible) { 763 throw new IllegalStateException("buffer is inaccessible"); 764 } 765 Memory.pokeLongArray(ix(pos), 766 src, srcOffset, length, !nativeByteOrder); 767 } 768 769 @Override asLongBuffer()770 public final LongBuffer asLongBuffer() { 771 if (memoryRef.isFreed) { 772 throw new IllegalStateException("buffer has been freed"); 773 } 774 int off = this.position(); 775 int lim = this.limit(); 776 assert (off <= lim); 777 int rem = (off <= lim ? lim - off : 0); 778 int size = rem >> 3; 779 return new ByteBufferAsLongBuffer(this, 780 -1, 781 0, 782 size, 783 size, 784 off, 785 order()); 786 } 787 getFloat(long a)788 private float getFloat(long a) { 789 int x = Memory.peekInt(a, !nativeByteOrder); 790 return Float.intBitsToFloat(x); 791 } 792 793 @Override getFloat()794 public final float getFloat() { 795 if (!memoryRef.isAccessible) { 796 throw new IllegalStateException("buffer is inaccessible"); 797 } 798 return getFloat(ix(nextGetIndex(Float.BYTES))); 799 } 800 801 @Override getFloat(int i)802 public final float getFloat(int i) { 803 if (!memoryRef.isAccessible) { 804 throw new IllegalStateException("buffer is inaccessible"); 805 } 806 return getFloat(ix(checkIndex(i, Float.BYTES))); 807 } 808 809 @Override getFloatUnchecked(int i)810 final float getFloatUnchecked(int i) { 811 if (!memoryRef.isAccessible) { 812 throw new IllegalStateException("buffer is inaccessible"); 813 } 814 return getFloat(ix(i)); 815 } 816 817 @Override getUnchecked(int pos, float[] dst, int dstOffset, int length)818 final void getUnchecked(int pos, float[] dst, int dstOffset, int length) { 819 if (!memoryRef.isAccessible) { 820 throw new IllegalStateException("buffer is inaccessible"); 821 } 822 Memory.peekFloatArray(ix(pos), 823 dst, dstOffset, length, !nativeByteOrder); 824 } 825 putFloat(long a, float x)826 private ByteBuffer putFloat(long a, float x) { 827 int y = Float.floatToRawIntBits(x); 828 Memory.pokeInt(a, y, !nativeByteOrder); 829 return this; 830 } 831 832 @Override putFloat(float x)833 public final ByteBuffer putFloat(float x) { 834 if (!memoryRef.isAccessible) { 835 throw new IllegalStateException("buffer is inaccessible"); 836 } 837 if (isReadOnly) { 838 throw new ReadOnlyBufferException(); 839 } 840 putFloat(ix(nextPutIndex(Float.BYTES)), x); 841 return this; 842 } 843 844 @Override putFloat(int i, float x)845 public final ByteBuffer putFloat(int i, float x) { 846 if (!memoryRef.isAccessible) { 847 throw new IllegalStateException("buffer is inaccessible"); 848 } 849 if (isReadOnly) { 850 throw new ReadOnlyBufferException(); 851 } 852 putFloat(ix(checkIndex(i, Float.BYTES)), x); 853 return this; 854 } 855 856 @Override putFloatUnchecked(int i, float x)857 final void putFloatUnchecked(int i, float x) { 858 if (!memoryRef.isAccessible) { 859 throw new IllegalStateException("buffer is inaccessible"); 860 } 861 putFloat(ix(i), x); 862 } 863 864 @Override putUnchecked(int pos, float[] src, int srcOffset, int length)865 final void putUnchecked(int pos, float[] src, int srcOffset, int length) { 866 if (!memoryRef.isAccessible) { 867 throw new IllegalStateException("buffer is inaccessible"); 868 } 869 Memory.pokeFloatArray(ix(pos), 870 src, srcOffset, length, !nativeByteOrder); 871 } 872 873 @Override asFloatBuffer()874 public final FloatBuffer asFloatBuffer() { 875 if (memoryRef.isFreed) { 876 throw new IllegalStateException("buffer has been freed"); 877 } 878 int off = this.position(); 879 int lim = this.limit(); 880 assert (off <= lim); 881 int rem = (off <= lim ? lim - off : 0); 882 int size = rem >> 2; 883 return new ByteBufferAsFloatBuffer(this, 884 -1, 885 0, 886 size, 887 size, 888 off, 889 order()); 890 } 891 getDouble(long a)892 private double getDouble(long a) { 893 long x = Memory.peekLong(a, !nativeByteOrder); 894 return Double.longBitsToDouble(x); 895 } 896 897 @Override getDouble()898 public final double getDouble() { 899 if (!memoryRef.isAccessible) { 900 throw new IllegalStateException("buffer is inaccessible"); 901 } 902 return getDouble(ix(nextGetIndex(Double.BYTES))); 903 } 904 905 @Override getDouble(int i)906 public final double getDouble(int i) { 907 if (!memoryRef.isAccessible) { 908 throw new IllegalStateException("buffer is inaccessible"); 909 } 910 return getDouble(ix(checkIndex(i, Double.BYTES))); 911 } 912 913 @Override getDoubleUnchecked(int i)914 final double getDoubleUnchecked(int i) { 915 if (!memoryRef.isAccessible) { 916 throw new IllegalStateException("buffer is inaccessible"); 917 } 918 return getDouble(ix(i)); 919 } 920 921 @Override getUnchecked(int pos, double[] dst, int dstOffset, int length)922 final void getUnchecked(int pos, double[] dst, int dstOffset, int length) { 923 if (!memoryRef.isAccessible) { 924 throw new IllegalStateException("buffer is inaccessible"); 925 } 926 Memory.peekDoubleArray(ix(pos), 927 dst, dstOffset, length, !nativeByteOrder); 928 } 929 putDouble(long a, double x)930 private ByteBuffer putDouble(long a, double x) { 931 long y = Double.doubleToRawLongBits(x); 932 Memory.pokeLong(a, y, !nativeByteOrder); 933 return this; 934 } 935 936 @Override putDouble(double x)937 public final ByteBuffer putDouble(double x) { 938 if (!memoryRef.isAccessible) { 939 throw new IllegalStateException("buffer is inaccessible"); 940 } 941 if (isReadOnly) { 942 throw new ReadOnlyBufferException(); 943 } 944 putDouble(ix(nextPutIndex(Double.BYTES)), x); 945 return this; 946 } 947 948 @Override putDouble(int i, double x)949 public final ByteBuffer putDouble(int i, double x) { 950 if (!memoryRef.isAccessible) { 951 throw new IllegalStateException("buffer is inaccessible"); 952 } 953 if (isReadOnly) { 954 throw new ReadOnlyBufferException(); 955 } 956 putDouble(ix(checkIndex(i, Double.BYTES)), x); 957 return this; 958 } 959 960 @Override putDoubleUnchecked(int i, double x)961 final void putDoubleUnchecked(int i, double x) { 962 if (!memoryRef.isAccessible) { 963 throw new IllegalStateException("buffer is inaccessible"); 964 } 965 putDouble(ix(i), x); 966 } 967 968 @Override putUnchecked(int pos, double[] src, int srcOffset, int length)969 final void putUnchecked(int pos, double[] src, int srcOffset, int length) { 970 if (!memoryRef.isAccessible) { 971 throw new IllegalStateException("buffer is inaccessible"); 972 } 973 Memory.pokeDoubleArray(ix(pos), 974 src, srcOffset, length, !nativeByteOrder); 975 } 976 977 @Override asDoubleBuffer()978 public final DoubleBuffer asDoubleBuffer() { 979 if (memoryRef.isFreed) { 980 throw new IllegalStateException("buffer has been freed"); 981 } 982 int off = this.position(); 983 int lim = this.limit(); 984 assert (off <= lim); 985 int rem = (off <= lim ? lim - off : 0); 986 987 int size = rem >> 3; 988 return new ByteBufferAsDoubleBuffer(this, 989 -1, 990 0, 991 size, 992 size, 993 off, 994 order()); 995 } 996 997 @Override isAccessible()998 public final boolean isAccessible() { 999 return memoryRef.isAccessible; 1000 } 1001 1002 @Override setAccessible(boolean value)1003 public final void setAccessible(boolean value) { 1004 memoryRef.isAccessible = value; 1005 } 1006 } 1007