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