HeapByteBuffer.java revision 490d8356c6d541aa296c5bf19b872473cd78deb8
1/* 2 * Copyright (c) 2000, 2008, 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 27package java.nio; 28 29 30/** 31 * A read/write HeapByteBuffer. 32 */ 33 34class HeapByteBuffer extends ByteBuffer { 35 36 // For speed these fields are actually declared in X-Buffer; 37 // these declarations are here as documentation 38 /* 39 40 protected final byte[] hb; 41 protected final int offset; 42 43 */ 44 45 private final boolean isReadOnly; 46 47 HeapByteBuffer(int cap, int lim) { // packag-private 48 this(cap, lim, false); 49 } 50 51 52 HeapByteBuffer(int cap, int lim, boolean isReadOnly) { // package-private 53 super(-1, 0, lim, cap, new byte[cap], 0); 54 this.isReadOnly = isReadOnly; 55 } 56 57 HeapByteBuffer(byte[] buf, int off, int len) { // package-private 58 this(buf, off, len, false); 59 } 60 61 HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) { // package-private 62 super(-1, off, off + len, buf.length, buf, 0); 63 this.isReadOnly = isReadOnly; 64 } 65 66 protected HeapByteBuffer(byte[] buf, 67 int mark, int pos, int lim, int cap, 68 int off) { 69 this(buf, mark, pos, lim, cap, off, false); 70 } 71 72 protected HeapByteBuffer(byte[] buf, 73 int mark, int pos, int lim, int cap, 74 int off, boolean isReadOnly) { 75 super(mark, pos, lim, cap, buf, off); 76 this.isReadOnly = isReadOnly; 77 } 78 79 public ByteBuffer slice() { 80 return new HeapByteBuffer(hb, 81 -1, 82 0, 83 this.remaining(), 84 this.remaining(), 85 this.position() + offset); 86 } 87 88 public ByteBuffer duplicate() { 89 return new HeapByteBuffer(hb, 90 this.markValue(), 91 this.position(), 92 this.limit(), 93 this.capacity(), 94 offset); 95 } 96 97 public ByteBuffer asReadOnlyBuffer() { 98 99 return new HeapByteBuffer(hb, 100 this.markValue(), 101 this.position(), 102 this.limit(), 103 this.capacity(), 104 offset, true); 105 106 107 108 } 109 110 protected int ix(int i) { 111 return i + offset; 112 } 113 114 public byte get() { 115 return hb[ix(nextGetIndex())]; 116 } 117 118 public byte get(int i) { 119 return hb[ix(checkIndex(i))]; 120 } 121 122 public ByteBuffer get(byte[] dst, int offset, int length) { 123 checkBounds(offset, length, dst.length); 124 if (length > remaining()) 125 throw new BufferUnderflowException(); 126 System.arraycopy(hb, ix(position()), dst, offset, length); 127 position(position() + length); 128 return this; 129 } 130 131 public boolean isDirect() { 132 return false; 133 } 134 135 public boolean isReadOnly() { 136 return isReadOnly; 137 } 138 139 public ByteBuffer put(byte x) { 140 if (isReadOnly) { 141 throw new ReadOnlyBufferException(); 142 } 143 hb[ix(nextPutIndex())] = x; 144 return this; 145 } 146 147 public ByteBuffer put(int i, byte x) { 148 if (isReadOnly) { 149 throw new ReadOnlyBufferException(); 150 } 151 hb[ix(checkIndex(i))] = x; 152 return this; 153 } 154 155 public ByteBuffer put(byte[] src, int offset, int length) { 156 if (isReadOnly) { 157 throw new ReadOnlyBufferException(); 158 } 159 checkBounds(offset, length, src.length); 160 if (length > remaining()) 161 throw new BufferOverflowException(); 162 System.arraycopy(src, offset, hb, ix(position()), length); 163 position(position() + length); 164 return this; 165 } 166 167 public ByteBuffer put(ByteBuffer src) { 168 if (isReadOnly) { 169 throw new ReadOnlyBufferException(); 170 } 171 if (src instanceof HeapByteBuffer) { 172 if (src == this) 173 throw new IllegalArgumentException(); 174 HeapByteBuffer sb = (HeapByteBuffer)src; 175 int n = sb.remaining(); 176 if (n > remaining()) 177 throw new BufferOverflowException(); 178 System.arraycopy(sb.hb, sb.ix(sb.position()), 179 hb, ix(position()), n); 180 sb.position(sb.position() + n); 181 position(position() + n); 182 } else if (src.isDirect()) { 183 int n = src.remaining(); 184 if (n > remaining()) 185 throw new BufferOverflowException(); 186 src.get(hb, ix(position()), n); 187 position(position() + n); 188 } else { 189 super.put(src); 190 } 191 return this; 192 } 193 194 public ByteBuffer compact() { 195 if (isReadOnly) { 196 throw new ReadOnlyBufferException(); 197 } 198 System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); 199 position(remaining()); 200 limit(capacity()); 201 discardMark(); 202 return this; 203 } 204 205 byte _get(int i) { // package-private 206 return hb[i]; 207 } 208 209 void _put(int i, byte b) { // package-private 210 if (isReadOnly) { 211 throw new ReadOnlyBufferException(); 212 } 213 hb[i] = b; 214 } 215 216 public char getChar() { 217 return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian); 218 } 219 220 public char getChar(int i) { 221 return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian); 222 } 223 224 public ByteBuffer putChar(char x) { 225 if (isReadOnly) { 226 throw new ReadOnlyBufferException(); 227 } 228 Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian); 229 return this; 230 } 231 232 public ByteBuffer putChar(int i, char x) { 233 if (isReadOnly) { 234 throw new ReadOnlyBufferException(); 235 } 236 Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian); 237 return this; 238 } 239 240 public CharBuffer asCharBuffer() { 241 int size = this.remaining() >> 1; 242 int off = offset + position(); 243 if (isReadOnly) { 244 return (bigEndian 245 ? (CharBuffer)(new ByteBufferAsCharBufferRB(this, 246 -1, 247 0, 248 size, 249 size, 250 off)) 251 : (CharBuffer)(new ByteBufferAsCharBufferRL(this, 252 -1, 253 0, 254 size, 255 size, 256 off))); 257 } else { 258 return (bigEndian 259 ? (CharBuffer)(new ByteBufferAsCharBufferB(this, 260 -1, 261 0, 262 size, 263 size, 264 off)) 265 : (CharBuffer)(new ByteBufferAsCharBufferL(this, 266 -1, 267 0, 268 size, 269 size, 270 off))); 271 } 272 } 273 274 public short getShort() { 275 return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian); 276 } 277 278 public short getShort(int i) { 279 return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian); 280 } 281 282 public ByteBuffer putShort(short x) { 283 if (isReadOnly) { 284 throw new ReadOnlyBufferException(); 285 } 286 Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian); 287 return this; 288 } 289 290 public ByteBuffer putShort(int i, short x) { 291 if (isReadOnly) { 292 throw new ReadOnlyBufferException(); 293 } 294 Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian); 295 return this; 296 } 297 298 public ShortBuffer asShortBuffer() { 299 int size = this.remaining() >> 1; 300 int off = offset + position(); 301 return new ByteBufferAsShortBuffer(this, 302 -1, 303 0, 304 size, 305 size, 306 off, 307 order(), 308 isReadOnly); 309 } 310 311 public int getInt() { 312 return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian); 313 } 314 315 public int getInt(int i) { 316 return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian); 317 } 318 319 public ByteBuffer putInt(int x) { 320 if (isReadOnly) { 321 throw new ReadOnlyBufferException(); 322 } 323 Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian); 324 return this; 325 } 326 327 public ByteBuffer putInt(int i, int x) { 328 if (isReadOnly) { 329 throw new ReadOnlyBufferException(); 330 } 331 Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian); 332 return this; 333 } 334 335 public IntBuffer asIntBuffer() { 336 int size = this.remaining() >> 2; 337 int off = offset + position(); 338 339 return (IntBuffer)(new ByteBufferAsIntBuffer(this, 340 -1, 341 0, 342 size, 343 size, 344 off, 345 order(), 346 isReadOnly)); 347 } 348 349 public long getLong() { 350 return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian); 351 } 352 353 public long getLong(int i) { 354 return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian); 355 } 356 357 public ByteBuffer putLong(long x) { 358 if (isReadOnly) { 359 throw new ReadOnlyBufferException(); 360 } 361 Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian); 362 return this; 363 } 364 365 public ByteBuffer putLong(int i, long x) { 366 if (isReadOnly) { 367 throw new ReadOnlyBufferException(); 368 } 369 Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian); 370 return this; 371 } 372 373 public LongBuffer asLongBuffer() { 374 int size = this.remaining() >> 3; 375 int off = offset + position(); 376 if (isReadOnly) { 377 return (bigEndian 378 ? (LongBuffer)(new ByteBufferAsLongBufferRB(this, 379 -1, 380 0, 381 size, 382 size, 383 off)) 384 : (LongBuffer)(new ByteBufferAsLongBufferRL(this, 385 -1, 386 0, 387 size, 388 size, 389 off))); 390 } else { 391 return (bigEndian 392 ? (LongBuffer)(new ByteBufferAsLongBufferB(this, 393 -1, 394 0, 395 size, 396 size, 397 off)) 398 : (LongBuffer)(new ByteBufferAsLongBufferL(this, 399 -1, 400 0, 401 size, 402 size, 403 off))); 404 } 405 } 406 407 public float getFloat() { 408 return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian); 409 } 410 411 public float getFloat(int i) { 412 return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian); 413 } 414 415 416 417 public ByteBuffer putFloat(float x) { 418 if (isReadOnly) { 419 throw new ReadOnlyBufferException(); 420 } 421 Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian); 422 return this; 423 } 424 425 public ByteBuffer putFloat(int i, float x) { 426 if (isReadOnly) { 427 throw new ReadOnlyBufferException(); 428 } 429 Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian); 430 return this; 431 } 432 433 public FloatBuffer asFloatBuffer() { 434 int size = this.remaining() >> 2; 435 int off = offset + position(); 436 if (isReadOnly) { 437 return (bigEndian 438 ? (FloatBuffer)(new ByteBufferAsFloatBufferRB(this, 439 -1, 440 0, 441 size, 442 size, 443 off)) 444 : (FloatBuffer)(new ByteBufferAsFloatBufferRL(this, 445 -1, 446 0, 447 size, 448 size, 449 off))); 450 } else { 451 return (bigEndian 452 ? (FloatBuffer)(new ByteBufferAsFloatBufferB(this, 453 -1, 454 0, 455 size, 456 size, 457 off)) 458 : (FloatBuffer)(new ByteBufferAsFloatBufferL(this, 459 -1, 460 0, 461 size, 462 size, 463 off))); 464 } 465 } 466 467 public double getDouble() { 468 return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian); 469 } 470 471 public double getDouble(int i) { 472 return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian); 473 } 474 475 476 477 public ByteBuffer putDouble(double x) { 478 if (isReadOnly) { 479 throw new ReadOnlyBufferException(); 480 } 481 Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian); 482 return this; 483 } 484 485 public ByteBuffer putDouble(int i, double x) { 486 if (isReadOnly) { 487 throw new ReadOnlyBufferException(); 488 } 489 Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian); 490 return this; 491 } 492 493 public DoubleBuffer asDoubleBuffer() { 494 int size = this.remaining() >> 3; 495 int off = offset + position(); 496 return (bigEndian 497 ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer(this, 498 -1, 499 0, 500 size, 501 size, 502 off, 503 ByteOrder.BIG_ENDIAN, 504 isReadOnly)) 505 : (DoubleBuffer)(new ByteBufferAsDoubleBuffer(this, 506 -1, 507 0, 508 size, 509 size, 510 off, 511 ByteOrder.LITTLE_ENDIAN, 512 isReadOnly))); 513 514 } 515} 516