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 84 @Override duplicate()85 public ByteBuffer duplicate() { 86 return new HeapByteBuffer(hb, 87 markValue(), 88 position(), 89 limit(), 90 capacity(), 91 offset, 92 isReadOnly); 93 } 94 95 @Override asReadOnlyBuffer()96 public ByteBuffer asReadOnlyBuffer() { 97 return new HeapByteBuffer(hb, 98 this.markValue(), 99 this.position(), 100 this.limit(), 101 this.capacity(), 102 offset, true); 103 } 104 ix(int i)105 protected int ix(int i) { 106 return i + offset; 107 } 108 109 @Override get()110 public byte get() { 111 return hb[ix(nextGetIndex())]; 112 } 113 114 @Override get(int i)115 public byte get(int i) { 116 return hb[ix(checkIndex(i))]; 117 } 118 119 @Override get(byte[] dst, int offset, int length)120 public ByteBuffer get(byte[] dst, int offset, int length) { 121 checkBounds(offset, length, dst.length); 122 if (length > remaining()) 123 throw new BufferUnderflowException(); 124 System.arraycopy(hb, ix(position()), dst, offset, length); 125 position(position() + length); 126 return this; 127 } 128 129 @Override isDirect()130 public boolean isDirect() { 131 return false; 132 } 133 134 @Override isReadOnly()135 public boolean isReadOnly() { 136 return isReadOnly; 137 } 138 139 @Override put(byte x)140 public ByteBuffer put(byte x) { 141 if (isReadOnly) { 142 throw new ReadOnlyBufferException(); 143 } 144 hb[ix(nextPutIndex())] = x; 145 return this; 146 } 147 148 @Override put(int i, byte x)149 public ByteBuffer put(int i, byte x) { 150 if (isReadOnly) { 151 throw new ReadOnlyBufferException(); 152 } 153 hb[ix(checkIndex(i))] = x; 154 return this; 155 } 156 157 @Override put(byte[] src, int offset, int length)158 public ByteBuffer put(byte[] src, int offset, int length) { 159 if (isReadOnly) { 160 throw new ReadOnlyBufferException(); 161 } 162 checkBounds(offset, length, src.length); 163 if (length > remaining()) 164 throw new BufferOverflowException(); 165 System.arraycopy(src, offset, hb, ix(position()), length); 166 position(position() + length); 167 return this; 168 } 169 170 @Override compact()171 public ByteBuffer compact() { 172 if (isReadOnly) { 173 throw new ReadOnlyBufferException(); 174 } 175 System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); 176 position(remaining()); 177 limit(capacity()); 178 discardMark(); 179 return this; 180 } 181 182 @Override _get(int i)183 byte _get(int i) { // package-private 184 return hb[i]; 185 } 186 187 @Override _put(int i, byte b)188 void _put(int i, byte b) { // package-private 189 if (isReadOnly) { 190 throw new ReadOnlyBufferException(); 191 } 192 hb[i] = b; 193 } 194 195 @Override getChar()196 public char getChar() { 197 return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian); 198 } 199 200 @Override getChar(int i)201 public char getChar(int i) { 202 return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian); 203 } 204 205 @Override getCharUnchecked(int i)206 char getCharUnchecked(int i) { 207 return Bits.getChar(this, ix(i), bigEndian); 208 } 209 210 @Override getUnchecked(int pos, char[] dst, int dstOffset, int length)211 void getUnchecked(int pos, char[] dst, int dstOffset, int length) { 212 Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder); 213 } 214 215 @Override putChar(char x)216 public ByteBuffer putChar(char x) { 217 if (isReadOnly) { 218 throw new ReadOnlyBufferException(); 219 } 220 Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian); 221 return this; 222 } 223 224 @Override putChar(int i, char x)225 public ByteBuffer putChar(int i, char x) { 226 if (isReadOnly) { 227 throw new ReadOnlyBufferException(); 228 } 229 Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian); 230 return this; 231 } 232 233 @Override putCharUnchecked(int i, char x)234 void putCharUnchecked(int i, char x) { 235 Bits.putChar(this, ix(i), x, bigEndian); 236 } 237 238 @Override putUnchecked(int pos, char[] src, int srcOffset, int length)239 void putUnchecked(int pos, char[] src, int srcOffset, int length) { 240 Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder); 241 } 242 243 @Override asCharBuffer()244 public CharBuffer asCharBuffer() { 245 int size = this.remaining() >> 1; 246 int off = position(); 247 return new ByteBufferAsCharBuffer(this, 248 -1, 249 0, 250 size, 251 size, 252 off, 253 order()); 254 } 255 256 @Override getShort()257 public short getShort() { 258 return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian); 259 } 260 261 @Override getShort(int i)262 public short getShort(int i) { 263 return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian); 264 } 265 266 @Override getShortUnchecked(int i)267 short getShortUnchecked(int i) { 268 return Bits.getShort(this, ix(i), bigEndian); 269 } 270 271 @Override getUnchecked(int pos, short[] dst, int dstOffset, int length)272 void getUnchecked(int pos, short[] dst, int dstOffset, int length) { 273 Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder); 274 } 275 276 @Override putShort(short x)277 public ByteBuffer putShort(short x) { 278 if (isReadOnly) { 279 throw new ReadOnlyBufferException(); 280 } 281 Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian); 282 return this; 283 } 284 285 @Override putShort(int i, short x)286 public ByteBuffer putShort(int i, short x) { 287 if (isReadOnly) { 288 throw new ReadOnlyBufferException(); 289 } 290 Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian); 291 return this; 292 } 293 294 @Override putShortUnchecked(int i, short x)295 void putShortUnchecked(int i, short x) { 296 Bits.putShort(this, ix(i), x, bigEndian); 297 } 298 299 @Override putUnchecked(int pos, short[] src, int srcOffset, int length)300 void putUnchecked(int pos, short[] src, int srcOffset, int length) { 301 Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder); 302 } 303 304 @Override asShortBuffer()305 public ShortBuffer asShortBuffer() { 306 int size = this.remaining() >> 1; 307 int off = position(); 308 return new ByteBufferAsShortBuffer(this, 309 -1, 310 0, 311 size, 312 size, 313 off, 314 order()); 315 } 316 317 @Override getInt()318 public int getInt() { 319 return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian); 320 } 321 322 @Override getInt(int i)323 public int getInt(int i) { 324 return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian); 325 } 326 327 @Override getIntUnchecked(int i)328 int getIntUnchecked(int i) { 329 return Bits.getInt(this, ix(i), bigEndian); 330 } 331 332 @Override getUnchecked(int pos, int[] dst, int dstOffset, int length)333 void getUnchecked(int pos, int[] dst, int dstOffset, int length) { 334 Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder); 335 } 336 337 @Override putInt(int x)338 public ByteBuffer putInt(int x) { 339 if (isReadOnly) { 340 throw new ReadOnlyBufferException(); 341 } 342 Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian); 343 return this; 344 } 345 346 @Override putInt(int i, int x)347 public ByteBuffer putInt(int i, int x) { 348 if (isReadOnly) { 349 throw new ReadOnlyBufferException(); 350 } 351 Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian); 352 return this; 353 } 354 355 @Override putIntUnchecked(int i, int x)356 void putIntUnchecked(int i, int x) { 357 Bits.putInt(this, ix(i), x, bigEndian); 358 } 359 360 @Override putUnchecked(int pos, int[] src, int srcOffset, int length)361 void putUnchecked(int pos, int[] src, int srcOffset, int length) { 362 Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder); 363 } 364 365 @Override asIntBuffer()366 public IntBuffer asIntBuffer() { 367 int size = this.remaining() >> 2; 368 int off = position(); 369 370 return new ByteBufferAsIntBuffer(this, 371 -1, 372 0, 373 size, 374 size, 375 off, 376 order()); 377 } 378 379 @Override getLong()380 public long getLong() { 381 return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian); 382 } 383 384 @Override getLong(int i)385 public long getLong(int i) { 386 return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian); 387 } 388 389 @Override getLongUnchecked(int i)390 long getLongUnchecked(int i) { 391 return Bits.getLong(this, ix(i), bigEndian); 392 } 393 394 @Override getUnchecked(int pos, long[] dst, int dstOffset, int length)395 void getUnchecked(int pos, long[] dst, int dstOffset, int length) { 396 Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder); 397 } 398 399 @Override putLong(long x)400 public ByteBuffer putLong(long x) { 401 if (isReadOnly) { 402 throw new ReadOnlyBufferException(); 403 } 404 Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian); 405 return this; 406 } 407 408 @Override putLong(int i, long x)409 public ByteBuffer putLong(int i, long x) { 410 if (isReadOnly) { 411 throw new ReadOnlyBufferException(); 412 } 413 Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian); 414 return this; 415 } 416 417 @Override putLongUnchecked(int i, long x)418 void putLongUnchecked(int i, long x) { 419 Bits.putLong(this, ix(i), x, bigEndian); 420 } 421 422 @Override putUnchecked(int pos, long[] src, int srcOffset, int length)423 void putUnchecked(int pos, long[] src, int srcOffset, int length) { 424 Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder); 425 } 426 427 @Override asLongBuffer()428 public LongBuffer asLongBuffer() { 429 int size = this.remaining() >> 3; 430 int off = position(); 431 return new ByteBufferAsLongBuffer(this, 432 -1, 433 0, 434 size, 435 size, 436 off, 437 order()); 438 } 439 440 @Override getFloat()441 public float getFloat() { 442 return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian); 443 } 444 445 @Override getFloat(int i)446 public float getFloat(int i) { 447 return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian); 448 } 449 450 @Override getFloatUnchecked(int i)451 float getFloatUnchecked(int i) { 452 return Bits.getFloat(this, ix(i), bigEndian); 453 } 454 455 @Override getUnchecked(int pos, float[] dst, int dstOffset, int length)456 void getUnchecked(int pos, float[] dst, int dstOffset, int length) { 457 Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder); 458 } 459 460 @Override putFloat(float x)461 public ByteBuffer putFloat(float x) { 462 if (isReadOnly) { 463 throw new ReadOnlyBufferException(); 464 } 465 Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian); 466 return this; 467 } 468 469 @Override putFloat(int i, float x)470 public ByteBuffer putFloat(int i, float x) { 471 if (isReadOnly) { 472 throw new ReadOnlyBufferException(); 473 } 474 Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian); 475 return this; 476 } 477 478 @Override putFloatUnchecked(int i, float x)479 void putFloatUnchecked(int i, float x) { 480 Bits.putFloat(this, ix(i), x, bigEndian); 481 } 482 483 @Override putUnchecked(int pos, float[] src, int srcOffset, int length)484 void putUnchecked(int pos, float[] src, int srcOffset, int length) { 485 Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder); 486 } 487 488 @Override asFloatBuffer()489 public FloatBuffer asFloatBuffer() { 490 int size = this.remaining() >> 2; 491 int off = position(); 492 return new ByteBufferAsFloatBuffer(this, 493 -1, 494 0, 495 size, 496 size, 497 off, 498 order()); 499 } 500 501 @Override getDouble()502 public double getDouble() { 503 return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian); 504 } 505 506 @Override getDouble(int i)507 public double getDouble(int i) { 508 return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian); 509 } 510 511 @Override getDoubleUnchecked(int i)512 double getDoubleUnchecked(int i) { 513 return Bits.getDouble(this, ix(i), bigEndian); 514 } 515 516 @Override getUnchecked(int pos, double[] dst, int dstOffset, int length)517 void getUnchecked(int pos, double[] dst, int dstOffset, int length) { 518 Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder); 519 } 520 521 @Override putDouble(double x)522 public ByteBuffer putDouble(double x) { 523 if (isReadOnly) { 524 throw new ReadOnlyBufferException(); 525 } 526 Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian); 527 return this; 528 } 529 530 @Override putDouble(int i, double x)531 public ByteBuffer putDouble(int i, double x) { 532 if (isReadOnly) { 533 throw new ReadOnlyBufferException(); 534 } 535 Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian); 536 return this; 537 } 538 539 @Override putDoubleUnchecked(int i, double x)540 void putDoubleUnchecked(int i, double x) { 541 Bits.putDouble(this, ix(i), x, bigEndian); 542 } 543 544 @Override putUnchecked(int pos, double[] src, int srcOffset, int length)545 void putUnchecked(int pos, double[] src, int srcOffset, int length) { 546 Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder); 547 } 548 549 @Override asDoubleBuffer()550 public DoubleBuffer asDoubleBuffer() { 551 int size = this.remaining() >> 3; 552 int off = position(); 553 return new ByteBufferAsDoubleBuffer(this, 554 -1, 555 0, 556 size, 557 size, 558 off, 559 order()); 560 } 561 } 562