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