1 /* 2 * Copyright (c) 2000, 2019, 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 28 package java.nio; 29 30 import java.util.Objects; 31 import 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 44 class 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 base offset 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 rem = this.remaining(); 109 return new Heap$Type$Buffer$RW$(hb, 110 -1, 111 0, 112 rem, 113 rem, 114 this.position() + offset, segment); 115 } 116 117 @Override 118 public $Type$Buffer slice(int index, int length) { 119 Objects.checkFromIndexSize(index, length, limit()); 120 return new Heap$Type$Buffer$RW$(hb, 121 -1, 122 0, 123 length, 124 length, 125 index + offset, segment); 126 } 127 128 public $Type$Buffer duplicate() { 129 return new Heap$Type$Buffer$RW$(hb, 130 this.markValue(), 131 this.position(), 132 this.limit(), 133 this.capacity(), 134 offset, segment); 135 } 136 137 public $Type$Buffer asReadOnlyBuffer() { 138 #if[rw] 139 return new Heap$Type$BufferR(hb, 140 this.markValue(), 141 this.position(), 142 this.limit(), 143 this.capacity(), 144 offset, segment); 145 #else[rw] 146 return duplicate(); 147 #end[rw] 148 } 149 150 #if[rw] 151 152 protected int ix(int i) { 153 return i + offset; 154 } 155 156 #if[byte] 157 private long byteOffset(long i) { 158 return address + i; 159 } 160 #end[byte] 161 162 public $type$ get() { 163 checkSegment(); 164 return hb[ix(nextGetIndex())]; 165 } 166 167 public $type$ get(int i) { 168 checkSegment(); 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 checkSegment(); 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 checkSegment(); 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 checkSegment(); 210 hb[ix(nextPutIndex())] = x; 211 return this; 212 #else[rw] 213 throw new ReadOnlyBufferException(); 214 #end[rw] 215 } 216 217 public $Type$Buffer put(int i, $type$ x) { 218 #if[rw] 219 checkSegment(); 220 hb[ix(checkIndex(i))] = x; 221 return this; 222 #else[rw] 223 throw new ReadOnlyBufferException(); 224 #end[rw] 225 } 226 227 public $Type$Buffer put($type$[] src, int offset, int length) { 228 #if[rw] 229 checkSegment(); 230 Objects.checkFromIndexSize(offset, length, src.length); 231 int pos = position(); 232 if (length > limit() - pos) 233 throw new BufferOverflowException(); 234 System.arraycopy(src, offset, hb, ix(pos), length); 235 position(pos + length); 236 return this; 237 #else[rw] 238 throw new ReadOnlyBufferException(); 239 #end[rw] 240 } 241 242 public $Type$Buffer put($Type$Buffer src) { 243 #if[rw] 244 checkSegment(); 245 if (src instanceof Heap$Type$Buffer) { 246 if (src == this) 247 throw createSameBufferException(); 248 Heap$Type$Buffer sb = (Heap$Type$Buffer)src; 249 int pos = position(); 250 int sbpos = sb.position(); 251 int n = sb.limit() - sbpos; 252 if (n > limit() - pos) 253 throw new BufferOverflowException(); 254 System.arraycopy(sb.hb, sb.ix(sbpos), 255 hb, ix(pos), n); 256 sb.position(sbpos + n); 257 position(pos + n); 258 } else if (src.isDirect()) { 259 int n = src.remaining(); 260 int pos = position(); 261 if (n > limit() - pos) 262 throw new BufferOverflowException(); 263 src.get(hb, ix(pos), n); 264 position(pos + n); 265 } else { 266 super.put(src); 267 } 268 return this; 269 #else[rw] 270 throw new ReadOnlyBufferException(); 271 #end[rw] 272 } 273 274 public $Type$Buffer put(int index, $type$[] src, int offset, int length) { 275 #if[rw] 276 checkSegment(); 277 Objects.checkFromIndexSize(index, length, limit()); 278 Objects.checkFromIndexSize(offset, length, src.length); 279 System.arraycopy(src, offset, hb, ix(index), length); 280 return this; 281 #else[rw] 282 throw new ReadOnlyBufferException(); 283 #end[rw] 284 } 285 286 #if[char] 287 288 public $Type$Buffer put(String src, int start, int end) { 289 checkSegment(); 290 int length = end - start; 291 Objects.checkFromIndexSize(start, length, src.length()); 292 if (isReadOnly()) 293 throw new ReadOnlyBufferException(); 294 int pos = position(); 295 int lim = limit(); 296 int rem = (pos <= lim) ? lim - pos : 0; 297 if (length > rem) 298 throw new BufferOverflowException(); 299 src.getChars(start, end, hb, ix(pos)); 300 position(pos + length); 301 return this; 302 } 303 304 #end[char] 305 306 public $Type$Buffer compact() { 307 #if[rw] 308 int pos = position(); 309 int rem = limit() - pos; 310 System.arraycopy(hb, ix(pos), hb, ix(0), rem); 311 position(rem); 312 limit(capacity()); 313 discardMark(); 314 return this; 315 #else[rw] 316 throw new ReadOnlyBufferException(); 317 #end[rw] 318 } 319 320 321 322 #if[byte] 323 324 byte _get(int i) { // package-private 325 return hb[i]; 326 } 327 328 void _put(int i, byte b) { // package-private 329 #if[rw] 330 hb[i] = b; 331 #else[rw] 332 throw new ReadOnlyBufferException(); 333 #end[rw] 334 } 335 336 // char 337 338 #if[rw] 339 340 public char getChar() { 341 checkSegment(); 342 return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 343 } 344 345 public char getChar(int i) { 346 return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 347 } 348 349 #end[rw] 350 351 public $Type$Buffer putChar(char x) { 352 #if[rw] 353 checkSegment(); 354 UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 355 return this; 356 #else[rw] 357 throw new ReadOnlyBufferException(); 358 #end[rw] 359 } 360 361 public $Type$Buffer putChar(int i, char x) { 362 #if[rw] 363 checkSegment(); 364 UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 365 return this; 366 #else[rw] 367 throw new ReadOnlyBufferException(); 368 #end[rw] 369 } 370 371 public CharBuffer asCharBuffer() { 372 int pos = position(); 373 int size = (limit() - pos) >> 1; 374 long addr = address + pos; 375 return (bigEndian 376 ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, 377 -1, 378 0, 379 size, 380 size, 381 addr, segment)) 382 : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this, 383 -1, 384 0, 385 size, 386 size, 387 addr, segment))); 388 } 389 390 391 // short 392 393 #if[rw] 394 395 public short getShort() { 396 checkSegment(); 397 return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 398 } 399 400 public short getShort(int i) { 401 checkSegment(); 402 return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 403 } 404 405 #end[rw] 406 407 public $Type$Buffer putShort(short x) { 408 #if[rw] 409 checkSegment(); 410 UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 411 return this; 412 #else[rw] 413 throw new ReadOnlyBufferException(); 414 #end[rw] 415 } 416 417 public $Type$Buffer putShort(int i, short x) { 418 #if[rw] 419 checkSegment(); 420 UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 421 return this; 422 #else[rw] 423 throw new ReadOnlyBufferException(); 424 #end[rw] 425 } 426 427 public ShortBuffer asShortBuffer() { 428 int pos = position(); 429 int size = (limit() - pos) >> 1; 430 long addr = address + pos; 431 return (bigEndian 432 ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, 433 -1, 434 0, 435 size, 436 size, 437 addr, segment)) 438 : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this, 439 -1, 440 0, 441 size, 442 size, 443 addr, segment))); 444 } 445 446 447 // int 448 449 #if[rw] 450 451 public int getInt() { 452 checkSegment(); 453 return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 454 } 455 456 public int getInt(int i) { 457 checkSegment(); 458 return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); 459 } 460 461 #end[rw] 462 463 public $Type$Buffer putInt(int x) { 464 #if[rw] 465 checkSegment(); 466 UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian); 467 return this; 468 #else[rw] 469 throw new ReadOnlyBufferException(); 470 #end[rw] 471 } 472 473 public $Type$Buffer putInt(int i, int x) { 474 #if[rw] 475 checkSegment(); 476 UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian); 477 return this; 478 #else[rw] 479 throw new ReadOnlyBufferException(); 480 #end[rw] 481 } 482 483 public IntBuffer asIntBuffer() { 484 int pos = position(); 485 int size = (limit() - pos) >> 2; 486 long addr = address + pos; 487 return (bigEndian 488 ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this, 489 -1, 490 0, 491 size, 492 size, 493 addr, segment)) 494 : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this, 495 -1, 496 0, 497 size, 498 size, 499 addr, segment))); 500 } 501 502 503 // long 504 505 #if[rw] 506 507 public long getLong() { 508 checkSegment(); 509 return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); 510 } 511 512 public long getLong(int i) { 513 checkSegment(); 514 return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); 515 } 516 517 #end[rw] 518 519 public $Type$Buffer putLong(long x) { 520 #if[rw] 521 checkSegment(); 522 UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian); 523 return this; 524 #else[rw] 525 throw new ReadOnlyBufferException(); 526 #end[rw] 527 } 528 529 public $Type$Buffer putLong(int i, long x) { 530 #if[rw] 531 checkSegment(); 532 UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian); 533 return this; 534 #else[rw] 535 throw new ReadOnlyBufferException(); 536 #end[rw] 537 } 538 539 public LongBuffer asLongBuffer() { 540 int pos = position(); 541 int size = (limit() - pos) >> 3; 542 long addr = address + pos; 543 return (bigEndian 544 ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, 545 -1, 546 0, 547 size, 548 size, 549 addr, segment)) 550 : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this, 551 -1, 552 0, 553 size, 554 size, 555 addr, segment))); 556 } 557 558 559 // float 560 561 #if[rw] 562 563 public float getFloat() { 564 checkSegment(); 565 int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 566 return Float.intBitsToFloat(x); 567 } 568 569 public float getFloat(int i) { 570 checkSegment(); 571 int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); 572 return Float.intBitsToFloat(x); 573 } 574 575 #end[rw] 576 577 public $Type$Buffer putFloat(float x) { 578 #if[rw] 579 checkSegment(); 580 int y = Float.floatToRawIntBits(x); 581 UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian); 582 return this; 583 #else[rw] 584 throw new ReadOnlyBufferException(); 585 #end[rw] 586 } 587 588 public $Type$Buffer putFloat(int i, float x) { 589 #if[rw] 590 checkSegment(); 591 int y = Float.floatToRawIntBits(x); 592 UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian); 593 return this; 594 #else[rw] 595 throw new ReadOnlyBufferException(); 596 #end[rw] 597 } 598 599 public FloatBuffer asFloatBuffer() { 600 int pos = position(); 601 int size = (limit() - pos) >> 2; 602 long addr = address + pos; 603 return (bigEndian 604 ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, 605 -1, 606 0, 607 size, 608 size, 609 addr, segment)) 610 : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this, 611 -1, 612 0, 613 size, 614 size, 615 addr, segment))); 616 } 617 618 619 // double 620 621 #if[rw] 622 623 public double getDouble() { 624 checkSegment(); 625 long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); 626 return Double.longBitsToDouble(x); 627 } 628 629 public double getDouble(int i) { 630 checkSegment(); 631 long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); 632 return Double.longBitsToDouble(x); 633 } 634 635 #end[rw] 636 637 public $Type$Buffer putDouble(double x) { 638 #if[rw] 639 checkSegment(); 640 long y = Double.doubleToRawLongBits(x); 641 UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian); 642 return this; 643 #else[rw] 644 throw new ReadOnlyBufferException(); 645 #end[rw] 646 } 647 648 public $Type$Buffer putDouble(int i, double x) { 649 #if[rw] 650 checkSegment(); 651 long y = Double.doubleToRawLongBits(x); 652 UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian); 653 return this; 654 #else[rw] 655 throw new ReadOnlyBufferException(); 656 #end[rw] 657 } 658 659 public DoubleBuffer asDoubleBuffer() { 660 int pos = position(); 661 int size = (limit() - pos) >> 3; 662 long addr = address + pos; 663 return (bigEndian 664 ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, 665 -1, 666 0, 667 size, 668 size, 669 addr, segment)) 670 : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this, 671 -1, 672 0, 673 size, 674 size, 675 addr, segment))); 676 } 677 678 679 #end[byte] 680 681 682 #if[char] 683 684 String toString(int start, int end) { // package-private 685 try { 686 return new String(hb, start + offset, end - start); 687 } catch (StringIndexOutOfBoundsException x) { 688 throw new IndexOutOfBoundsException(); 689 } 690 } 691 692 693 // --- Methods to support CharSequence --- 694 695 public CharBuffer subSequence(int start, int end) { 696 int pos = position(); 697 Objects.checkFromToIndex(start, end, limit() - pos); 698 return new HeapCharBuffer$RW$(hb, 699 -1, 700 pos + start, 701 pos + end, 702 capacity(), 703 offset, segment); 704 } 705 706 #end[char] 707 708 709 #if[!byte] 710 711 public ByteOrder order() { 712 return ByteOrder.nativeOrder(); 713 } 714 #end[!byte] 715 #if[char] 716 717 ByteOrder charRegionOrder() { 718 return order(); 719 } 720 #end[char] 721 }