ByteBuffer.java revision b327df0b7d83f079856304830ff4da92b4a5ea1f
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.nio; 19 20import java.util.Arrays; 21import libcore.io.Memory; 22 23/** 24 * A buffer for bytes. 25 * <p> 26 * A byte buffer can be created in either one of the following ways: 27 * <ul> 28 * <li>{@link #allocate(int) Allocate} a new byte array and create a buffer 29 * based on it;</li> 30 * <li>{@link #allocateDirect(int) Allocate} a memory block and create a direct 31 * buffer based on it;</li> 32 * <li>{@link #wrap(byte[]) Wrap} an existing byte array to create a new 33 * buffer.</li> 34 * </ul> 35 * 36 */ 37public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer> { 38 /** 39 * The byte order of this buffer, default is {@code BIG_ENDIAN}. 40 */ 41 ByteOrder order = ByteOrder.BIG_ENDIAN; 42 43 /** 44 * Creates a byte buffer based on a newly allocated byte array. 45 * 46 * @param capacity 47 * the capacity of the new buffer 48 * @return the created byte buffer. 49 * @throws IllegalArgumentException 50 * if {@code capacity < 0}. 51 */ 52 public static ByteBuffer allocate(int capacity) { 53 if (capacity < 0) { 54 throw new IllegalArgumentException("capacity < 0: " + capacity); 55 } 56 return new ByteArrayBuffer(new byte[capacity]); 57 } 58 59 /** 60 * Creates a direct byte buffer based on a newly allocated memory block. 61 * 62 * @param capacity 63 * the capacity of the new buffer 64 * @return the created byte buffer. 65 * @throws IllegalArgumentException 66 * if {@code capacity < 0}. 67 */ 68 public static ByteBuffer allocateDirect(int capacity) { 69 if (capacity < 0) { 70 throw new IllegalArgumentException("capacity < 0: " + capacity); 71 } 72 return new DirectByteBuffer(MemoryBlock.allocate(capacity), capacity, 0, false, null); 73 } 74 75 /** 76 * Creates a new byte buffer by wrapping the given byte array. 77 * <p> 78 * Calling this method has the same effect as 79 * {@code wrap(array, 0, array.length)}. 80 * 81 * @param array 82 * the byte array which the new buffer will be based on 83 * @return the created byte buffer. 84 */ 85 public static ByteBuffer wrap(byte[] array) { 86 return new ByteArrayBuffer(array); 87 } 88 89 /** 90 * Creates a new byte buffer by wrapping the given byte array. 91 * <p> 92 * The new buffer's position will be {@code start}, limit will be 93 * {@code start + byteCount}, capacity will be the length of the array. 94 * 95 * @param array 96 * the byte array which the new buffer will be based on. 97 * @param start 98 * the start index, must not be negative and not greater than 99 * {@code array.length}. 100 * @param byteCount 101 * the length, must not be negative and not greater than 102 * {@code array.length - start}. 103 * @return the created byte buffer. 104 * @throws IndexOutOfBoundsException 105 * if either {@code start} or {@code byteCount} is invalid. 106 */ 107 public static ByteBuffer wrap(byte[] array, int start, int byteCount) { 108 Arrays.checkOffsetAndCount(array.length, start, byteCount); 109 ByteBuffer buf = new ByteArrayBuffer(array); 110 buf.position = start; 111 buf.limit = start + byteCount; 112 return buf; 113 } 114 115 ByteBuffer(int capacity, long effectiveDirectAddress) { 116 super(0, capacity, effectiveDirectAddress); 117 } 118 119 /** 120 * Returns the byte array which this buffer is based on, if there is one. 121 * 122 * @return the byte array which this buffer is based on. 123 * @throws ReadOnlyBufferException 124 * if this buffer is based on a read-only array. 125 * @throws UnsupportedOperationException 126 * if this buffer is not based on an array. 127 */ 128 @Override public final byte[] array() { 129 return protectedArray(); 130 } 131 132 /** 133 * Returns the offset of the byte array which this buffer is based on, if 134 * there is one. 135 * <p> 136 * The offset is the index of the array which corresponds to the zero 137 * position of the buffer. 138 * 139 * @return the offset of the byte array which this buffer is based on. 140 * @throws ReadOnlyBufferException 141 * if this buffer is based on a read-only array. 142 * @throws UnsupportedOperationException 143 * if this buffer is not based on an array. 144 */ 145 @Override public final int arrayOffset() { 146 return protectedArrayOffset(); 147 } 148 149 /** 150 * Returns a char buffer which is based on the remaining content of this 151 * byte buffer. 152 * <p> 153 * The new buffer's position is zero, its limit and capacity is the number 154 * of remaining bytes divided by two, and its mark is not set. The new 155 * buffer's read-only property and byte order are the same as this buffer's. 156 * The new buffer is direct if this byte buffer is direct. 157 * <p> 158 * The new buffer shares its content with this buffer, which means either 159 * buffer's change of content will be visible to the other. The two buffers' 160 * position, limit and mark are independent. 161 */ 162 public abstract CharBuffer asCharBuffer(); 163 164 /** 165 * Returns a double buffer which is based on the remaining content of this 166 * byte buffer. 167 * <p> 168 * The new buffer's position is zero, its limit and capacity is the number 169 * of remaining bytes divided by eight, and its mark is not set. The new 170 * buffer's read-only property and byte order are the same as this buffer's. 171 * The new buffer is direct if this byte buffer is direct. 172 * <p> 173 * The new buffer shares its content with this buffer, which means either 174 * buffer's change of content will be visible to the other. The two buffers' 175 * position, limit and mark are independent. 176 */ 177 public abstract DoubleBuffer asDoubleBuffer(); 178 179 /** 180 * Returns a float buffer which is based on the remaining content of this 181 * byte buffer. 182 * <p> 183 * The new buffer's position is zero, its limit and capacity is the number 184 * of remaining bytes divided by four, and its mark is not set. The new 185 * buffer's read-only property and byte order are the same as this buffer's. 186 * The new buffer is direct if this byte buffer is direct. 187 * <p> 188 * The new buffer shares its content with this buffer, which means either 189 * buffer's change of content will be visible to the other. The two buffers' 190 * position, limit and mark are independent. 191 */ 192 public abstract FloatBuffer asFloatBuffer(); 193 194 /** 195 * Returns a int buffer which is based on the remaining content of this byte 196 * buffer. 197 * <p> 198 * The new buffer's position is zero, its limit and capacity is the number 199 * of remaining bytes divided by four, and its mark is not set. The new 200 * buffer's read-only property and byte order are the same as this buffer's. 201 * The new buffer is direct if this byte buffer is direct. 202 * <p> 203 * The new buffer shares its content with this buffer, which means either 204 * buffer's change of content will be visible to the other. The two buffers' 205 * position, limit and mark are independent. 206 */ 207 public abstract IntBuffer asIntBuffer(); 208 209 /** 210 * Returns a long buffer which is based on the remaining content of this 211 * byte buffer. 212 * <p> 213 * The new buffer's position is zero, its limit and capacity is the number 214 * of remaining bytes divided by eight, and its mark is not set. The new 215 * buffer's read-only property and byte order are the same as this buffer's. 216 * The new buffer is direct if this byte buffer is direct. 217 * <p> 218 * The new buffer shares its content with this buffer, which means either 219 * buffer's change of content will be visible to the other. The two buffers' 220 * position, limit and mark are independent. 221 */ 222 public abstract LongBuffer asLongBuffer(); 223 224 /** 225 * Returns a read-only buffer that shares its content with this buffer. 226 * <p> 227 * The returned buffer is guaranteed to be a new instance, even if this 228 * buffer is read-only itself. The new buffer's position, limit, capacity 229 * and mark are the same as this buffer. 230 * <p> 231 * The new buffer shares its content with this buffer, which means this 232 * buffer's change of content will be visible to the new buffer. The two 233 * buffer's position, limit and mark are independent. 234 * 235 * @return a read-only version of this buffer. 236 */ 237 public abstract ByteBuffer asReadOnlyBuffer(); 238 239 /** 240 * Returns a short buffer which is based on the remaining content of this 241 * byte buffer. 242 * <p> 243 * The new buffer's position is zero, its limit and capacity is the number 244 * of remaining bytes divided by two, and its mark is not set. The new 245 * buffer's read-only property and byte order are the same as this buffer's. 246 * The new buffer is direct if this byte buffer is direct. 247 * <p> 248 * The new buffer shares its content with this buffer, which means either 249 * buffer's change of content will be visible to the other. The two buffers' 250 * position, limit and mark are independent. 251 */ 252 public abstract ShortBuffer asShortBuffer(); 253 254 /** 255 * Compacts this byte buffer. 256 * <p> 257 * The remaining bytes will be moved to the head of the 258 * buffer, starting from position zero. Then the position is set to 259 * {@code remaining()}; the limit is set to capacity; the mark is 260 * cleared. 261 * 262 * @return {@code this} 263 * @throws ReadOnlyBufferException 264 * if no changes may be made to the contents of this buffer. 265 */ 266 public abstract ByteBuffer compact(); 267 268 /** 269 * Compares the remaining bytes of this buffer to another byte buffer's 270 * remaining bytes. 271 * 272 * @param otherBuffer 273 * another byte buffer. 274 * @return a negative value if this is less than {@code other}; 0 if this 275 * equals to {@code other}; a positive value if this is greater 276 * than {@code other}. 277 * @throws ClassCastException 278 * if {@code other} is not a byte buffer. 279 */ 280 @Override public int compareTo(ByteBuffer otherBuffer) { 281 int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining() 282 : otherBuffer.remaining(); 283 int thisPos = position; 284 int otherPos = otherBuffer.position; 285 byte thisByte, otherByte; 286 while (compareRemaining > 0) { 287 thisByte = get(thisPos); 288 otherByte = otherBuffer.get(otherPos); 289 if (thisByte != otherByte) { 290 return thisByte < otherByte ? -1 : 1; 291 } 292 thisPos++; 293 otherPos++; 294 compareRemaining--; 295 } 296 return remaining() - otherBuffer.remaining(); 297 } 298 299 /** 300 * Returns a duplicated buffer that shares its content with this buffer. 301 * <p> 302 * The duplicated buffer's position, limit, capacity and mark are the same 303 * as this buffer's. The duplicated buffer's read-only property is the same 304 * as this buffer's. 305 * 306 * <p>Note that <i>in contrast to all non-{@code byte} buffers</i>, 307 * byte order is not preserved in the duplicate, and is instead set to 308 * big-endian. 309 * 310 * <p>The new buffer shares its content with this buffer, which means either 311 * buffer's change of content will be visible to the other. The two buffers' 312 * position, limit and mark are independent. 313 */ 314 public abstract ByteBuffer duplicate(); 315 316 /** 317 * Checks whether this byte buffer is equal to another object. 318 * <p> 319 * If {@code other} is not a byte buffer then {@code false} is returned. Two 320 * byte buffers are equal if and only if their remaining bytes are exactly 321 * the same. Position, limit, capacity and mark are not considered. 322 * 323 * @param other 324 * the object to compare with this byte buffer. 325 * @return {@code true} if this byte buffer is equal to {@code other}, 326 * {@code false} otherwise. 327 */ 328 @Override 329 public boolean equals(Object other) { 330 if (!(other instanceof ByteBuffer)) { 331 return false; 332 } 333 ByteBuffer otherBuffer = (ByteBuffer) other; 334 335 if (remaining() != otherBuffer.remaining()) { 336 return false; 337 } 338 339 int myPosition = position; 340 int otherPosition = otherBuffer.position; 341 boolean equalSoFar = true; 342 while (equalSoFar && (myPosition < limit)) { 343 equalSoFar = get(myPosition++) == otherBuffer.get(otherPosition++); 344 } 345 346 return equalSoFar; 347 } 348 349 /** 350 * Returns the byte at the current position and increases the position by 1. 351 * 352 * @return the byte at the current position. 353 * @throws BufferUnderflowException 354 * if the position is equal or greater than limit. 355 */ 356 public abstract byte get(); 357 358 /** 359 * Reads bytes from the current position into the specified byte array and 360 * increases the position by the number of bytes read. 361 * <p> 362 * Calling this method has the same effect as 363 * {@code get(dst, 0, dst.length)}. 364 * 365 * @param dst 366 * the destination byte array. 367 * @return {@code this} 368 * @throws BufferUnderflowException 369 * if {@code dst.length} is greater than {@code remaining()}. 370 */ 371 public ByteBuffer get(byte[] dst) { 372 return get(dst, 0, dst.length); 373 } 374 375 /** 376 * Reads bytes from the current position into the specified byte array, 377 * starting at the specified offset, and increases the position by the 378 * number of bytes read. 379 * 380 * @param dst 381 * the target byte array. 382 * @param dstOffset 383 * the offset of the byte array, must not be negative and 384 * not greater than {@code dst.length}. 385 * @param byteCount 386 * the number of bytes to read, must not be negative and not 387 * greater than {@code dst.length - dstOffset} 388 * @return {@code this} 389 * @throws IndexOutOfBoundsException if {@code dstOffset < 0 || byteCount < 0} 390 * @throws BufferUnderflowException if {@code byteCount > remaining()} 391 */ 392 public ByteBuffer get(byte[] dst, int dstOffset, int byteCount) { 393 Arrays.checkOffsetAndCount(dst.length, dstOffset, byteCount); 394 if (byteCount > remaining()) { 395 throw new BufferUnderflowException(); 396 } 397 for (int i = dstOffset; i < dstOffset + byteCount; ++i) { 398 dst[i] = get(); 399 } 400 return this; 401 } 402 403 /** 404 * Returns the byte at the specified index and does not change the position. 405 * 406 * @param index 407 * the index, must not be negative and less than limit. 408 * @return the byte at the specified index. 409 * @throws IndexOutOfBoundsException 410 * if index is invalid. 411 */ 412 public abstract byte get(int index); 413 414 /** 415 * Returns the char at the current position and increases the position by 2. 416 * <p> 417 * The 2 bytes starting at the current position are composed into a char 418 * according to the current byte order and returned. 419 * 420 * @return the char at the current position. 421 * @throws BufferUnderflowException 422 * if the position is greater than {@code limit - 2}. 423 */ 424 public abstract char getChar(); 425 426 /** 427 * Returns the char at the specified index. 428 * <p> 429 * The 2 bytes starting from the specified index are composed into a char 430 * according to the current byte order and returned. The position is not 431 * changed. 432 * 433 * @param index 434 * the index, must not be negative and equal or less than 435 * {@code limit - 2}. 436 * @return the char at the specified index. 437 * @throws IndexOutOfBoundsException 438 * if {@code index} is invalid. 439 */ 440 public abstract char getChar(int index); 441 442 /** 443 * Returns the double at the current position and increases the position by 444 * 8. 445 * <p> 446 * The 8 bytes starting from the current position are composed into a double 447 * according to the current byte order and returned. 448 * 449 * @return the double at the current position. 450 * @throws BufferUnderflowException 451 * if the position is greater than {@code limit - 8}. 452 */ 453 public abstract double getDouble(); 454 455 /** 456 * Returns the double at the specified index. 457 * <p> 458 * The 8 bytes starting at the specified index are composed into a double 459 * according to the current byte order and returned. The position is not 460 * changed. 461 * 462 * @param index 463 * the index, must not be negative and equal or less than 464 * {@code limit - 8}. 465 * @return the double at the specified index. 466 * @throws IndexOutOfBoundsException 467 * if {@code index} is invalid. 468 */ 469 public abstract double getDouble(int index); 470 471 /** 472 * Returns the float at the current position and increases the position by 473 * 4. 474 * <p> 475 * The 4 bytes starting at the current position are composed into a float 476 * according to the current byte order and returned. 477 * 478 * @return the float at the current position. 479 * @throws BufferUnderflowException 480 * if the position is greater than {@code limit - 4}. 481 */ 482 public abstract float getFloat(); 483 484 /** 485 * Returns the float at the specified index. 486 * <p> 487 * The 4 bytes starting at the specified index are composed into a float 488 * according to the current byte order and returned. The position is not 489 * changed. 490 * 491 * @param index 492 * the index, must not be negative and equal or less than 493 * {@code limit - 4}. 494 * @return the float at the specified index. 495 * @throws IndexOutOfBoundsException 496 * if {@code index} is invalid. 497 */ 498 public abstract float getFloat(int index); 499 500 /** 501 * Returns the int at the current position and increases the position by 4. 502 * <p> 503 * The 4 bytes starting at the current position are composed into a int 504 * according to the current byte order and returned. 505 * 506 * @return the int at the current position. 507 * @throws BufferUnderflowException 508 * if the position is greater than {@code limit - 4}. 509 */ 510 public abstract int getInt(); 511 512 /** 513 * Returns the int at the specified index. 514 * <p> 515 * The 4 bytes starting at the specified index are composed into a int 516 * according to the current byte order and returned. The position is not 517 * changed. 518 * 519 * @param index 520 * the index, must not be negative and equal or less than 521 * {@code limit - 4}. 522 * @return the int at the specified index. 523 * @throws IndexOutOfBoundsException 524 * if {@code index} is invalid. 525 */ 526 public abstract int getInt(int index); 527 528 /** 529 * Returns the long at the current position and increases the position by 8. 530 * <p> 531 * The 8 bytes starting at the current position are composed into a long 532 * according to the current byte order and returned. 533 * 534 * @return the long at the current position. 535 * @throws BufferUnderflowException 536 * if the position is greater than {@code limit - 8}. 537 */ 538 public abstract long getLong(); 539 540 /** 541 * Returns the long at the specified index. 542 * <p> 543 * The 8 bytes starting at the specified index are composed into a long 544 * according to the current byte order and returned. The position is not 545 * changed. 546 * 547 * @param index 548 * the index, must not be negative and equal or less than 549 * {@code limit - 8}. 550 * @return the long at the specified index. 551 * @throws IndexOutOfBoundsException 552 * if {@code index} is invalid. 553 */ 554 public abstract long getLong(int index); 555 556 /** 557 * Returns the short at the current position and increases the position by 2. 558 * <p> 559 * The 2 bytes starting at the current position are composed into a short 560 * according to the current byte order and returned. 561 * 562 * @return the short at the current position. 563 * @throws BufferUnderflowException 564 * if the position is greater than {@code limit - 2}. 565 */ 566 public abstract short getShort(); 567 568 /** 569 * Returns the short at the specified index. 570 * <p> 571 * The 2 bytes starting at the specified index are composed into a short 572 * according to the current byte order and returned. The position is not 573 * changed. 574 * 575 * @param index 576 * the index, must not be negative and equal or less than 577 * {@code limit - 2}. 578 * @return the short at the specified index. 579 * @throws IndexOutOfBoundsException 580 * if {@code index} is invalid. 581 */ 582 public abstract short getShort(int index); 583 584 @Override public final boolean hasArray() { 585 return protectedHasArray(); 586 } 587 588 /** 589 * Calculates this buffer's hash code from the remaining chars. The 590 * position, limit, capacity and mark don't affect the hash code. 591 * 592 * @return the hash code calculated from the remaining bytes. 593 */ 594 @Override 595 public int hashCode() { 596 int myPosition = position; 597 int hash = 0; 598 while (myPosition < limit) { 599 hash = hash + get(myPosition++); 600 } 601 return hash; 602 } 603 604 /** 605 * Indicates whether this buffer is direct. 606 * 607 * @return {@code true} if this buffer is direct, {@code false} otherwise. 608 */ 609 @Override public abstract boolean isDirect(); 610 611 /** 612 * Indicates whether this buffer is still accessible. 613 * 614 * @return {@code true} if this buffer is accessible, {@code false} if the 615 * buffer was made inaccessible (e.g. freed) and should not be used. 616 * @hide 617 */ 618 public boolean isAccessible() { 619 return true; 620 } 621 622 /** 623 * Sets buffer accessibility (only supported for direct byte buffers). If 624 * {@code accessible} is {@code false}, {@link #isAccessible} will return 625 * false, and any attempt to access the buffer will throw an exception. If 626 * {@code true}, the buffer will become useable again, unless it has been 627 * freed. 628 * 629 * @hide 630 */ 631 public void setAccessible(boolean accessible) { 632 throw new UnsupportedOperationException(); 633 } 634 635 /** 636 * Returns the byte order used by this buffer when converting bytes from/to 637 * other primitive types. 638 * <p> 639 * The default byte order of byte buffer is always 640 * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN} 641 * 642 * @return the byte order used by this buffer when converting bytes from/to 643 * other primitive types. 644 */ 645 public final ByteOrder order() { 646 return order; 647 } 648 649 /** 650 * Sets the byte order of this buffer. 651 * 652 * @param byteOrder 653 * the byte order to set. If {@code null} then the order 654 * will be {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}. 655 * @return {@code this} 656 * @see ByteOrder 657 */ 658 public final ByteBuffer order(ByteOrder byteOrder) { 659 if (byteOrder == null) { 660 byteOrder = ByteOrder.LITTLE_ENDIAN; 661 } 662 order = byteOrder; 663 return this; 664 } 665 666 /** 667 * Child class implements this method to realize {@code array()}. 668 * 669 * @see #array() 670 */ 671 abstract byte[] protectedArray(); 672 673 /** 674 * Child class implements this method to realize {@code arrayOffset()}. 675 * 676 * @see #arrayOffset() 677 */ 678 abstract int protectedArrayOffset(); 679 680 /** 681 * Child class implements this method to realize {@code hasArray()}. 682 * 683 * @see #hasArray() 684 */ 685 abstract boolean protectedHasArray(); 686 687 /** 688 * Writes the given byte to the current position and increases the position 689 * by 1. 690 * 691 * @param b 692 * the byte to write. 693 * @return {@code this} 694 * @throws BufferOverflowException 695 * if position is equal or greater than limit. 696 * @throws ReadOnlyBufferException 697 * if no changes may be made to the contents of this buffer. 698 */ 699 public abstract ByteBuffer put(byte b); 700 701 /** 702 * Writes bytes in the given byte array to the current position and 703 * increases the position by the number of bytes written. 704 * <p> 705 * Calling this method has the same effect as 706 * {@code put(src, 0, src.length)}. 707 * 708 * @param src 709 * the source byte array. 710 * @return {@code this} 711 * @throws BufferOverflowException 712 * if {@code remaining()} is less than {@code src.length}. 713 * @throws ReadOnlyBufferException 714 * if no changes may be made to the contents of this buffer. 715 */ 716 public final ByteBuffer put(byte[] src) { 717 return put(src, 0, src.length); 718 } 719 720 /** 721 * Writes bytes in the given byte array, starting from the specified offset, 722 * to the current position and increases the position by the number of bytes 723 * written. 724 * 725 * @param src 726 * the source byte array. 727 * @param srcOffset 728 * the offset of byte array, must not be negative and not greater 729 * than {@code src.length}. 730 * @param byteCount 731 * the number of bytes to write, must not be negative and not 732 * greater than {@code src.length - srcOffset}. 733 * @return {@code this} 734 * @throws BufferOverflowException 735 * if {@code remaining()} is less than {@code byteCount}. 736 * @throws IndexOutOfBoundsException 737 * if either {@code srcOffset} or {@code byteCount} is invalid. 738 * @throws ReadOnlyBufferException 739 * if no changes may be made to the contents of this buffer. 740 */ 741 public ByteBuffer put(byte[] src, int srcOffset, int byteCount) { 742 Arrays.checkOffsetAndCount(src.length, srcOffset, byteCount); 743 if (byteCount > remaining()) { 744 throw new BufferOverflowException(); 745 } 746 for (int i = srcOffset; i < srcOffset + byteCount; ++i) { 747 put(src[i]); 748 } 749 return this; 750 } 751 752 /** 753 * Writes all the remaining bytes of the {@code src} byte buffer to this 754 * buffer's current position, and increases both buffers' position by the 755 * number of bytes copied. 756 * 757 * @param src 758 * the source byte buffer. 759 * @return {@code this} 760 * @throws BufferOverflowException 761 * if {@code src.remaining()} is greater than this buffer's 762 * {@code remaining()}. 763 * @throws IllegalArgumentException 764 * if {@code src} is this buffer. 765 * @throws ReadOnlyBufferException 766 * if no changes may be made to the contents of this buffer. 767 */ 768 public ByteBuffer put(ByteBuffer src) { 769 if (isReadOnly()) { 770 throw new ReadOnlyBufferException(); 771 } 772 if (src == this) { 773 throw new IllegalArgumentException("src == this"); 774 } 775 if (!src.isAccessible() || !isAccessible()) { 776 throw new IllegalStateException("buffer is inaccessible"); 777 } 778 int srcByteCount = src.remaining(); 779 if (srcByteCount > remaining()) { 780 throw new BufferOverflowException(); 781 } 782 783 Object srcObject = src.isDirect() ? src : NioUtils.unsafeArray(src); 784 int srcOffset = src.position(); 785 if (!src.isDirect()) { 786 srcOffset += NioUtils.unsafeArrayOffset(src); 787 } 788 789 ByteBuffer dst = this; 790 Object dstObject = dst.isDirect() ? dst : NioUtils.unsafeArray(dst); 791 int dstOffset = dst.position(); 792 if (!dst.isDirect()) { 793 dstOffset += NioUtils.unsafeArrayOffset(dst); 794 } 795 796 Memory.memmove(dstObject, dstOffset, srcObject, srcOffset, srcByteCount); 797 src.position(src.limit()); 798 dst.position(dst.position() + srcByteCount); 799 800 return this; 801 } 802 803 /** 804 * Write a byte to the specified index of this buffer without changing the 805 * position. 806 * 807 * @param index 808 * the index, must not be negative and less than the limit. 809 * @param b 810 * the byte to write. 811 * @return {@code this} 812 * @throws IndexOutOfBoundsException 813 * if {@code index} is invalid. 814 * @throws ReadOnlyBufferException 815 * if no changes may be made to the contents of this buffer. 816 */ 817 public abstract ByteBuffer put(int index, byte b); 818 819 /** 820 * Writes the given char to the current position and increases the position 821 * by 2. 822 * <p> 823 * The char is converted to bytes using the current byte order. 824 * 825 * @param value 826 * the char to write. 827 * @return {@code this} 828 * @throws BufferOverflowException 829 * if position is greater than {@code limit - 2}. 830 * @throws ReadOnlyBufferException 831 * if no changes may be made to the contents of this buffer. 832 */ 833 public abstract ByteBuffer putChar(char value); 834 835 /** 836 * Writes the given char to the specified index of this buffer. 837 * <p> 838 * The char is converted to bytes using the current byte order. The position 839 * is not changed. 840 * 841 * @param index 842 * the index, must not be negative and equal or less than 843 * {@code limit - 2}. 844 * @param value 845 * the char to write. 846 * @return {@code this} 847 * @throws IndexOutOfBoundsException 848 * if {@code index} is invalid. 849 * @throws ReadOnlyBufferException 850 * if no changes may be made to the contents of this buffer. 851 */ 852 public abstract ByteBuffer putChar(int index, char value); 853 854 /** 855 * Writes the given double to the current position and increases the position 856 * by 8. 857 * <p> 858 * The double is converted to bytes using the current byte order. 859 * 860 * @param value 861 * the double to write. 862 * @return {@code this} 863 * @throws BufferOverflowException 864 * if position is greater than {@code limit - 8}. 865 * @throws ReadOnlyBufferException 866 * if no changes may be made to the contents of this buffer. 867 */ 868 public abstract ByteBuffer putDouble(double value); 869 870 /** 871 * Writes the given double to the specified index of this buffer. 872 * <p> 873 * The double is converted to bytes using the current byte order. The 874 * position is not changed. 875 * 876 * @param index 877 * the index, must not be negative and equal or less than 878 * {@code limit - 8}. 879 * @param value 880 * the double to write. 881 * @return {@code this} 882 * @throws IndexOutOfBoundsException 883 * if {@code index} is invalid. 884 * @throws ReadOnlyBufferException 885 * if no changes may be made to the contents of this buffer. 886 */ 887 public abstract ByteBuffer putDouble(int index, double value); 888 889 /** 890 * Writes the given float to the current position and increases the position 891 * by 4. 892 * <p> 893 * The float is converted to bytes using the current byte order. 894 * 895 * @param value 896 * the float to write. 897 * @return {@code this} 898 * @throws BufferOverflowException 899 * if position is greater than {@code limit - 4}. 900 * @throws ReadOnlyBufferException 901 * if no changes may be made to the contents of this buffer. 902 */ 903 public abstract ByteBuffer putFloat(float value); 904 905 /** 906 * Writes the given float to the specified index of this buffer. 907 * <p> 908 * The float is converted to bytes using the current byte order. The 909 * position is not changed. 910 * 911 * @param index 912 * the index, must not be negative and equal or less than 913 * {@code limit - 4}. 914 * @param value 915 * the float to write. 916 * @return {@code this} 917 * @throws IndexOutOfBoundsException 918 * if {@code index} is invalid. 919 * @throws ReadOnlyBufferException 920 * if no changes may be made to the contents of this buffer. 921 */ 922 public abstract ByteBuffer putFloat(int index, float value); 923 924 /** 925 * Writes the given int to the current position and increases the position by 926 * 4. 927 * <p> 928 * The int is converted to bytes using the current byte order. 929 * 930 * @param value 931 * the int to write. 932 * @return {@code this} 933 * @throws BufferOverflowException 934 * if position is greater than {@code limit - 4}. 935 * @throws ReadOnlyBufferException 936 * if no changes may be made to the contents of this buffer. 937 */ 938 public abstract ByteBuffer putInt(int value); 939 940 /** 941 * Writes the given int to the specified index of this buffer. 942 * <p> 943 * The int is converted to bytes using the current byte order. The position 944 * is not changed. 945 * 946 * @param index 947 * the index, must not be negative and equal or less than 948 * {@code limit - 4}. 949 * @param value 950 * the int to write. 951 * @return {@code this} 952 * @throws IndexOutOfBoundsException 953 * if {@code index} is invalid. 954 * @throws ReadOnlyBufferException 955 * if no changes may be made to the contents of this buffer. 956 */ 957 public abstract ByteBuffer putInt(int index, int value); 958 959 /** 960 * Writes the given long to the current position and increases the position 961 * by 8. 962 * <p> 963 * The long is converted to bytes using the current byte order. 964 * 965 * @param value 966 * the long to write. 967 * @return {@code this} 968 * @throws BufferOverflowException 969 * if position is greater than {@code limit - 8}. 970 * @throws ReadOnlyBufferException 971 * if no changes may be made to the contents of this buffer. 972 */ 973 public abstract ByteBuffer putLong(long value); 974 975 /** 976 * Writes the given long to the specified index of this buffer. 977 * <p> 978 * The long is converted to bytes using the current byte order. The position 979 * is not changed. 980 * 981 * @param index 982 * the index, must not be negative and equal or less than 983 * {@code limit - 8}. 984 * @param value 985 * the long to write. 986 * @return {@code this} 987 * @throws IndexOutOfBoundsException 988 * if {@code index} is invalid. 989 * @throws ReadOnlyBufferException 990 * if no changes may be made to the contents of this buffer. 991 */ 992 public abstract ByteBuffer putLong(int index, long value); 993 994 /** 995 * Writes the given short to the current position and increases the position 996 * by 2. 997 * <p> 998 * The short is converted to bytes using the current byte order. 999 * 1000 * @param value 1001 * the short to write. 1002 * @return {@code this} 1003 * @throws BufferOverflowException 1004 * if position is greater than {@code limit - 2}. 1005 * @throws ReadOnlyBufferException 1006 * if no changes may be made to the contents of this buffer. 1007 */ 1008 public abstract ByteBuffer putShort(short value); 1009 1010 /** 1011 * Writes the given short to the specified index of this buffer. 1012 * <p> 1013 * The short is converted to bytes using the current byte order. The 1014 * position is not changed. 1015 * 1016 * @param index 1017 * the index, must not be negative and equal or less than 1018 * {@code limit - 2}. 1019 * @param value 1020 * the short to write. 1021 * @return {@code this} 1022 * @throws IndexOutOfBoundsException 1023 * if {@code index} is invalid. 1024 * @throws ReadOnlyBufferException 1025 * if no changes may be made to the contents of this buffer. 1026 */ 1027 public abstract ByteBuffer putShort(int index, short value); 1028 1029 /** 1030 * Returns a sliced buffer that shares its content with this buffer. 1031 * <p> 1032 * The sliced buffer's capacity will be this buffer's 1033 * {@code remaining()}, and it's zero position will correspond to 1034 * this buffer's current position. The new buffer's position will be 0, 1035 * limit will be its capacity, and its mark is cleared. The new buffer's 1036 * read-only property and byte order are the same as this buffer's. 1037 * <p> 1038 * The new buffer shares its content with this buffer, which means either 1039 * buffer's change of content will be visible to the other. The two buffers' 1040 * position, limit and mark are independent. 1041 */ 1042 public abstract ByteBuffer slice(); 1043} 1044