1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 28 package java.nio; 29 30 31 import libcore.io.Memory; 32 33 /** 34 * A read/write HeapByteBuffer. 35 */ 36 37 final class HeapByteBuffer extends ByteBuffer { 38 39 // For speed these fields are actually declared in X-Buffer; 40 // these declarations are here as documentation 41 /* 42 43 protected final byte[] hb; 44 protected final int offset; 45 46 */ 47 HeapByteBuffer(int cap, int lim)48 HeapByteBuffer(int cap, int lim) { // packag-private 49 this(cap, lim, false); 50 } 51 52 HeapByteBuffer(int cap, int lim, boolean isReadOnly)53 private HeapByteBuffer(int cap, int lim, boolean isReadOnly) { 54 super(-1, 0, lim, cap, new byte[cap], 0); 55 this.isReadOnly = isReadOnly; 56 } 57 HeapByteBuffer(byte[] buf, int off, int len)58 HeapByteBuffer(byte[] buf, int off, int len) { // package-private 59 this(buf, off, len, false); 60 } 61 HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly)62 private HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) { 63 super(-1, off, off + len, buf.length, buf, 0); 64 this.isReadOnly = isReadOnly; 65 } 66 HeapByteBuffer(byte[] buf, int mark, int pos, int lim, int cap, int off, boolean isReadOnly)67 private HeapByteBuffer(byte[] buf, int mark, int pos, int lim, int cap, int off, 68 boolean isReadOnly) { 69 super(mark, pos, lim, cap, buf, off); 70 this.isReadOnly = isReadOnly; 71 } 72 73 @Override slice()74 public ByteBuffer slice() { 75 return new HeapByteBuffer(hb, 76 -1, 77 0, 78 remaining(), 79 remaining(), 80 position() + offset, 81 isReadOnly); 82 } 83 slice(int pos, int lim)84 ByteBuffer slice(int pos, int lim) { 85 assert (pos >= 0); 86 assert (pos <= lim); 87 int rem = lim - pos; 88 return new HeapByteBuffer(hb, 89 -1, 90 0, 91 rem, 92 rem, 93 pos + offset, 94 isReadOnly); 95 } 96 97 @Override duplicate()98 public ByteBuffer duplicate() { 99 return new HeapByteBuffer(hb, 100 markValue(), 101 position(), 102 limit(), 103 capacity(), 104 offset, 105 isReadOnly); 106 } 107 108 @Override asReadOnlyBuffer()109 public ByteBuffer asReadOnlyBuffer() { 110 return new HeapByteBuffer(hb, 111 this.markValue(), 112 this.position(), 113 this.limit(), 114 this.capacity(), 115 offset, true); 116 } 117 ix(int i)118 protected int ix(int i) { 119 return i + offset; 120 } 121 122 @Override get()123 public byte get() { 124 return hb[ix(nextGetIndex())]; 125 } 126 127 @Override get(int i)128 public byte get(int i) { 129 return hb[ix(checkIndex(i))]; 130 } 131 132 @Override get(byte[] dst, int offset, int length)133 public ByteBuffer get(byte[] dst, int offset, int length) { 134 checkBounds(offset, length, dst.length); 135 if (length > remaining()) 136 throw new BufferUnderflowException(); 137 System.arraycopy(hb, ix(position()), dst, offset, length); 138 position(position() + length); 139 return this; 140 } 141 142 @Override isDirect()143 public boolean isDirect() { 144 return false; 145 } 146 147 @Override isReadOnly()148 public boolean isReadOnly() { 149 return isReadOnly; 150 } 151 152 @Override put(byte x)153 public ByteBuffer put(byte x) { 154 if (isReadOnly) { 155 throw new ReadOnlyBufferException(); 156 } 157 hb[ix(nextPutIndex())] = x; 158 return this; 159 } 160 161 @Override put(int i, byte x)162 public ByteBuffer put(int i, byte x) { 163 if (isReadOnly) { 164 throw new ReadOnlyBufferException(); 165 } 166 hb[ix(checkIndex(i))] = x; 167 return this; 168 } 169 170 @Override put(byte[] src, int offset, int length)171 public ByteBuffer put(byte[] src, int offset, int length) { 172 if (isReadOnly) { 173 throw new ReadOnlyBufferException(); 174 } 175 checkBounds(offset, length, src.length); 176 if (length > remaining()) 177 throw new BufferOverflowException(); 178 System.arraycopy(src, offset, hb, ix(position()), length); 179 position(position() + length); 180 return this; 181 } 182 183 @Override compact()184 public ByteBuffer compact() { 185 if (isReadOnly) { 186 throw new ReadOnlyBufferException(); 187 } 188 System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); 189 position(remaining()); 190 limit(capacity()); 191 discardMark(); 192 return this; 193 } 194 195 @Override _get(int i)196 byte _get(int i) { // package-private 197 return hb[i]; 198 } 199 200 @Override _put(int i, byte b)201 void _put(int i, byte b) { // package-private 202 if (isReadOnly) { 203 throw new ReadOnlyBufferException(); 204 } 205 hb[i] = b; 206 } 207 208 @Override getChar()209 public char getChar() { 210 return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian); 211 } 212 213 @Override getChar(int i)214 public char getChar(int i) { 215 return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian); 216 } 217 218 @Override getCharUnchecked(int i)219 char getCharUnchecked(int i) { 220 return Bits.getChar(this, ix(i), bigEndian); 221 } 222 223 @Override getUnchecked(int pos, char[] dst, int dstOffset, int length)224 void getUnchecked(int pos, char[] dst, int dstOffset, int length) { 225 Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder); 226 } 227 228 @Override putChar(char x)229 public ByteBuffer putChar(char x) { 230 if (isReadOnly) { 231 throw new ReadOnlyBufferException(); 232 } 233 Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian); 234 return this; 235 } 236 237 @Override putChar(int i, char x)238 public ByteBuffer putChar(int i, char x) { 239 if (isReadOnly) { 240 throw new ReadOnlyBufferException(); 241 } 242 Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian); 243 return this; 244 } 245 246 @Override putCharUnchecked(int i, char x)247 void putCharUnchecked(int i, char x) { 248 Bits.putChar(this, ix(i), x, bigEndian); 249 } 250 251 @Override putUnchecked(int pos, char[] src, int srcOffset, int length)252 void putUnchecked(int pos, char[] src, int srcOffset, int length) { 253 Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder); 254 } 255 256 @Override asCharBuffer()257 public CharBuffer asCharBuffer() { 258 int size = this.remaining() >> 1; 259 int off = position(); 260 return new ByteBufferAsCharBuffer(this, 261 -1, 262 0, 263 size, 264 size, 265 off, 266 order()); 267 } 268 269 @Override getShort()270 public short getShort() { 271 return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian); 272 } 273 274 @Override getShort(int i)275 public short getShort(int i) { 276 return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian); 277 } 278 279 @Override getShortUnchecked(int i)280 short getShortUnchecked(int i) { 281 return Bits.getShort(this, ix(i), bigEndian); 282 } 283 284 @Override getUnchecked(int pos, short[] dst, int dstOffset, int length)285 void getUnchecked(int pos, short[] dst, int dstOffset, int length) { 286 Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder); 287 } 288 289 @Override putShort(short x)290 public ByteBuffer putShort(short x) { 291 if (isReadOnly) { 292 throw new ReadOnlyBufferException(); 293 } 294 Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian); 295 return this; 296 } 297 298 @Override putShort(int i, short x)299 public ByteBuffer putShort(int i, short x) { 300 if (isReadOnly) { 301 throw new ReadOnlyBufferException(); 302 } 303 Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian); 304 return this; 305 } 306 307 @Override putShortUnchecked(int i, short x)308 void putShortUnchecked(int i, short x) { 309 Bits.putShort(this, ix(i), x, bigEndian); 310 } 311 312 @Override putUnchecked(int pos, short[] src, int srcOffset, int length)313 void putUnchecked(int pos, short[] src, int srcOffset, int length) { 314 Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder); 315 } 316 317 @Override asShortBuffer()318 public ShortBuffer asShortBuffer() { 319 int size = this.remaining() >> 1; 320 int off = position(); 321 return new ByteBufferAsShortBuffer(this, 322 -1, 323 0, 324 size, 325 size, 326 off, 327 order()); 328 } 329 330 @Override getInt()331 public int getInt() { 332 return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian); 333 } 334 335 @Override getInt(int i)336 public int getInt(int i) { 337 return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian); 338 } 339 340 @Override getIntUnchecked(int i)341 int getIntUnchecked(int i) { 342 return Bits.getInt(this, ix(i), bigEndian); 343 } 344 345 @Override getUnchecked(int pos, int[] dst, int dstOffset, int length)346 void getUnchecked(int pos, int[] dst, int dstOffset, int length) { 347 Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder); 348 } 349 350 @Override putInt(int x)351 public ByteBuffer putInt(int x) { 352 if (isReadOnly) { 353 throw new ReadOnlyBufferException(); 354 } 355 Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian); 356 return this; 357 } 358 359 @Override putInt(int i, int x)360 public ByteBuffer putInt(int i, int x) { 361 if (isReadOnly) { 362 throw new ReadOnlyBufferException(); 363 } 364 Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian); 365 return this; 366 } 367 368 @Override putIntUnchecked(int i, int x)369 void putIntUnchecked(int i, int x) { 370 Bits.putInt(this, ix(i), x, bigEndian); 371 } 372 373 @Override putUnchecked(int pos, int[] src, int srcOffset, int length)374 void putUnchecked(int pos, int[] src, int srcOffset, int length) { 375 Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder); 376 } 377 378 @Override asIntBuffer()379 public IntBuffer asIntBuffer() { 380 int size = this.remaining() >> 2; 381 int off = position(); 382 383 return new ByteBufferAsIntBuffer(this, 384 -1, 385 0, 386 size, 387 size, 388 off, 389 order()); 390 } 391 392 @Override getLong()393 public long getLong() { 394 return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian); 395 } 396 397 @Override getLong(int i)398 public long getLong(int i) { 399 return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian); 400 } 401 402 @Override getLongUnchecked(int i)403 long getLongUnchecked(int i) { 404 return Bits.getLong(this, ix(i), bigEndian); 405 } 406 407 @Override getUnchecked(int pos, long[] dst, int dstOffset, int length)408 void getUnchecked(int pos, long[] dst, int dstOffset, int length) { 409 Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder); 410 } 411 412 @Override putLong(long x)413 public ByteBuffer putLong(long x) { 414 if (isReadOnly) { 415 throw new ReadOnlyBufferException(); 416 } 417 Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian); 418 return this; 419 } 420 421 @Override putLong(int i, long x)422 public ByteBuffer putLong(int i, long x) { 423 if (isReadOnly) { 424 throw new ReadOnlyBufferException(); 425 } 426 Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian); 427 return this; 428 } 429 430 @Override putLongUnchecked(int i, long x)431 void putLongUnchecked(int i, long x) { 432 Bits.putLong(this, ix(i), x, bigEndian); 433 } 434 435 @Override putUnchecked(int pos, long[] src, int srcOffset, int length)436 void putUnchecked(int pos, long[] src, int srcOffset, int length) { 437 Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder); 438 } 439 440 @Override asLongBuffer()441 public LongBuffer asLongBuffer() { 442 int size = this.remaining() >> 3; 443 int off = position(); 444 return new ByteBufferAsLongBuffer(this, 445 -1, 446 0, 447 size, 448 size, 449 off, 450 order()); 451 } 452 453 @Override getFloat()454 public float getFloat() { 455 return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian); 456 } 457 458 @Override getFloat(int i)459 public float getFloat(int i) { 460 return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian); 461 } 462 463 @Override getFloatUnchecked(int i)464 float getFloatUnchecked(int i) { 465 return Bits.getFloat(this, ix(i), bigEndian); 466 } 467 468 @Override getUnchecked(int pos, float[] dst, int dstOffset, int length)469 void getUnchecked(int pos, float[] dst, int dstOffset, int length) { 470 Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder); 471 } 472 473 @Override putFloat(float x)474 public ByteBuffer putFloat(float x) { 475 if (isReadOnly) { 476 throw new ReadOnlyBufferException(); 477 } 478 Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian); 479 return this; 480 } 481 482 @Override putFloat(int i, float x)483 public ByteBuffer putFloat(int i, float x) { 484 if (isReadOnly) { 485 throw new ReadOnlyBufferException(); 486 } 487 Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian); 488 return this; 489 } 490 491 @Override putFloatUnchecked(int i, float x)492 void putFloatUnchecked(int i, float x) { 493 Bits.putFloat(this, ix(i), x, bigEndian); 494 } 495 496 @Override putUnchecked(int pos, float[] src, int srcOffset, int length)497 void putUnchecked(int pos, float[] src, int srcOffset, int length) { 498 Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder); 499 } 500 501 @Override asFloatBuffer()502 public FloatBuffer asFloatBuffer() { 503 int size = this.remaining() >> 2; 504 int off = position(); 505 return new ByteBufferAsFloatBuffer(this, 506 -1, 507 0, 508 size, 509 size, 510 off, 511 order()); 512 } 513 514 @Override getDouble()515 public double getDouble() { 516 return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian); 517 } 518 519 @Override getDouble(int i)520 public double getDouble(int i) { 521 return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian); 522 } 523 524 @Override getDoubleUnchecked(int i)525 double getDoubleUnchecked(int i) { 526 return Bits.getDouble(this, ix(i), bigEndian); 527 } 528 529 @Override getUnchecked(int pos, double[] dst, int dstOffset, int length)530 void getUnchecked(int pos, double[] dst, int dstOffset, int length) { 531 Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder); 532 } 533 534 @Override putDouble(double x)535 public ByteBuffer putDouble(double x) { 536 if (isReadOnly) { 537 throw new ReadOnlyBufferException(); 538 } 539 Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian); 540 return this; 541 } 542 543 @Override putDouble(int i, double x)544 public ByteBuffer putDouble(int i, double x) { 545 if (isReadOnly) { 546 throw new ReadOnlyBufferException(); 547 } 548 Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian); 549 return this; 550 } 551 552 @Override putDoubleUnchecked(int i, double x)553 void putDoubleUnchecked(int i, double x) { 554 Bits.putDouble(this, ix(i), x, bigEndian); 555 } 556 557 @Override putUnchecked(int pos, double[] src, int srcOffset, int length)558 void putUnchecked(int pos, double[] src, int srcOffset, int length) { 559 Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder); 560 } 561 562 @Override asDoubleBuffer()563 public DoubleBuffer asDoubleBuffer() { 564 int size = this.remaining() >> 3; 565 int off = position(); 566 return new ByteBufferAsDoubleBuffer(this, 567 -1, 568 0, 569 size, 570 size, 571 off, 572 order()); 573 } 574 } 575