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