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