1/* 2 * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26#warn This file is preprocessed before being compiled 27 28package java.nio; 29 30import java.util.Objects; 31import jdk.internal.access.foreign.MemorySegmentProxy; 32 33/** 34#if[rw] 35 * A read/write Heap$Type$Buffer. 36#else[rw] 37 * A read-only Heap$Type$Buffer. This class extends the corresponding 38 * read/write class, overriding the mutation methods to throw a {@link 39 * ReadOnlyBufferException} and overriding the view-buffer methods to return an 40 * instance of this class rather than of the superclass. 41#end[rw] 42 */ 43 44class Heap$Type$Buffer$RW$ 45 extends {#if[ro]?Heap}$Type$Buffer 46{ 47 // Cached array base offset 48 private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class); 49 50 // Cached array index scale 51 private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class); 52 53 // For speed these fields are actually declared in X-Buffer; 54 // these declarations are here as documentation 55 /* 56#if[rw] 57 protected final $type$[] hb; 58 protected final int offset; 59#end[rw] 60 */ 61 62 Heap$Type$Buffer$RW$(int cap, int lim, MemorySegmentProxy segment) { // package-private 63#if[rw] 64 super(-1, 0, lim, cap, new $type$[cap], 0, segment); 65 /* 66 hb = new $type$[cap]; 67 offset = 0; 68 */ 69 this.address = ARRAY_BASE_OFFSET; 70#else[rw] 71 super(cap, lim, segment); 72 this.isReadOnly = true; 73#end[rw] 74 } 75 76 Heap$Type$Buffer$RW$($type$[] buf, int off, int len, MemorySegmentProxy segment) { // package-private 77#if[rw] 78 super(-1, off, off + len, buf.length, buf, 0, segment); 79 /* 80 hb = buf; 81 offset = 0; 82 */ 83 this.address = ARRAY_BASE_OFFSET; 84#else[rw] 85 super(buf, off, len, segment); 86 this.isReadOnly = true; 87#end[rw] 88 } 89 90 protected Heap$Type$Buffer$RW$($type$[] buf, 91 int mark, int pos, int lim, int cap, 92 int off, MemorySegmentProxy segment) 93 { 94#if[rw] 95 super(mark, pos, lim, cap, buf, off, segment); 96 /* 97 hb = buf; 98 offset = off; 99 */ 100 this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE; 101#else[rw] 102 super(buf, mark, pos, lim, cap, off, segment); 103 this.isReadOnly = true; 104#end[rw] 105 } 106 107 public $Type$Buffer slice() { 108 int pos = this.position(); 109 int lim = this.limit(); 110 int rem = (pos <= lim ? lim - pos : 0); 111 return new Heap$Type$Buffer$RW$(hb, 112 -1, 113 0, 114 rem, 115 rem, 116 pos + offset, segment); 117 } 118 119 @Override 120 public $Type$Buffer slice(int index, int length) { 121 Objects.checkFromIndexSize(index, length, limit()); 122 return new Heap$Type$Buffer$RW$(hb, 123 -1, 124 0, 125 length, 126 length, 127 index + offset, segment); 128 } 129 130 public $Type$Buffer duplicate() { 131 return new Heap$Type$Buffer$RW$(hb, 132 this.markValue(), 133 this.position(), 134 this.limit(), 135 this.capacity(), 136 offset, segment); 137 } 138 139 public $Type$Buffer asReadOnlyBuffer() { 140#if[rw] 141 return new Heap$Type$BufferR(hb, 142 this.markValue(), 143 this.position(), 144 this.limit(), 145 this.capacity(), 146 offset, segment); 147#else[rw] 148 return duplicate(); 149#end[rw] 150 } 151 152#if[rw] 153 154 protected int ix(int i) { 155 return i + offset; 156 } 157 158#if[byte] 159 private long byteOffset(long i) { 160 return address + i; 161 } 162#end[byte] 163 164 public $type$ get() { 165 return hb[ix(nextGetIndex())]; 166 } 167 168 public $type$ get(int i) { 169 return hb[ix(checkIndex(i))]; 170 } 171 172#if[streamableType] 173 $type$ getUnchecked(int i) { 174 return hb[ix(i)]; 175 } 176#end[streamableType] 177 178 public $Type$Buffer get($type$[] dst, int offset, int length) { 179 checkScope(); 180 Objects.checkFromIndexSize(offset, length, dst.length); 181 int pos = position(); 182 if (length > limit() - pos) 183 throw new BufferUnderflowException(); 184 System.arraycopy(hb, ix(pos), dst, offset, length); 185 position(pos + length); 186 return this; 187 } 188 189 public $Type$Buffer get(int index, $type$[] dst, int offset, int length) { 190 checkScope(); 191 Objects.checkFromIndexSize(index, length, limit()); 192 Objects.checkFromIndexSize(offset, length, dst.length); 193 System.arraycopy(hb, ix(index), dst, offset, length); 194 return this; 195 } 196 197 public boolean isDirect() { 198 return false; 199 } 200 201#end[rw] 202 203 public boolean isReadOnly() { 204 return {#if[rw]?false:true}; 205 } 206 207 public $Type$Buffer put($type$ x) { 208#if[rw] 209 hb[ix(nextPutIndex())] = x; 210 return this; 211#else[rw] 212 throw new ReadOnlyBufferException(); 213#end[rw] 214 } 215 216 public $Type$Buffer put(int i, $type$ x) { 217#if[rw] 218 hb[ix(checkIndex(i))] = x; 219 return this; 220#else[rw] 221 throw new ReadOnlyBufferException(); 222#end[rw] 223 } 224 225 public $Type$Buffer put($type$[] src, int offset, int length) { 226#if[rw] 227 checkScope(); 228 Objects.checkFromIndexSize(offset, length, src.length); 229 int pos = position(); 230 if (length > limit() - pos) 231 throw new BufferOverflowException(); 232 System.arraycopy(src, offset, hb, ix(pos), length); 233 position(pos + length); 234 return this; 235#else[rw] 236 throw new ReadOnlyBufferException(); 237#end[rw] 238 } 239 240 public $Type$Buffer put($Type$Buffer src) { 241#if[rw] 242 checkScope(); 243 super.put(src); 244 return this; 245#else[rw] 246 throw new ReadOnlyBufferException(); 247#end[rw] 248 } 249 250 public $Type$Buffer put(int index, $Type$Buffer src, int offset, int length) { 251#if[rw] 252 checkScope(); 253 super.put(index, src, offset, length); 254 return this; 255#else[rw] 256 throw new ReadOnlyBufferException(); 257#end[rw] 258 } 259 260 public $Type$Buffer put(int index, $type$[] src, int offset, int length) { 261#if[rw] 262 checkScope(); 263 Objects.checkFromIndexSize(index, length, limit()); 264 Objects.checkFromIndexSize(offset, length, src.length); 265 System.arraycopy(src, offset, hb, ix(index), length); 266 return this; 267#else[rw] 268 throw new ReadOnlyBufferException(); 269#end[rw] 270 } 271 272#if[char] 273 274 public $Type$Buffer put(String src, int start, int end) { 275#if[rw] 276 checkScope(); 277 int length = end - start; 278 Objects.checkFromIndexSize(start, length, src.length()); 279 int pos = position(); 280 int lim = limit(); 281 int rem = (pos <= lim) ? lim - pos : 0; 282 if (length > rem) 283 throw new BufferOverflowException(); 284 src.getChars(start, end, hb, ix(pos)); 285 position(pos + length); 286 return this; 287#else[rw] 288 throw new ReadOnlyBufferException(); 289#end[rw] 290 } 291 292#end[char] 293 294 public $Type$Buffer compact() { 295#if[rw] 296 int pos = position(); 297 int lim = limit(); 298 assert (pos <= lim); 299 int rem = (pos <= lim ? lim - pos : 0); 300 System.arraycopy(hb, ix(pos), hb, ix(0), rem); 301 position(rem); 302 limit(capacity()); 303 discardMark(); 304 return this; 305#else[rw] 306 throw new ReadOnlyBufferException(); 307#end[rw] 308 } 309 310 311 312#if[byte] 313 314 byte _get(int i) { // package-private 315 return hb[i]; 316 } 317 318 void _put(int i, byte b) { // package-private 319#if[rw] 320 hb[i] = b; 321#else[rw] 322 throw new ReadOnlyBufferException(); 323#end[rw] 324 } 325 326 // char 327 328#if[rw] 329 330 public char getChar() { 331 return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian); 332 } 333 334 public char getChar(int i) { 335 return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian); 336 } 337 338#end[rw] 339 340 public $Type$Buffer putChar(char x) { 341#if[rw] 342 SCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian); 343 return this; 344#else[rw] 345 throw new ReadOnlyBufferException(); 346#end[rw] 347 } 348 349 public $Type$Buffer putChar(int i, char x) { 350#if[rw] 351 SCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 352 return this; 353#else[rw] 354 throw new ReadOnlyBufferException(); 355#end[rw] 356 } 357 358 public CharBuffer asCharBuffer() { 359 int pos = position(); 360 int size = (limit() - pos) >> 1; 361 long addr = address + pos; 362 return (bigEndian 363 ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, 364 -1, 365 0, 366 size, 367 size, 368 addr, segment)) 369 : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this, 370 -1, 371 0, 372 size, 373 size, 374 addr, segment))); 375 } 376 377 378 // short 379 380#if[rw] 381 382 public short getShort() { 383 return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian); 384 } 385 386 public short getShort(int i) { 387 return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian); 388 } 389 390#end[rw] 391 392 public $Type$Buffer putShort(short x) { 393#if[rw] 394 SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian); 395 return this; 396#else[rw] 397 throw new ReadOnlyBufferException(); 398#end[rw] 399 } 400 401 public $Type$Buffer putShort(int i, short x) { 402#if[rw] 403 SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 404 return this; 405#else[rw] 406 throw new ReadOnlyBufferException(); 407#end[rw] 408 } 409 410 public ShortBuffer asShortBuffer() { 411 int pos = position(); 412 int size = (limit() - pos) >> 1; 413 long addr = address + pos; 414 return (bigEndian 415 ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, 416 -1, 417 0, 418 size, 419 size, 420 addr, segment)) 421 : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this, 422 -1, 423 0, 424 size, 425 size, 426 addr, segment))); 427 } 428 429 430 // int 431 432#if[rw] 433 434 public int getInt() { 435 return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian); 436 } 437 438 public int getInt(int i) { 439 return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian); 440 } 441 442#end[rw] 443 444 public $Type$Buffer putInt(int x) { 445#if[rw] 446 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), x, bigEndian); 447 return this; 448#else[rw] 449 throw new ReadOnlyBufferException(); 450#end[rw] 451 } 452 453 public $Type$Buffer putInt(int i, int x) { 454#if[rw] 455 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), x, bigEndian); 456 return this; 457#else[rw] 458 throw new ReadOnlyBufferException(); 459#end[rw] 460 } 461 462 public IntBuffer asIntBuffer() { 463 int pos = position(); 464 int size = (limit() - pos) >> 2; 465 long addr = address + pos; 466 return (bigEndian 467 ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this, 468 -1, 469 0, 470 size, 471 size, 472 addr, segment)) 473 : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this, 474 -1, 475 0, 476 size, 477 size, 478 addr, segment))); 479 } 480 481 482 // long 483 484#if[rw] 485 486 public long getLong() { 487 return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian); 488 } 489 490 public long getLong(int i) { 491 return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian); 492 } 493 494#end[rw] 495 496 public $Type$Buffer putLong(long x) { 497#if[rw] 498 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), x, bigEndian); 499 return this; 500#else[rw] 501 throw new ReadOnlyBufferException(); 502#end[rw] 503 } 504 505 public $Type$Buffer putLong(int i, long x) { 506#if[rw] 507 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), x, bigEndian); 508 return this; 509#else[rw] 510 throw new ReadOnlyBufferException(); 511#end[rw] 512 } 513 514 public LongBuffer asLongBuffer() { 515 int pos = position(); 516 int size = (limit() - pos) >> 3; 517 long addr = address + pos; 518 return (bigEndian 519 ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, 520 -1, 521 0, 522 size, 523 size, 524 addr, segment)) 525 : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this, 526 -1, 527 0, 528 size, 529 size, 530 addr, segment))); 531 } 532 533 534 // float 535 536#if[rw] 537 538 public float getFloat() { 539 int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian); 540 return Float.intBitsToFloat(x); 541 } 542 543 public float getFloat(int i) { 544 int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian); 545 return Float.intBitsToFloat(x); 546 } 547 548#end[rw] 549 550 public $Type$Buffer putFloat(float x) { 551#if[rw] 552 int y = Float.floatToRawIntBits(x); 553 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), y, bigEndian); 554 return this; 555#else[rw] 556 throw new ReadOnlyBufferException(); 557#end[rw] 558 } 559 560 public $Type$Buffer putFloat(int i, float x) { 561#if[rw] 562 int y = Float.floatToRawIntBits(x); 563 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), y, bigEndian); 564 return this; 565#else[rw] 566 throw new ReadOnlyBufferException(); 567#end[rw] 568 } 569 570 public FloatBuffer asFloatBuffer() { 571 int pos = position(); 572 int size = (limit() - pos) >> 2; 573 long addr = address + pos; 574 return (bigEndian 575 ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, 576 -1, 577 0, 578 size, 579 size, 580 addr, segment)) 581 : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this, 582 -1, 583 0, 584 size, 585 size, 586 addr, segment))); 587 } 588 589 590 // double 591 592#if[rw] 593 594 public double getDouble() { 595 long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian); 596 return Double.longBitsToDouble(x); 597 } 598 599 public double getDouble(int i) { 600 long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian); 601 return Double.longBitsToDouble(x); 602 } 603 604#end[rw] 605 606 public $Type$Buffer putDouble(double x) { 607#if[rw] 608 long y = Double.doubleToRawLongBits(x); 609 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), y, bigEndian); 610 return this; 611#else[rw] 612 throw new ReadOnlyBufferException(); 613#end[rw] 614 } 615 616 public $Type$Buffer putDouble(int i, double x) { 617#if[rw] 618 long y = Double.doubleToRawLongBits(x); 619 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), y, bigEndian); 620 return this; 621#else[rw] 622 throw new ReadOnlyBufferException(); 623#end[rw] 624 } 625 626 public DoubleBuffer asDoubleBuffer() { 627 int pos = position(); 628 int size = (limit() - pos) >> 3; 629 long addr = address + pos; 630 return (bigEndian 631 ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, 632 -1, 633 0, 634 size, 635 size, 636 addr, segment)) 637 : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this, 638 -1, 639 0, 640 size, 641 size, 642 addr, segment))); 643 } 644 645 646#end[byte] 647 648 649#if[char] 650 651 String toString(int start, int end) { // package-private 652 try { 653 return new String(hb, start + offset, end - start); 654 } catch (StringIndexOutOfBoundsException x) { 655 throw new IndexOutOfBoundsException(); 656 } 657 } 658 659 660 // --- Methods to support CharSequence --- 661 662 public CharBuffer subSequence(int start, int end) { 663 int pos = position(); 664 Objects.checkFromToIndex(start, end, limit() - pos); 665 return new HeapCharBuffer$RW$(hb, 666 -1, 667 pos + start, 668 pos + end, 669 capacity(), 670 offset, segment); 671 } 672 673#end[char] 674 675 676#if[!byte] 677 678 public ByteOrder order() { 679 return ByteOrder.nativeOrder(); 680 } 681#end[!byte] 682#if[char] 683 684 ByteOrder charRegionOrder() { 685 return order(); 686 } 687#end[char] 688} 689