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 slice(int pos, int lim)170 ByteBuffer slice(int pos, int lim) { 171 if (!memoryRef.isAccessible) { 172 throw new IllegalStateException("buffer is inaccessible"); 173 } 174 assert (pos >= 0); 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 duplicate()183 public final ByteBuffer duplicate() { 184 if (memoryRef.isFreed) { 185 throw new IllegalStateException("buffer has been freed"); 186 } 187 return new DirectByteBuffer(memoryRef, 188 this.markValue(), 189 this.position(), 190 this.limit(), 191 this.capacity(), 192 offset, 193 isReadOnly); 194 } 195 196 @Override asReadOnlyBuffer()197 public final ByteBuffer asReadOnlyBuffer() { 198 if (memoryRef.isFreed) { 199 throw new IllegalStateException("buffer has been freed"); 200 } 201 return new DirectByteBuffer(memoryRef, 202 this.markValue(), 203 this.position(), 204 this.limit(), 205 this.capacity(), 206 offset, 207 true); 208 } 209 210 @Override address()211 public final long address() { 212 return address; 213 } 214 ix(int i)215 private long ix(int i) { 216 return address + i; 217 } 218 get(long a)219 private byte get(long a) { 220 return Memory.peekByte(a); 221 } 222 223 @Override get()224 public final byte get() { 225 if (!memoryRef.isAccessible) { 226 throw new IllegalStateException("buffer is inaccessible"); 227 } 228 return get(ix(nextGetIndex())); 229 } 230 231 @Override get(int i)232 public final byte get(int i) { 233 if (!memoryRef.isAccessible) { 234 throw new IllegalStateException("buffer is inaccessible"); 235 } 236 return get(ix(checkIndex(i))); 237 } 238 239 // This method is not declared final because it is overridden in tests. 240 @Override get(byte[] dst, int dstOffset, int length)241 public ByteBuffer get(byte[] dst, int dstOffset, int length) { 242 if (!memoryRef.isAccessible) { 243 throw new IllegalStateException("buffer is inaccessible"); 244 } 245 checkBounds(dstOffset, length, dst.length); 246 int pos = position(); 247 int lim = limit(); 248 assert (pos <= lim); 249 int rem = (pos <= lim ? lim - pos : 0); 250 if (length > rem) 251 throw new BufferUnderflowException(); 252 Memory.peekByteArray(ix(pos), 253 dst, dstOffset, length); 254 position = pos + length; 255 return this; 256 } 257 put(long a, byte x)258 private ByteBuffer put(long a, byte x) { 259 Memory.pokeByte(a, x); 260 return this; 261 } 262 263 @Override put(ByteBuffer src)264 public ByteBuffer put(ByteBuffer src) { 265 if (!memoryRef.isAccessible) { 266 throw new IllegalStateException("buffer is inaccessible"); 267 } 268 return super.put(src); 269 } 270 271 @Override put(byte x)272 public final ByteBuffer put(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(nextPutIndex()), x); 280 return this; 281 } 282 283 @Override put(int i, byte x)284 public final ByteBuffer put(int i, byte x) { 285 if (!memoryRef.isAccessible) { 286 throw new IllegalStateException("buffer is inaccessible"); 287 } 288 if (isReadOnly) { 289 throw new ReadOnlyBufferException(); 290 } 291 put(ix(checkIndex(i)), x); 292 return this; 293 } 294 295 // This method is not declared final because it is overridden in tests. 296 @Override put(byte[] src, int srcOffset, int length)297 public ByteBuffer put(byte[] src, int srcOffset, int length) { 298 if (!memoryRef.isAccessible) { 299 throw new IllegalStateException("buffer is inaccessible"); 300 } 301 if (isReadOnly) { 302 throw new ReadOnlyBufferException(); 303 } 304 checkBounds(srcOffset, length, src.length); 305 int pos = position(); 306 int lim = limit(); 307 assert (pos <= lim); 308 int rem = (pos <= lim ? lim - pos : 0); 309 if (length > rem) 310 throw new BufferOverflowException(); 311 Memory.pokeByteArray(ix(pos), 312 src, srcOffset, length); 313 position = pos + length; 314 return this; 315 } 316 317 @Override compact()318 public final ByteBuffer compact() { 319 if (!memoryRef.isAccessible) { 320 throw new IllegalStateException("buffer is inaccessible"); 321 } 322 if (isReadOnly) { 323 throw new ReadOnlyBufferException(); 324 } 325 int pos = position(); 326 int lim = limit(); 327 assert (pos <= lim); 328 int rem = (pos <= lim ? lim - pos : 0); 329 System.arraycopy(hb, position + offset, hb, offset, remaining()); 330 position(rem); 331 limit(capacity()); 332 discardMark(); 333 return this; 334 } 335 336 @Override isDirect()337 public final boolean isDirect() { 338 return true; 339 } 340 341 @Override isReadOnly()342 public final boolean isReadOnly() { 343 return isReadOnly; 344 } 345 346 // Used by java.nio.Bits 347 @Override _get(int i)348 final byte _get(int i) { // package-private 349 return get(i); 350 } 351 352 // Used by java.nio.Bits 353 @Override _put(int i, byte b)354 final void _put(int i, byte b) { // package-private 355 put(i, b); 356 } 357 358 @Override getChar()359 public final char getChar() { 360 if (!memoryRef.isAccessible) { 361 throw new IllegalStateException("buffer is inaccessible"); 362 } 363 int newPosition = position + Character.BYTES; 364 if (newPosition > limit()) { 365 throw new BufferUnderflowException(); 366 } 367 char x = (char) Memory.peekShort(ix(position), !nativeByteOrder); 368 position = newPosition; 369 return x; 370 } 371 372 @Override getChar(int i)373 public final char getChar(int i) { 374 if (!memoryRef.isAccessible) { 375 throw new IllegalStateException("buffer is inaccessible"); 376 } 377 checkIndex(i, Character.BYTES); 378 return (char) Memory.peekShort(ix(i), !nativeByteOrder); 379 } 380 381 @Override getCharUnchecked(int i)382 char getCharUnchecked(int i) { 383 if (!memoryRef.isAccessible) { 384 throw new IllegalStateException("buffer is inaccessible"); 385 } 386 return (char) Memory.peekShort(ix(i), !nativeByteOrder); 387 } 388 389 @Override getUnchecked(int pos, char[] dst, int dstOffset, int length)390 void getUnchecked(int pos, char[] dst, int dstOffset, int length) { 391 if (!memoryRef.isAccessible) { 392 throw new IllegalStateException("buffer is inaccessible"); 393 } 394 Memory.peekCharArray(ix(pos), 395 dst, dstOffset, length, !nativeByteOrder); 396 } 397 putChar(long a, char x)398 private ByteBuffer putChar(long a, char x) { 399 Memory.pokeShort(a, (short) x, !nativeByteOrder); 400 return this; 401 } 402 403 @Override putChar(char x)404 public final ByteBuffer putChar(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(nextPutIndex(Character.BYTES)), x); 412 return this; 413 } 414 415 @Override putChar(int i, char x)416 public final ByteBuffer putChar(int i, char x) { 417 if (!memoryRef.isAccessible) { 418 throw new IllegalStateException("buffer is inaccessible"); 419 } 420 if (isReadOnly) { 421 throw new ReadOnlyBufferException(); 422 } 423 putChar(ix(checkIndex(i, Character.BYTES)), x); 424 return this; 425 } 426 427 @Override putCharUnchecked(int i, char x)428 void putCharUnchecked(int i, char x) { 429 if (!memoryRef.isAccessible) { 430 throw new IllegalStateException("buffer is inaccessible"); 431 } 432 putChar(ix(i), x); 433 } 434 435 @Override putUnchecked(int pos, char[] src, int srcOffset, int length)436 void putUnchecked(int pos, char[] src, int srcOffset, int length) { 437 if (!memoryRef.isAccessible) { 438 throw new IllegalStateException("buffer is inaccessible"); 439 } 440 Memory.pokeCharArray(ix(pos), 441 src, srcOffset, length, !nativeByteOrder); 442 } 443 444 @Override asCharBuffer()445 public final CharBuffer asCharBuffer() { 446 if (memoryRef.isFreed) { 447 throw new IllegalStateException("buffer has been freed"); 448 } 449 int off = this.position(); 450 int lim = this.limit(); 451 assert (off <= lim); 452 int rem = (off <= lim ? lim - off : 0); 453 int size = rem >> 1; 454 return new ByteBufferAsCharBuffer(this, 455 -1, 456 0, 457 size, 458 size, 459 off, 460 order()); 461 } 462 getShort(long a)463 private short getShort(long a) { 464 return Memory.peekShort(a, !nativeByteOrder); 465 } 466 467 @Override getShort()468 public final short getShort() { 469 if (!memoryRef.isAccessible) { 470 throw new IllegalStateException("buffer is inaccessible"); 471 } 472 return getShort(ix(nextGetIndex(Short.BYTES))); 473 } 474 475 @Override getShort(int i)476 public final short getShort(int i) { 477 if (!memoryRef.isAccessible) { 478 throw new IllegalStateException("buffer is inaccessible"); 479 } 480 return getShort(ix(checkIndex(i, Short.BYTES))); 481 } 482 483 @Override getShortUnchecked(int i)484 short getShortUnchecked(int i) { 485 if (!memoryRef.isAccessible) { 486 throw new IllegalStateException("buffer is inaccessible"); 487 } 488 return getShort(ix(i)); 489 } 490 491 @Override getUnchecked(int pos, short[] dst, int dstOffset, int length)492 void getUnchecked(int pos, short[] dst, int dstOffset, int length) { 493 if (!memoryRef.isAccessible) { 494 throw new IllegalStateException("buffer is inaccessible"); 495 } 496 Memory.peekShortArray(ix(pos), 497 dst, dstOffset, length, !nativeByteOrder); 498 } 499 putShort(long a, short x)500 private ByteBuffer putShort(long a, short x) { 501 Memory.pokeShort(a, x, !nativeByteOrder); 502 return this; 503 } 504 505 @Override putShort(short x)506 public final ByteBuffer putShort(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(nextPutIndex(Short.BYTES)), x); 514 return this; 515 } 516 517 @Override putShort(int i, short x)518 public final ByteBuffer putShort(int i, short x) { 519 if (!memoryRef.isAccessible) { 520 throw new IllegalStateException("buffer is inaccessible"); 521 } 522 if (isReadOnly) { 523 throw new ReadOnlyBufferException(); 524 } 525 putShort(ix(checkIndex(i, Short.BYTES)), x); 526 return this; 527 } 528 529 @Override putShortUnchecked(int i, short x)530 void putShortUnchecked(int i, short x) { 531 if (!memoryRef.isAccessible) { 532 throw new IllegalStateException("buffer is inaccessible"); 533 } 534 putShort(ix(i), x); 535 } 536 537 @Override putUnchecked(int pos, short[] src, int srcOffset, int length)538 void putUnchecked(int pos, short[] src, int srcOffset, int length) { 539 if (!memoryRef.isAccessible) { 540 throw new IllegalStateException("buffer is inaccessible"); 541 } 542 Memory.pokeShortArray(ix(pos), 543 src, srcOffset, length, !nativeByteOrder); 544 } 545 546 @Override asShortBuffer()547 public final ShortBuffer asShortBuffer() { 548 if (memoryRef.isFreed) { 549 throw new IllegalStateException("buffer has been freed"); 550 } 551 int off = this.position(); 552 int lim = this.limit(); 553 assert (off <= lim); 554 int rem = (off <= lim ? lim - off : 0); 555 int size = rem >> 1; 556 return new ByteBufferAsShortBuffer(this, 557 -1, 558 0, 559 size, 560 size, 561 off, 562 order()); 563 } 564 getInt(long a)565 private int getInt(long a) { 566 return Memory.peekInt(a, !nativeByteOrder); 567 } 568 569 @Override getInt()570 public int getInt() { 571 if (!memoryRef.isAccessible) { 572 throw new IllegalStateException("buffer is inaccessible"); 573 } 574 return getInt(ix(nextGetIndex(Integer.BYTES))); 575 } 576 577 @Override getInt(int i)578 public int getInt(int i) { 579 if (!memoryRef.isAccessible) { 580 throw new IllegalStateException("buffer is inaccessible"); 581 } 582 return getInt(ix(checkIndex(i, (Integer.BYTES)))); 583 } 584 585 @Override getIntUnchecked(int i)586 final int getIntUnchecked(int i) { 587 if (!memoryRef.isAccessible) { 588 throw new IllegalStateException("buffer is inaccessible"); 589 } 590 return getInt(ix(i)); 591 } 592 593 @Override getUnchecked(int pos, int[] dst, int dstOffset, int length)594 final void getUnchecked(int pos, int[] dst, int dstOffset, int length) { 595 if (!memoryRef.isAccessible) { 596 throw new IllegalStateException("buffer is inaccessible"); 597 } 598 Memory.peekIntArray(ix(pos), 599 dst, dstOffset, length, !nativeByteOrder); 600 } 601 putInt(long a, int x)602 private ByteBuffer putInt(long a, int x) { 603 Memory.pokeInt(a, x, !nativeByteOrder); 604 return this; 605 } 606 607 @Override putInt(int x)608 public final ByteBuffer putInt(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(nextPutIndex(Integer.BYTES)), x); 616 return this; 617 } 618 619 @Override putInt(int i, int x)620 public final ByteBuffer putInt(int i, int x) { 621 if (!memoryRef.isAccessible) { 622 throw new IllegalStateException("buffer is inaccessible"); 623 } 624 if (isReadOnly) { 625 throw new ReadOnlyBufferException(); 626 } 627 putInt(ix(checkIndex(i, Integer.BYTES)), x); 628 return this; 629 } 630 631 @Override putIntUnchecked(int i, int x)632 final void putIntUnchecked(int i, int x) { 633 if (!memoryRef.isAccessible) { 634 throw new IllegalStateException("buffer is inaccessible"); 635 } 636 putInt(ix(i), x); 637 } 638 639 @Override putUnchecked(int pos, int[] src, int srcOffset, int length)640 final void putUnchecked(int pos, int[] src, int srcOffset, int length) { 641 if (!memoryRef.isAccessible) { 642 throw new IllegalStateException("buffer is inaccessible"); 643 } 644 Memory.pokeIntArray(ix(pos), 645 src, srcOffset, length, !nativeByteOrder); 646 } 647 648 @Override asIntBuffer()649 public final IntBuffer asIntBuffer() { 650 if (memoryRef.isFreed) { 651 throw new IllegalStateException("buffer has been freed"); 652 } 653 int off = this.position(); 654 int lim = this.limit(); 655 assert (off <= lim); 656 int rem = (off <= lim ? lim - off : 0); 657 int size = rem >> 2; 658 return new ByteBufferAsIntBuffer(this, 659 -1, 660 0, 661 size, 662 size, 663 off, 664 order()); 665 } 666 getLong(long a)667 private long getLong(long a) { 668 return Memory.peekLong(a, !nativeByteOrder); 669 } 670 671 @Override getLong()672 public final long getLong() { 673 if (!memoryRef.isAccessible) { 674 throw new IllegalStateException("buffer is inaccessible"); 675 } 676 return getLong(ix(nextGetIndex(Long.BYTES))); 677 } 678 679 @Override getLong(int i)680 public final long getLong(int i) { 681 if (!memoryRef.isAccessible) { 682 throw new IllegalStateException("buffer is inaccessible"); 683 } 684 return getLong(ix(checkIndex(i, Long.BYTES))); 685 } 686 687 @Override getLongUnchecked(int i)688 final long getLongUnchecked(int i) { 689 if (!memoryRef.isAccessible) { 690 throw new IllegalStateException("buffer is inaccessible"); 691 } 692 return getLong(ix(i)); 693 } 694 695 @Override getUnchecked(int pos, long[] dst, int dstOffset, int length)696 final void getUnchecked(int pos, long[] dst, int dstOffset, int length) { 697 if (!memoryRef.isAccessible) { 698 throw new IllegalStateException("buffer is inaccessible"); 699 } 700 Memory.peekLongArray(ix(pos), 701 dst, dstOffset, length, !nativeByteOrder); 702 } 703 putLong(long a, long x)704 private ByteBuffer putLong(long a, long x) { 705 Memory.pokeLong(a, x, !nativeByteOrder); 706 return this; 707 } 708 709 @Override putLong(long x)710 public final ByteBuffer putLong(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(nextPutIndex(Long.BYTES)), x); 718 return this; 719 } 720 721 @Override putLong(int i, long x)722 public final ByteBuffer putLong(int i, long x) { 723 if (!memoryRef.isAccessible) { 724 throw new IllegalStateException("buffer is inaccessible"); 725 } 726 if (isReadOnly) { 727 throw new ReadOnlyBufferException(); 728 } 729 putLong(ix(checkIndex(i, Long.BYTES)), x); 730 return this; 731 } 732 733 @Override putLongUnchecked(int i, long x)734 final void putLongUnchecked(int i, long x) { 735 if (!memoryRef.isAccessible) { 736 throw new IllegalStateException("buffer is inaccessible"); 737 } 738 putLong(ix(i), x); 739 } 740 741 @Override putUnchecked(int pos, long[] src, int srcOffset, int length)742 final void putUnchecked(int pos, long[] src, int srcOffset, int length) { 743 if (!memoryRef.isAccessible) { 744 throw new IllegalStateException("buffer is inaccessible"); 745 } 746 Memory.pokeLongArray(ix(pos), 747 src, srcOffset, length, !nativeByteOrder); 748 } 749 750 @Override asLongBuffer()751 public final LongBuffer asLongBuffer() { 752 if (memoryRef.isFreed) { 753 throw new IllegalStateException("buffer has been freed"); 754 } 755 int off = this.position(); 756 int lim = this.limit(); 757 assert (off <= lim); 758 int rem = (off <= lim ? lim - off : 0); 759 int size = rem >> 3; 760 return new ByteBufferAsLongBuffer(this, 761 -1, 762 0, 763 size, 764 size, 765 off, 766 order()); 767 } 768 getFloat(long a)769 private float getFloat(long a) { 770 int x = Memory.peekInt(a, !nativeByteOrder); 771 return Float.intBitsToFloat(x); 772 } 773 774 @Override getFloat()775 public final float getFloat() { 776 if (!memoryRef.isAccessible) { 777 throw new IllegalStateException("buffer is inaccessible"); 778 } 779 return getFloat(ix(nextGetIndex(Float.BYTES))); 780 } 781 782 @Override getFloat(int i)783 public final float getFloat(int i) { 784 if (!memoryRef.isAccessible) { 785 throw new IllegalStateException("buffer is inaccessible"); 786 } 787 return getFloat(ix(checkIndex(i, Float.BYTES))); 788 } 789 790 @Override getFloatUnchecked(int i)791 final float getFloatUnchecked(int i) { 792 if (!memoryRef.isAccessible) { 793 throw new IllegalStateException("buffer is inaccessible"); 794 } 795 return getFloat(ix(i)); 796 } 797 798 @Override getUnchecked(int pos, float[] dst, int dstOffset, int length)799 final void getUnchecked(int pos, float[] dst, int dstOffset, int length) { 800 if (!memoryRef.isAccessible) { 801 throw new IllegalStateException("buffer is inaccessible"); 802 } 803 Memory.peekFloatArray(ix(pos), 804 dst, dstOffset, length, !nativeByteOrder); 805 } 806 putFloat(long a, float x)807 private ByteBuffer putFloat(long a, float x) { 808 int y = Float.floatToRawIntBits(x); 809 Memory.pokeInt(a, y, !nativeByteOrder); 810 return this; 811 } 812 813 @Override putFloat(float x)814 public final ByteBuffer putFloat(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(nextPutIndex(Float.BYTES)), x); 822 return this; 823 } 824 825 @Override putFloat(int i, float x)826 public final ByteBuffer putFloat(int i, float x) { 827 if (!memoryRef.isAccessible) { 828 throw new IllegalStateException("buffer is inaccessible"); 829 } 830 if (isReadOnly) { 831 throw new ReadOnlyBufferException(); 832 } 833 putFloat(ix(checkIndex(i, Float.BYTES)), x); 834 return this; 835 } 836 837 @Override putFloatUnchecked(int i, float x)838 final void putFloatUnchecked(int i, float x) { 839 if (!memoryRef.isAccessible) { 840 throw new IllegalStateException("buffer is inaccessible"); 841 } 842 putFloat(ix(i), x); 843 } 844 845 @Override putUnchecked(int pos, float[] src, int srcOffset, int length)846 final void putUnchecked(int pos, float[] src, int srcOffset, int length) { 847 if (!memoryRef.isAccessible) { 848 throw new IllegalStateException("buffer is inaccessible"); 849 } 850 Memory.pokeFloatArray(ix(pos), 851 src, srcOffset, length, !nativeByteOrder); 852 } 853 854 @Override asFloatBuffer()855 public final FloatBuffer asFloatBuffer() { 856 if (memoryRef.isFreed) { 857 throw new IllegalStateException("buffer has been freed"); 858 } 859 int off = this.position(); 860 int lim = this.limit(); 861 assert (off <= lim); 862 int rem = (off <= lim ? lim - off : 0); 863 int size = rem >> 2; 864 return new ByteBufferAsFloatBuffer(this, 865 -1, 866 0, 867 size, 868 size, 869 off, 870 order()); 871 } 872 getDouble(long a)873 private double getDouble(long a) { 874 long x = Memory.peekLong(a, !nativeByteOrder); 875 return Double.longBitsToDouble(x); 876 } 877 878 @Override getDouble()879 public final double getDouble() { 880 if (!memoryRef.isAccessible) { 881 throw new IllegalStateException("buffer is inaccessible"); 882 } 883 return getDouble(ix(nextGetIndex(Double.BYTES))); 884 } 885 886 @Override getDouble(int i)887 public final double getDouble(int i) { 888 if (!memoryRef.isAccessible) { 889 throw new IllegalStateException("buffer is inaccessible"); 890 } 891 return getDouble(ix(checkIndex(i, Double.BYTES))); 892 } 893 894 @Override getDoubleUnchecked(int i)895 final double getDoubleUnchecked(int i) { 896 if (!memoryRef.isAccessible) { 897 throw new IllegalStateException("buffer is inaccessible"); 898 } 899 return getDouble(ix(i)); 900 } 901 902 @Override getUnchecked(int pos, double[] dst, int dstOffset, int length)903 final void getUnchecked(int pos, double[] dst, int dstOffset, int length) { 904 if (!memoryRef.isAccessible) { 905 throw new IllegalStateException("buffer is inaccessible"); 906 } 907 Memory.peekDoubleArray(ix(pos), 908 dst, dstOffset, length, !nativeByteOrder); 909 } 910 putDouble(long a, double x)911 private ByteBuffer putDouble(long a, double x) { 912 long y = Double.doubleToRawLongBits(x); 913 Memory.pokeLong(a, y, !nativeByteOrder); 914 return this; 915 } 916 917 @Override putDouble(double x)918 public final ByteBuffer putDouble(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(nextPutIndex(Double.BYTES)), x); 926 return this; 927 } 928 929 @Override putDouble(int i, double x)930 public final ByteBuffer putDouble(int i, double x) { 931 if (!memoryRef.isAccessible) { 932 throw new IllegalStateException("buffer is inaccessible"); 933 } 934 if (isReadOnly) { 935 throw new ReadOnlyBufferException(); 936 } 937 putDouble(ix(checkIndex(i, Double.BYTES)), x); 938 return this; 939 } 940 941 @Override putDoubleUnchecked(int i, double x)942 final void putDoubleUnchecked(int i, double x) { 943 if (!memoryRef.isAccessible) { 944 throw new IllegalStateException("buffer is inaccessible"); 945 } 946 putDouble(ix(i), x); 947 } 948 949 @Override putUnchecked(int pos, double[] src, int srcOffset, int length)950 final void putUnchecked(int pos, double[] src, int srcOffset, int length) { 951 if (!memoryRef.isAccessible) { 952 throw new IllegalStateException("buffer is inaccessible"); 953 } 954 Memory.pokeDoubleArray(ix(pos), 955 src, srcOffset, length, !nativeByteOrder); 956 } 957 958 @Override asDoubleBuffer()959 public final DoubleBuffer asDoubleBuffer() { 960 if (memoryRef.isFreed) { 961 throw new IllegalStateException("buffer has been freed"); 962 } 963 int off = this.position(); 964 int lim = this.limit(); 965 assert (off <= lim); 966 int rem = (off <= lim ? lim - off : 0); 967 968 int size = rem >> 3; 969 return new ByteBufferAsDoubleBuffer(this, 970 -1, 971 0, 972 size, 973 size, 974 off, 975 order()); 976 } 977 978 @Override isAccessible()979 public final boolean isAccessible() { 980 return memoryRef.isAccessible; 981 } 982 983 @Override setAccessible(boolean value)984 public final void setAccessible(boolean value) { 985 memoryRef.isAccessible = value; 986 } 987 } 988