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