1/* 2 * Copyright (c) 2000, 2020, 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 checkScope(); 276 int length = end - start; 277 Objects.checkFromIndexSize(start, length, src.length()); 278 if (isReadOnly()) 279 throw new ReadOnlyBufferException(); 280 int pos = position(); 281 int lim = limit(); 282 int rem = (pos <= lim) ? lim - pos : 0; 283 if (length > rem) 284 throw new BufferOverflowException(); 285 src.getChars(start, end, hb, ix(pos)); 286 position(pos + length); 287 return this; 288 } 289 290#end[char] 291 292 public $Type$Buffer compact() { 293#if[rw] 294 int pos = position(); 295 int lim = limit(); 296 assert (pos <= lim); 297 int rem = (pos <= lim ? lim - pos : 0); 298 System.arraycopy(hb, ix(pos), hb, ix(0), rem); 299 position(rem); 300 limit(capacity()); 301 discardMark(); 302 return this; 303#else[rw] 304 throw new ReadOnlyBufferException(); 305#end[rw] 306 } 307 308 309 310#if[byte] 311 312 byte _get(int i) { // package-private 313 return hb[i]; 314 } 315 316 void _put(int i, byte b) { // package-private 317#if[rw] 318 hb[i] = b; 319#else[rw] 320 throw new ReadOnlyBufferException(); 321#end[rw] 322 } 323 324 // char 325 326#if[rw] 327 328 public char getChar() { 329 return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian); 330 } 331 332 public char getChar(int i) { 333 return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian); 334 } 335 336#end[rw] 337 338 public $Type$Buffer putChar(char x) { 339#if[rw] 340 SCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian); 341 return this; 342#else[rw] 343 throw new ReadOnlyBufferException(); 344#end[rw] 345 } 346 347 public $Type$Buffer putChar(int i, char x) { 348#if[rw] 349 SCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 350 return this; 351#else[rw] 352 throw new ReadOnlyBufferException(); 353#end[rw] 354 } 355 356 public CharBuffer asCharBuffer() { 357 int pos = position(); 358 int size = (limit() - pos) >> 1; 359 long addr = address + pos; 360 return (bigEndian 361 ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, 362 -1, 363 0, 364 size, 365 size, 366 addr, segment)) 367 : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this, 368 -1, 369 0, 370 size, 371 size, 372 addr, segment))); 373 } 374 375 376 // short 377 378#if[rw] 379 380 public short getShort() { 381 return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian); 382 } 383 384 public short getShort(int i) { 385 return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian); 386 } 387 388#end[rw] 389 390 public $Type$Buffer putShort(short x) { 391#if[rw] 392 SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian); 393 return this; 394#else[rw] 395 throw new ReadOnlyBufferException(); 396#end[rw] 397 } 398 399 public $Type$Buffer putShort(int i, short x) { 400#if[rw] 401 SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 402 return this; 403#else[rw] 404 throw new ReadOnlyBufferException(); 405#end[rw] 406 } 407 408 public ShortBuffer asShortBuffer() { 409 int pos = position(); 410 int size = (limit() - pos) >> 1; 411 long addr = address + pos; 412 return (bigEndian 413 ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, 414 -1, 415 0, 416 size, 417 size, 418 addr, segment)) 419 : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this, 420 -1, 421 0, 422 size, 423 size, 424 addr, segment))); 425 } 426 427 428 // int 429 430#if[rw] 431 432 public int getInt() { 433 return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian); 434 } 435 436 public int getInt(int i) { 437 return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian); 438 } 439 440#end[rw] 441 442 public $Type$Buffer putInt(int x) { 443#if[rw] 444 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), x, bigEndian); 445 return this; 446#else[rw] 447 throw new ReadOnlyBufferException(); 448#end[rw] 449 } 450 451 public $Type$Buffer putInt(int i, int x) { 452#if[rw] 453 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), x, bigEndian); 454 return this; 455#else[rw] 456 throw new ReadOnlyBufferException(); 457#end[rw] 458 } 459 460 public IntBuffer asIntBuffer() { 461 int pos = position(); 462 int size = (limit() - pos) >> 2; 463 long addr = address + pos; 464 return (bigEndian 465 ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this, 466 -1, 467 0, 468 size, 469 size, 470 addr, segment)) 471 : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this, 472 -1, 473 0, 474 size, 475 size, 476 addr, segment))); 477 } 478 479 480 // long 481 482#if[rw] 483 484 public long getLong() { 485 return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian); 486 } 487 488 public long getLong(int i) { 489 return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian); 490 } 491 492#end[rw] 493 494 public $Type$Buffer putLong(long x) { 495#if[rw] 496 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), x, bigEndian); 497 return this; 498#else[rw] 499 throw new ReadOnlyBufferException(); 500#end[rw] 501 } 502 503 public $Type$Buffer putLong(int i, long x) { 504#if[rw] 505 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), x, bigEndian); 506 return this; 507#else[rw] 508 throw new ReadOnlyBufferException(); 509#end[rw] 510 } 511 512 public LongBuffer asLongBuffer() { 513 int pos = position(); 514 int size = (limit() - pos) >> 3; 515 long addr = address + pos; 516 return (bigEndian 517 ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, 518 -1, 519 0, 520 size, 521 size, 522 addr, segment)) 523 : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this, 524 -1, 525 0, 526 size, 527 size, 528 addr, segment))); 529 } 530 531 532 // float 533 534#if[rw] 535 536 public float getFloat() { 537 int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian); 538 return Float.intBitsToFloat(x); 539 } 540 541 public float getFloat(int i) { 542 int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian); 543 return Float.intBitsToFloat(x); 544 } 545 546#end[rw] 547 548 public $Type$Buffer putFloat(float x) { 549#if[rw] 550 int y = Float.floatToRawIntBits(x); 551 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), y, bigEndian); 552 return this; 553#else[rw] 554 throw new ReadOnlyBufferException(); 555#end[rw] 556 } 557 558 public $Type$Buffer putFloat(int i, float x) { 559#if[rw] 560 int y = Float.floatToRawIntBits(x); 561 SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), y, bigEndian); 562 return this; 563#else[rw] 564 throw new ReadOnlyBufferException(); 565#end[rw] 566 } 567 568 public FloatBuffer asFloatBuffer() { 569 int pos = position(); 570 int size = (limit() - pos) >> 2; 571 long addr = address + pos; 572 return (bigEndian 573 ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, 574 -1, 575 0, 576 size, 577 size, 578 addr, segment)) 579 : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this, 580 -1, 581 0, 582 size, 583 size, 584 addr, segment))); 585 } 586 587 588 // double 589 590#if[rw] 591 592 public double getDouble() { 593 long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian); 594 return Double.longBitsToDouble(x); 595 } 596 597 public double getDouble(int i) { 598 long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian); 599 return Double.longBitsToDouble(x); 600 } 601 602#end[rw] 603 604 public $Type$Buffer putDouble(double x) { 605#if[rw] 606 long y = Double.doubleToRawLongBits(x); 607 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), y, bigEndian); 608 return this; 609#else[rw] 610 throw new ReadOnlyBufferException(); 611#end[rw] 612 } 613 614 public $Type$Buffer putDouble(int i, double x) { 615#if[rw] 616 long y = Double.doubleToRawLongBits(x); 617 SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), y, bigEndian); 618 return this; 619#else[rw] 620 throw new ReadOnlyBufferException(); 621#end[rw] 622 } 623 624 public DoubleBuffer asDoubleBuffer() { 625 int pos = position(); 626 int size = (limit() - pos) >> 3; 627 long addr = address + pos; 628 return (bigEndian 629 ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, 630 -1, 631 0, 632 size, 633 size, 634 addr, segment)) 635 : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this, 636 -1, 637 0, 638 size, 639 size, 640 addr, segment))); 641 } 642 643 644#end[byte] 645 646 647#if[char] 648 649 String toString(int start, int end) { // package-private 650 try { 651 return new String(hb, start + offset, end - start); 652 } catch (StringIndexOutOfBoundsException x) { 653 throw new IndexOutOfBoundsException(); 654 } 655 } 656 657 658 // --- Methods to support CharSequence --- 659 660 public CharBuffer subSequence(int start, int end) { 661 int pos = position(); 662 Objects.checkFromToIndex(start, end, limit() - pos); 663 return new HeapCharBuffer$RW$(hb, 664 -1, 665 pos + start, 666 pos + end, 667 capacity(), 668 offset, segment); 669 } 670 671#end[char] 672 673 674#if[!byte] 675 676 public ByteOrder order() { 677 return ByteOrder.nativeOrder(); 678 } 679#end[!byte] 680#if[char] 681 682 ByteOrder charRegionOrder() { 683 return order(); 684 } 685#end[char] 686} 687