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 32 /** 33 #if[rw] 34 * A read/write Heap$Type$Buffer. 35 #else[rw] 36 * A read-only Heap$Type$Buffer. This class extends the corresponding 37 * read/write class, overriding the mutation methods to throw a {@link 38 * ReadOnlyBufferException} and overriding the view-buffer methods to return an 39 * instance of this class rather than of the superclass. 40 #end[rw] 41 */ 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 int rem = this.remaining(); 108 return new Heap$Type$Buffer$RW$(hb, 109 -1, 110 0, 111 rem, 112 rem, 113 this.position() + offset); 114 } 115 116 @Override 117 public $Type$Buffer slice(int index, int length) { 118 Objects.checkFromIndexSize(index, length, limit()); 119 return new Heap$Type$Buffer$RW$(hb, 120 -1, 121 0, 122 length, 123 length, 124 index + offset); 125 } 126 127 public $Type$Buffer duplicate() { 128 return new Heap$Type$Buffer$RW$(hb, 129 this.markValue(), 130 this.position(), 131 this.limit(), 132 this.capacity(), 133 offset); 134 } 135 136 public $Type$Buffer asReadOnlyBuffer() { 137 #if[rw] 138 return new Heap$Type$BufferR(hb, 139 this.markValue(), 140 this.position(), 141 this.limit(), 142 this.capacity(), 143 offset); 144 #else[rw] 145 return duplicate(); 146 #end[rw] 147 } 148 149 #if[rw] 150 151 protected int ix(int i) { 152 return i + offset; 153 } 154 155 #if[byte] 156 private long byteOffset(long i) { 157 return address + i; 158 } 159 #end[byte] 160 161 public $type$ get() { 162 return hb[ix(nextGetIndex())]; 163 } 164 165 public $type$ get(int i) { 166 return hb[ix(checkIndex(i))]; 167 } 168 169 #if[streamableType] 170 $type$ getUnchecked(int i) { 171 return hb[ix(i)]; 172 } 173 #end[streamableType] 174 175 public $Type$Buffer get($type$[] dst, int offset, int length) { 176 Objects.checkFromIndexSize(offset, length, dst.length); 177 int pos = position(); 178 if (length > limit() - pos) 179 throw new BufferUnderflowException(); 180 System.arraycopy(hb, ix(pos), dst, offset, length); 181 position(pos + length); 182 return this; 183 } 184 185 public $Type$Buffer get(int index, $type$[] dst, int offset, int length) { 186 Objects.checkFromIndexSize(index, length, limit()); 187 Objects.checkFromIndexSize(offset, length, dst.length); 188 System.arraycopy(hb, ix(index), dst, offset, length); 189 return this; 190 } 191 192 public boolean isDirect() { 193 return false; 194 } 195 196 #end[rw] 197 198 public boolean isReadOnly() { 199 return {#if[rw]?false:true}; 200 } 201 202 public $Type$Buffer put($type$ x) { 203 #if[rw] 204 hb[ix(nextPutIndex())] = x; 205 return this; 206 #else[rw] 207 throw new ReadOnlyBufferException(); 208 #end[rw] 209 } 210 211 public $Type$Buffer put(int i, $type$ x) { 212 #if[rw] 213 hb[ix(checkIndex(i))] = x; 214 return this; 215 #else[rw] 216 throw new ReadOnlyBufferException(); 217 #end[rw] 218 } 219 220 public $Type$Buffer put($type$[] src, int offset, int length) { 221 #if[rw] 222 Objects.checkFromIndexSize(offset, length, src.length); 223 int pos = position(); 224 if (length > limit() - pos) 225 throw new BufferOverflowException(); 226 System.arraycopy(src, offset, hb, ix(pos), length); 227 position(pos + length); 228 return this; 229 #else[rw] 230 throw new ReadOnlyBufferException(); 231 #end[rw] 232 } 233 234 public $Type$Buffer put($Type$Buffer src) { 235 #if[rw] 236 if (src instanceof Heap$Type$Buffer) { 237 if (src == this) 238 throw createSameBufferException(); 239 Heap$Type$Buffer sb = (Heap$Type$Buffer)src; 240 int pos = position(); 241 int sbpos = sb.position(); 242 int n = sb.limit() - sbpos; 243 if (n > limit() - pos) 244 throw new BufferOverflowException(); 245 System.arraycopy(sb.hb, sb.ix(sbpos), 246 hb, ix(pos), n); 247 sb.position(sbpos + n); 248 position(pos + n); 249 } else if (src.isDirect()) { 250 int n = src.remaining(); 251 int pos = position(); 252 if (n > limit() - pos) 253 throw new BufferOverflowException(); 254 src.get(hb, ix(pos), n); 255 position(pos + n); 256 } else { 257 super.put(src); 258 } 259 return this; 260 #else[rw] 261 throw new ReadOnlyBufferException(); 262 #end[rw] 263 } 264 265 public $Type$Buffer put(int index, $type$[] src, int offset, int length) { 266 #if[rw] 267 Objects.checkFromIndexSize(index, length, limit()); 268 Objects.checkFromIndexSize(offset, length, src.length); 269 System.arraycopy(src, offset, hb, ix(index), length); 270 return this; 271 #else[rw] 272 throw new ReadOnlyBufferException(); 273 #end[rw] 274 } 275 276 #if[char] 277 278 public $Type$Buffer put(String src, int start, int end) { 279 int length = end - start; 280 Objects.checkFromIndexSize(start, length, src.length()); 281 if (isReadOnly()) 282 throw new ReadOnlyBufferException(); 283 int pos = position(); 284 int lim = limit(); 285 int rem = (pos <= lim) ? lim - pos : 0; 286 if (length > rem) 287 throw new BufferOverflowException(); 288 src.getChars(start, end, hb, ix(pos)); 289 position(pos + length); 290 return this; 291 } 292 293 #end[char] 294 295 public $Type$Buffer compact() { 296 #if[rw] 297 int pos = position(); 298 int rem = limit() - pos; 299 System.arraycopy(hb, ix(pos), hb, ix(0), rem); 300 position(rem); 301 limit(capacity()); 302 discardMark(); 303 return this; 304 #else[rw] 305 throw new ReadOnlyBufferException(); 306 #end[rw] 307 } 308 309 310 311 #if[byte] 312 313 byte _get(int i) { // package-private 314 return hb[i]; 315 } 316 317 void _put(int i, byte b) { // package-private 318 #if[rw] 319 hb[i] = b; 320 #else[rw] 321 throw new ReadOnlyBufferException(); 322 #end[rw] 323 } 324 325 // char 326 327 #if[rw] 328 329 public char getChar() { 330 return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 331 } 332 333 public char getChar(int i) { 334 return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 335 } 336 337 #end[rw] 338 339 public $Type$Buffer putChar(char x) { 340 #if[rw] 341 UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 342 return this; 343 #else[rw] 344 throw new ReadOnlyBufferException(); 345 #end[rw] 346 } 347 348 public $Type$Buffer putChar(int i, char x) { 349 #if[rw] 350 UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 351 return this; 352 #else[rw] 353 throw new ReadOnlyBufferException(); 354 #end[rw] 355 } 356 357 public CharBuffer asCharBuffer() { 358 int pos = position(); 359 int size = (limit() - pos) >> 1; 360 long addr = address + pos; 361 return (bigEndian 362 ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, 363 -1, 364 0, 365 size, 366 size, 367 addr)) 368 : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this, 369 -1, 370 0, 371 size, 372 size, 373 addr))); 374 } 375 376 377 // short 378 379 #if[rw] 380 381 public short getShort() { 382 return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 383 } 384 385 public short getShort(int i) { 386 return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 387 } 388 389 #end[rw] 390 391 public $Type$Buffer putShort(short x) { 392 #if[rw] 393 UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 394 return this; 395 #else[rw] 396 throw new ReadOnlyBufferException(); 397 #end[rw] 398 } 399 400 public $Type$Buffer putShort(int i, short x) { 401 #if[rw] 402 UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 403 return this; 404 #else[rw] 405 throw new ReadOnlyBufferException(); 406 #end[rw] 407 } 408 409 public ShortBuffer asShortBuffer() { 410 int pos = position(); 411 int size = (limit() - pos) >> 1; 412 long addr = address + pos; 413 return (bigEndian 414 ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, 415 -1, 416 0, 417 size, 418 size, 419 addr)) 420 : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this, 421 -1, 422 0, 423 size, 424 size, 425 addr))); 426 } 427 428 429 // int 430 431 #if[rw] 432 433 public int getInt() { 434 return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 435 } 436 437 public int getInt(int i) { 438 return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); 439 } 440 441 #end[rw] 442 443 public $Type$Buffer putInt(int x) { 444 #if[rw] 445 UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian); 446 return this; 447 #else[rw] 448 throw new ReadOnlyBufferException(); 449 #end[rw] 450 } 451 452 public $Type$Buffer putInt(int i, int x) { 453 #if[rw] 454 UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian); 455 return this; 456 #else[rw] 457 throw new ReadOnlyBufferException(); 458 #end[rw] 459 } 460 461 public IntBuffer asIntBuffer() { 462 int pos = position(); 463 int size = (limit() - pos) >> 2; 464 long addr = address + pos; 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 pos = position(); 515 int size = (limit() - pos) >> 3; 516 long addr = address + pos; 517 return (bigEndian 518 ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, 519 -1, 520 0, 521 size, 522 size, 523 addr)) 524 : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this, 525 -1, 526 0, 527 size, 528 size, 529 addr))); 530 } 531 532 533 // float 534 535 #if[rw] 536 537 public float getFloat() { 538 int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 539 return Float.intBitsToFloat(x); 540 } 541 542 public float getFloat(int i) { 543 int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); 544 return Float.intBitsToFloat(x); 545 } 546 547 #end[rw] 548 549 public $Type$Buffer putFloat(float x) { 550 #if[rw] 551 int y = Float.floatToRawIntBits(x); 552 UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian); 553 return this; 554 #else[rw] 555 throw new ReadOnlyBufferException(); 556 #end[rw] 557 } 558 559 public $Type$Buffer putFloat(int i, float x) { 560 #if[rw] 561 int y = Float.floatToRawIntBits(x); 562 UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian); 563 return this; 564 #else[rw] 565 throw new ReadOnlyBufferException(); 566 #end[rw] 567 } 568 569 public FloatBuffer asFloatBuffer() { 570 int pos = position(); 571 int size = (limit() - pos) >> 2; 572 long addr = address + pos; 573 return (bigEndian 574 ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, 575 -1, 576 0, 577 size, 578 size, 579 addr)) 580 : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this, 581 -1, 582 0, 583 size, 584 size, 585 addr))); 586 } 587 588 589 // double 590 591 #if[rw] 592 593 public double getDouble() { 594 long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); 595 return Double.longBitsToDouble(x); 596 } 597 598 public double getDouble(int i) { 599 long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); 600 return Double.longBitsToDouble(x); 601 } 602 603 #end[rw] 604 605 public $Type$Buffer putDouble(double x) { 606 #if[rw] 607 long y = Double.doubleToRawLongBits(x); 608 UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian); 609 return this; 610 #else[rw] 611 throw new ReadOnlyBufferException(); 612 #end[rw] 613 } 614 615 public $Type$Buffer putDouble(int i, double x) { 616 #if[rw] 617 long y = Double.doubleToRawLongBits(x); 618 UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian); 619 return this; 620 #else[rw] 621 throw new ReadOnlyBufferException(); 622 #end[rw] 623 } 624 625 public DoubleBuffer asDoubleBuffer() { 626 int pos = position(); 627 int size = (limit() - pos) >> 3; 628 long addr = address + pos; 629 return (bigEndian 630 ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, 631 -1, 632 0, 633 size, 634 size, 635 addr)) 636 : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this, 637 -1, 638 0, 639 size, 640 size, 641 addr))); 642 } 643 644 645 #end[byte] 646 647 648 #if[char] 649 650 String toString(int start, int end) { // package-private 651 try { 652 return new String(hb, start + offset, end - start); 653 } catch (StringIndexOutOfBoundsException x) { 654 throw new IndexOutOfBoundsException(); 655 } 656 } 657 658 659 // --- Methods to support CharSequence --- 660 661 public CharBuffer subSequence(int start, int end) { 662 int pos = position(); 663 Objects.checkFromToIndex(start, end, limit() - pos); 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 }