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