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