1 /* 2 * Copyright (c) 2000, 2016, 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 class Heap$Type$Buffer$RW$ 42 extends {#if[ro]?Heap}$Type$Buffer 43 { 44 // Cached array base offset 45 private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class); 46 47 // Cached array base offset 48 private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class); 49 50 // For speed these fields are actually declared in X-Buffer; 51 // these declarations are here as documentation 52 /* 53 #if[rw] 54 protected final $type$[] hb; 55 protected final int offset; 56 #end[rw] 57 */ 58 59 Heap$Type$Buffer$RW$(int cap, int lim) { // package-private 60 #if[rw] 61 super(-1, 0, lim, cap, new $type$[cap], 0); 62 /* 63 hb = new $type$[cap]; 64 offset = 0; 65 */ 66 this.address = ARRAY_BASE_OFFSET; 67 #else[rw] 68 super(cap, lim); 69 this.isReadOnly = true; 70 #end[rw] 71 } 72 73 Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private 74 #if[rw] 75 super(-1, off, off + len, buf.length, buf, 0); 76 /* 77 hb = buf; 78 offset = 0; 79 */ 80 this.address = ARRAY_BASE_OFFSET; 81 #else[rw] 82 super(buf, off, len); 83 this.isReadOnly = true; 84 #end[rw] 85 } 86 87 protected Heap$Type$Buffer$RW$($type$[] buf, 88 int mark, int pos, int lim, int cap, 89 int off) 90 { 91 #if[rw] 92 super(mark, pos, lim, cap, buf, off); 93 /* 94 hb = buf; 95 offset = off; 96 */ 97 this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE; 98 #else[rw] 99 super(buf, mark, pos, lim, cap, off); 100 this.isReadOnly = true; 101 #end[rw] 102 } 103 104 public $Type$Buffer slice() { 105 int pos = this.position(); 106 int lim = this.limit(); 107 int rem = (pos <= lim ? lim - pos : 0); 108 return new Heap$Type$Buffer$RW$(hb, 109 -1, 110 0, 111 rem, 112 rem, 113 pos + offset); 114 } 115 116 #if[byte] 117 $Type$Buffer slice(int pos, int lim) { 118 assert (pos >= 0); 119 assert (pos <= lim); 120 int rem = lim - pos; 121 return new Heap$Type$Buffer$RW$(hb, 122 -1, 123 0, 124 rem, 125 rem, 126 pos + offset); 127 } 128 #end[byte] 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); 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); 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 checkBounds(offset, length, dst.length); 180 int pos = position(); 181 if (length > limit() - pos) 182 throw new BufferUnderflowException(); 183 System.arraycopy(hb, ix(pos), dst, offset, length); 184 position(pos + length); 185 return this; 186 } 187 188 public boolean isDirect() { 189 return false; 190 } 191 192 #end[rw] 193 194 public boolean isReadOnly() { 195 return {#if[rw]?false:true}; 196 } 197 198 public $Type$Buffer put($type$ x) { 199 #if[rw] 200 hb[ix(nextPutIndex())] = x; 201 return this; 202 #else[rw] 203 throw new ReadOnlyBufferException(); 204 #end[rw] 205 } 206 207 public $Type$Buffer put(int i, $type$ x) { 208 #if[rw] 209 hb[ix(checkIndex(i))] = x; 210 return this; 211 #else[rw] 212 throw new ReadOnlyBufferException(); 213 #end[rw] 214 } 215 216 public $Type$Buffer put($type$[] src, int offset, int length) { 217 #if[rw] 218 checkBounds(offset, length, src.length); 219 int pos = position(); 220 if (length > limit() - pos) 221 throw new BufferOverflowException(); 222 System.arraycopy(src, offset, hb, ix(pos), length); 223 position(pos + length); 224 return this; 225 #else[rw] 226 throw new ReadOnlyBufferException(); 227 #end[rw] 228 } 229 230 public $Type$Buffer put($Type$Buffer src) { 231 #if[rw] 232 if (src instanceof Heap$Type$Buffer) { 233 if (src == this) 234 throw createSameBufferException(); 235 Heap$Type$Buffer sb = (Heap$Type$Buffer)src; 236 int pos = position(); 237 int sbpos = sb.position(); 238 int n = sb.limit() - sbpos; 239 if (n > limit() - pos) 240 throw new BufferOverflowException(); 241 System.arraycopy(sb.hb, sb.ix(sbpos), 242 hb, ix(pos), n); 243 sb.position(sbpos + n); 244 position(pos + n); 245 } else if (src.isDirect()) { 246 int n = src.remaining(); 247 int pos = position(); 248 if (n > limit() - pos) 249 throw new BufferOverflowException(); 250 src.get(hb, ix(pos), n); 251 position(pos + n); 252 } else { 253 super.put(src); 254 } 255 return this; 256 #else[rw] 257 throw new ReadOnlyBufferException(); 258 #end[rw] 259 } 260 261 public $Type$Buffer compact() { 262 #if[rw] 263 int pos = position(); 264 int rem = limit() - pos; 265 System.arraycopy(hb, ix(pos), hb, ix(0), rem); 266 position(rem); 267 limit(capacity()); 268 discardMark(); 269 return this; 270 #else[rw] 271 throw new ReadOnlyBufferException(); 272 #end[rw] 273 } 274 275 276 277 #if[byte] 278 279 byte _get(int i) { // package-private 280 return hb[i]; 281 } 282 283 void _put(int i, byte b) { // package-private 284 #if[rw] 285 hb[i] = b; 286 #else[rw] 287 throw new ReadOnlyBufferException(); 288 #end[rw] 289 } 290 291 // char 292 293 #if[rw] 294 295 public char getChar() { 296 return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 297 } 298 299 public char getChar(int i) { 300 return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 301 } 302 303 #end[rw] 304 305 public $Type$Buffer putChar(char x) { 306 #if[rw] 307 UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 308 return this; 309 #else[rw] 310 throw new ReadOnlyBufferException(); 311 #end[rw] 312 } 313 314 public $Type$Buffer putChar(int i, char x) { 315 #if[rw] 316 UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 317 return this; 318 #else[rw] 319 throw new ReadOnlyBufferException(); 320 #end[rw] 321 } 322 323 public CharBuffer asCharBuffer() { 324 int pos = position(); 325 int size = (limit() - pos) >> 1; 326 long addr = address + pos; 327 return (bigEndian 328 ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, 329 -1, 330 0, 331 size, 332 size, 333 addr)) 334 : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this, 335 -1, 336 0, 337 size, 338 size, 339 addr))); 340 } 341 342 343 // short 344 345 #if[rw] 346 347 public short getShort() { 348 return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); 349 } 350 351 public short getShort(int i) { 352 return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); 353 } 354 355 #end[rw] 356 357 public $Type$Buffer putShort(short x) { 358 #if[rw] 359 UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); 360 return this; 361 #else[rw] 362 throw new ReadOnlyBufferException(); 363 #end[rw] 364 } 365 366 public $Type$Buffer putShort(int i, short x) { 367 #if[rw] 368 UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); 369 return this; 370 #else[rw] 371 throw new ReadOnlyBufferException(); 372 #end[rw] 373 } 374 375 public ShortBuffer asShortBuffer() { 376 int pos = position(); 377 int size = (limit() - pos) >> 1; 378 long addr = address + pos; 379 return (bigEndian 380 ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, 381 -1, 382 0, 383 size, 384 size, 385 addr)) 386 : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this, 387 -1, 388 0, 389 size, 390 size, 391 addr))); 392 } 393 394 395 // int 396 397 #if[rw] 398 399 public int getInt() { 400 return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 401 } 402 403 public int getInt(int i) { 404 return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); 405 } 406 407 #end[rw] 408 409 public $Type$Buffer putInt(int x) { 410 #if[rw] 411 UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian); 412 return this; 413 #else[rw] 414 throw new ReadOnlyBufferException(); 415 #end[rw] 416 } 417 418 public $Type$Buffer putInt(int i, int x) { 419 #if[rw] 420 UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian); 421 return this; 422 #else[rw] 423 throw new ReadOnlyBufferException(); 424 #end[rw] 425 } 426 427 public IntBuffer asIntBuffer() { 428 int pos = position(); 429 int size = (limit() - pos) >> 2; 430 long addr = address + pos; 431 return (bigEndian 432 ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this, 433 -1, 434 0, 435 size, 436 size, 437 addr)) 438 : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this, 439 -1, 440 0, 441 size, 442 size, 443 addr))); 444 } 445 446 447 // long 448 449 #if[rw] 450 451 public long getLong() { 452 return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); 453 } 454 455 public long getLong(int i) { 456 return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); 457 } 458 459 #end[rw] 460 461 public $Type$Buffer putLong(long x) { 462 #if[rw] 463 UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian); 464 return this; 465 #else[rw] 466 throw new ReadOnlyBufferException(); 467 #end[rw] 468 } 469 470 public $Type$Buffer putLong(int i, long x) { 471 #if[rw] 472 UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian); 473 return this; 474 #else[rw] 475 throw new ReadOnlyBufferException(); 476 #end[rw] 477 } 478 479 public LongBuffer asLongBuffer() { 480 int pos = position(); 481 int size = (limit() - pos) >> 3; 482 long addr = address + pos; 483 return (bigEndian 484 ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, 485 -1, 486 0, 487 size, 488 size, 489 addr)) 490 : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this, 491 -1, 492 0, 493 size, 494 size, 495 addr))); 496 } 497 498 499 // float 500 501 #if[rw] 502 503 public float getFloat() { 504 int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); 505 return Float.intBitsToFloat(x); 506 } 507 508 public float getFloat(int i) { 509 int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); 510 return Float.intBitsToFloat(x); 511 } 512 513 #end[rw] 514 515 public $Type$Buffer putFloat(float x) { 516 #if[rw] 517 int y = Float.floatToRawIntBits(x); 518 UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian); 519 return this; 520 #else[rw] 521 throw new ReadOnlyBufferException(); 522 #end[rw] 523 } 524 525 public $Type$Buffer putFloat(int i, float x) { 526 #if[rw] 527 int y = Float.floatToRawIntBits(x); 528 UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian); 529 return this; 530 #else[rw] 531 throw new ReadOnlyBufferException(); 532 #end[rw] 533 } 534 535 public FloatBuffer asFloatBuffer() { 536 int pos = position(); 537 int size = (limit() - pos) >> 2; 538 long addr = address + pos; 539 return (bigEndian 540 ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, 541 -1, 542 0, 543 size, 544 size, 545 addr)) 546 : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this, 547 -1, 548 0, 549 size, 550 size, 551 addr))); 552 } 553 554 555 // double 556 557 #if[rw] 558 559 public double getDouble() { 560 long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); 561 return Double.longBitsToDouble(x); 562 } 563 564 public double getDouble(int i) { 565 long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); 566 return Double.longBitsToDouble(x); 567 } 568 569 #end[rw] 570 571 public $Type$Buffer putDouble(double x) { 572 #if[rw] 573 long y = Double.doubleToRawLongBits(x); 574 UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian); 575 return this; 576 #else[rw] 577 throw new ReadOnlyBufferException(); 578 #end[rw] 579 } 580 581 public $Type$Buffer putDouble(int i, double x) { 582 #if[rw] 583 long y = Double.doubleToRawLongBits(x); 584 UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian); 585 return this; 586 #else[rw] 587 throw new ReadOnlyBufferException(); 588 #end[rw] 589 } 590 591 public DoubleBuffer asDoubleBuffer() { 592 int pos = position(); 593 int size = (limit() - pos) >> 3; 594 long addr = address + pos; 595 return (bigEndian 596 ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, 597 -1, 598 0, 599 size, 600 size, 601 addr)) 602 : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this, 603 -1, 604 0, 605 size, 606 size, 607 addr))); 608 } 609 610 611 #end[byte] 612 613 614 #if[char] 615 616 String toString(int start, int end) { // package-private 617 try { 618 return new String(hb, start + offset, end - start); 619 } catch (StringIndexOutOfBoundsException x) { 620 throw new IndexOutOfBoundsException(); 621 } 622 } 623 624 625 // --- Methods to support CharSequence --- 626 627 public CharBuffer subSequence(int start, int end) { 628 if ((start < 0) 629 || (end > length()) 630 || (start > end)) 631 throw new IndexOutOfBoundsException(); 632 int pos = position(); 633 return new HeapCharBuffer$RW$(hb, 634 -1, 635 pos + start, 636 pos + end, 637 capacity(), 638 offset); 639 } 640 641 #end[char] 642 643 644 #if[!byte] 645 646 public ByteOrder order() { 647 return ByteOrder.nativeOrder(); 648 } 649 #end[!byte] 650 #if[char] 651 652 ByteOrder charRegionOrder() { 653 return order(); 654 } 655 #end[char] 656 }