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