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 /** 31 #if[rw] 32 * A read/write Heap$Type$Buffer. 33 #else[rw] 34 * A read-only Heap$Type$Buffer. This class extends the corresponding 35 * read/write class, overriding the mutation methods to throw a {@link 36 * ReadOnlyBufferException} and overriding the view-buffer methods to return an 37 * instance of this class rather than of the superclass. 38 #end[rw] 39 */ 40 41 import java.util.Objects; 42 43 class Heap$Type$Buffer$RW$ 44 extends {#if[ro]?Heap}$Type$Buffer 45 { 46 // Cached array base offset 47 private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class); 48 49 // Cached array base offset 50 private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class); 51 52 // For speed these fields are actually declared in X-Buffer; 53 // these declarations are here as documentation 54 /* 55 #if[rw] 56 protected final $type$[] hb; 57 protected final int offset; 58 #end[rw] 59 */ 60 61 Heap$Type$Buffer$RW$(int cap, int lim) { // package-private 62 #if[rw] 63 super(-1, 0, lim, cap, new $type$[cap], 0); 64 /* 65 hb = new $type$[cap]; 66 offset = 0; 67 */ 68 this.address = ARRAY_BASE_OFFSET; 69 #else[rw] 70 super(cap, lim); 71 this.isReadOnly = true; 72 #end[rw] 73 } 74 75 Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private 76 #if[rw] 77 super(-1, off, off + len, buf.length, buf, 0); 78 /* 79 hb = buf; 80 offset = 0; 81 */ 82 this.address = ARRAY_BASE_OFFSET; 83 #else[rw] 84 super(buf, off, len); 85 this.isReadOnly = true; 86 #end[rw] 87 } 88 89 protected Heap$Type$Buffer$RW$($type$[] buf, 90 int mark, int pos, int lim, int cap, 91 int off) 92 { 93 #if[rw] 94 super(mark, pos, lim, cap, buf, off); 95 /* 96 hb = buf; 97 offset = off; 98 */ 99 this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE; 100 #else[rw] 101 super(buf, mark, pos, lim, cap, off); 102 this.isReadOnly = true; 103 #end[rw] 104 } 105 106 public $Type$Buffer slice() { 107 return new Heap$Type$Buffer$RW$(hb, 108 -1, 109 0, 110 this.remaining(), 111 this.remaining(), 112 this.position() + offset); 113 } 114 115 #if[byte] 116 $Type$Buffer slice(int pos, int lim) { 117 assert (pos >= 0); 118 assert (pos <= lim); 119 int rem = lim - pos; 120 return new Heap$Type$Buffer$RW$(hb, 121 -1, 122 0, 123 rem, 124 rem, 125 pos + offset); 126 } 127 #end[byte] 128 129 public $Type$Buffer duplicate() { 130 return new Heap$Type$Buffer$RW$(hb, 131 this.markValue(), 132 this.position(), 133 this.limit(), 134 this.capacity(), 135 offset); 136 } 137 138 public $Type$Buffer asReadOnlyBuffer() { 139 #if[rw] 140 return new Heap$Type$BufferR(hb, 141 this.markValue(), 142 this.position(), 143 this.limit(), 144 this.capacity(), 145 offset); 146 #else[rw] 147 return duplicate(); 148 #end[rw] 149 } 150 151 #if[rw] 152 153 protected int ix(int i) { 154 return i + offset; 155 } 156 157 #if[byte] 158 private long byteOffset(long i) { 159 return address + i; 160 } 161 #end[byte] 162 163 public $type$ get() { 164 return hb[ix(nextGetIndex())]; 165 } 166 167 public $type$ get(int i) { 168 return hb[ix(checkIndex(i))]; 169 } 170 171 #if[streamableType] 172 $type$ getUnchecked(int i) { 173 return hb[ix(i)]; 174 } 175 #end[streamableType] 176 177 public $Type$Buffer get($type$[] dst, int offset, int length) { 178 checkBounds(offset, length, dst.length); 179 if (length > remaining()) 180 throw new BufferUnderflowException(); 181 System.arraycopy(hb, ix(position()), dst, offset, length); 182 position(position() + length); 183 return this; 184 } 185 186 public $Type$Buffer get(int index, $type$[] dst, int offset, int length) { 187 //System.out.println("Heap absolute bulk get"); 188 Objects.checkFromIndexSize(index, length, limit()); 189 Objects.checkFromIndexSize(offset, length, dst.length); 190 System.arraycopy(hb, ix(index), dst, offset, length); 191 return this; 192 } 193 194 public boolean isDirect() { 195 return false; 196 } 197 198 #end[rw] 199 200 public boolean isReadOnly() { 201 return {#if[rw]?false:true}; 202 } 203 204 public $Type$Buffer put($type$ x) { 205 #if[rw] 206 hb[ix(nextPutIndex())] = x; 207 return this; 208 #else[rw] 209 throw new ReadOnlyBufferException(); 210 #end[rw] 211 } 212 213 public $Type$Buffer put(int i, $type$ x) { 214 #if[rw] 215 hb[ix(checkIndex(i))] = x; 216 return this; 217 #else[rw] 218 throw new ReadOnlyBufferException(); 219 #end[rw] 220 } 221 222 public $Type$Buffer put($type$[] src, int offset, int length) { 223 #if[rw] 224 checkBounds(offset, length, src.length); 225 if (length > remaining()) 226 throw new BufferOverflowException(); 227 System.arraycopy(src, offset, hb, ix(position()), length); 228 position(position() + length); 229 return this; 230 #else[rw] 231 throw new ReadOnlyBufferException(); 232 #end[rw] 233 } 234 235 public $Type$Buffer put($Type$Buffer src) { 236 #if[rw] 237 if (src instanceof Heap$Type$Buffer) { 238 if (src == this) 239 throw createSameBufferException(); 240 Heap$Type$Buffer sb = (Heap$Type$Buffer)src; 241 int n = sb.remaining(); 242 if (n > remaining()) 243 throw new BufferOverflowException(); 244 System.arraycopy(sb.hb, sb.ix(sb.position()), 245 hb, ix(position()), n); 246 sb.position(sb.position() + n); 247 position(position() + n); 248 } else if (src.isDirect()) { 249 int n = src.remaining(); 250 if (n > remaining()) 251 throw new BufferOverflowException(); 252 src.get(hb, ix(position()), n); 253 position(position() + n); 254 } else { 255 super.put(src); 256 } 257 return this; 258 #else[rw] 259 throw new ReadOnlyBufferException(); 260 #end[rw] 261 } 262 263 public $Type$Buffer put(int index, $type$[] src, int offset, int length) { 264 //System.out.println("Heap absolute bulk put array"); 265 #if[rw] 266 Objects.checkFromIndexSize(index, length, limit()); 267 Objects.checkFromIndexSize(offset, length, src.length); 268 System.arraycopy(src, offset, hb, ix(index), length); 269 return this; 270 #else[rw] 271 throw new ReadOnlyBufferException(); 272 #end[rw] 273 } 274 275 public $Type$Buffer put(int index, $Type$Buffer src, int srcIndex, 276 int length) { 277 //System.out.println("Heap absolute bulk put buffer"); 278 #if[rw] 279 if (src instanceof Heap$Type$Buffer) { 280 if (index < 0) 281 throw new IndexOutOfBoundsException("Index negative: " + index); 282 Heap$Type$Buffer sb = (Heap$Type$Buffer)src; 283 Objects.checkFromIndexSize(index, length, limit()); 284 Objects.checkFromIndexSize(srcIndex, length, sb.limit()); 285 System.arraycopy(sb.hb, sb.ix(srcIndex), 286 hb, ix(index), length); 287 } else if (src.isDirect()) { 288 Objects.checkFromIndexSize(index, length, limit()); 289 Objects.checkFromIndexSize(srcIndex, length, src.limit()); 290 src.get(srcIndex, hb, ix(index), length); 291 } else { 292 super.put(index, src, srcIndex, length); 293 } 294 return this; 295 #else[rw] 296 throw new ReadOnlyBufferException(); 297 #end[rw] 298 } 299 300 public $Type$Buffer compact() { 301 #if[rw] 302 System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); 303 position(remaining()); 304 limit(capacity()); 305 discardMark(); 306 return this; 307 #else[rw] 308 throw new ReadOnlyBufferException(); 309 #end[rw] 310 } 311 312 313 314 #if[byte] 315 316 byte _get(int i) { // package-private 317 return hb[i]; 318 } 319 320 void _put(int i, byte b) { // package-private 321 #if[rw] 322 hb[i] = b; 323 #else[rw] 324 throw new ReadOnlyBufferException(); 325 #end[rw] 326 } 327 328 // char 329 330 #if[rw] 331 332 public char getChar() { 333 return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 334 } 335 336 public char getChar(int i) { 337 return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 338 } 339 340 #end[rw] 341 342 public $Type$Buffer putChar(char x) { 343 #if[rw] 344 UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 345 return this; 346 #else[rw] 347 throw new ReadOnlyBufferException(); 348 #end[rw] 349 } 350 351 public $Type$Buffer putChar(int i, char x) { 352 #if[rw] 353 UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 354 return this; 355 #else[rw] 356 throw new ReadOnlyBufferException(); 357 #end[rw] 358 } 359 360 public CharBuffer asCharBuffer() { 361 int size = this.remaining() >> 1; 362 long addr = address + position(); 363 return (bigEndian 364 ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, 365 -1, 366 0, 367 size, 368 size, 369 addr)) 370 : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this, 371 -1, 372 0, 373 size, 374 size, 375 addr))); 376 } 377 378 379 // short 380 381 #if[rw] 382 383 public short getShort() { 384 return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 385 } 386 387 public short getShort(int i) { 388 return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 389 } 390 391 #end[rw] 392 393 public $Type$Buffer putShort(short x) { 394 #if[rw] 395 UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 396 return this; 397 #else[rw] 398 throw new ReadOnlyBufferException(); 399 #end[rw] 400 } 401 402 public $Type$Buffer putShort(int i, short x) { 403 #if[rw] 404 UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 405 return this; 406 #else[rw] 407 throw new ReadOnlyBufferException(); 408 #end[rw] 409 } 410 411 public ShortBuffer asShortBuffer() { 412 int size = this.remaining() >> 1; 413 long addr = address + position(); 414 return (bigEndian 415 ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, 416 -1, 417 0, 418 size, 419 size, 420 addr)) 421 : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this, 422 -1, 423 0, 424 size, 425 size, 426 addr))); 427 } 428 429 430 // int 431 432 #if[rw] 433 434 public int getInt() { 435 return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 436 } 437 438 public int getInt(int i) { 439 return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); 440 } 441 442 #end[rw] 443 444 public $Type$Buffer putInt(int x) { 445 #if[rw] 446 UNSAFE.putIntUnaligned(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 UNSAFE.putIntUnaligned(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 size = this.remaining() >> 2; 464 long addr = address + position(); 465 return (bigEndian 466 ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this, 467 -1, 468 0, 469 size, 470 size, 471 addr)) 472 : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this, 473 -1, 474 0, 475 size, 476 size, 477 addr))); 478 } 479 480 481 // long 482 483 #if[rw] 484 485 public long getLong() { 486 return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); 487 } 488 489 public long getLong(int i) { 490 return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); 491 } 492 493 #end[rw] 494 495 public $Type$Buffer putLong(long x) { 496 #if[rw] 497 UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian); 498 return this; 499 #else[rw] 500 throw new ReadOnlyBufferException(); 501 #end[rw] 502 } 503 504 public $Type$Buffer putLong(int i, long x) { 505 #if[rw] 506 UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian); 507 return this; 508 #else[rw] 509 throw new ReadOnlyBufferException(); 510 #end[rw] 511 } 512 513 public LongBuffer asLongBuffer() { 514 int size = this.remaining() >> 3; 515 long addr = address + position(); 516 return (bigEndian 517 ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, 518 -1, 519 0, 520 size, 521 size, 522 addr)) 523 : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this, 524 -1, 525 0, 526 size, 527 size, 528 addr))); 529 } 530 531 532 // float 533 534 #if[rw] 535 536 public float getFloat() { 537 int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 538 return Float.intBitsToFloat(x); 539 } 540 541 public float getFloat(int i) { 542 int x = UNSAFE.getIntUnaligned(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 UNSAFE.putIntUnaligned(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 UNSAFE.putIntUnaligned(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 size = this.remaining() >> 2; 570 long addr = address + position(); 571 return (bigEndian 572 ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, 573 -1, 574 0, 575 size, 576 size, 577 addr)) 578 : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this, 579 -1, 580 0, 581 size, 582 size, 583 addr))); 584 } 585 586 587 // double 588 589 #if[rw] 590 591 public double getDouble() { 592 long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); 593 return Double.longBitsToDouble(x); 594 } 595 596 public double getDouble(int i) { 597 long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); 598 return Double.longBitsToDouble(x); 599 } 600 601 #end[rw] 602 603 public $Type$Buffer putDouble(double x) { 604 #if[rw] 605 long y = Double.doubleToRawLongBits(x); 606 UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian); 607 return this; 608 #else[rw] 609 throw new ReadOnlyBufferException(); 610 #end[rw] 611 } 612 613 public $Type$Buffer putDouble(int i, double x) { 614 #if[rw] 615 long y = Double.doubleToRawLongBits(x); 616 UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian); 617 return this; 618 #else[rw] 619 throw new ReadOnlyBufferException(); 620 #end[rw] 621 } 622 623 public DoubleBuffer asDoubleBuffer() { 624 int size = this.remaining() >> 3; 625 long addr = address + position(); 626 return (bigEndian 627 ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, 628 -1, 629 0, 630 size, 631 size, 632 addr)) 633 : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this, 634 -1, 635 0, 636 size, 637 size, 638 addr))); 639 } 640 641 642 #end[byte] 643 644 645 #if[char] 646 647 String toString(int start, int end) { // package-private 648 try { 649 return new String(hb, start + offset, end - start); 650 } catch (StringIndexOutOfBoundsException x) { 651 throw new IndexOutOfBoundsException(); 652 } 653 } 654 655 656 // --- Methods to support CharSequence --- 657 658 public CharBuffer subSequence(int start, int end) { 659 if ((start < 0) 660 || (end > length()) 661 || (start > end)) 662 throw new IndexOutOfBoundsException(); 663 int pos = position(); 664 return new HeapCharBuffer$RW$(hb, 665 -1, 666 pos + start, 667 pos + end, 668 capacity(), 669 offset); 670 } 671 672 #end[char] 673 674 675 #if[!byte] 676 677 public ByteOrder order() { 678 return ByteOrder.nativeOrder(); 679 } 680 #end[!byte] 681 #if[char] 682 683 ByteOrder charRegionOrder() { 684 return order(); 685 } 686 #end[char] 687 }