1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 * 19 */ 20 package org.apache.mina.core.buffer; 21 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.io.OutputStream; 25 import java.nio.BufferOverflowException; 26 import java.nio.ByteBuffer; 27 import java.nio.ByteOrder; 28 import java.nio.CharBuffer; 29 import java.nio.DoubleBuffer; 30 import java.nio.FloatBuffer; 31 import java.nio.IntBuffer; 32 import java.nio.LongBuffer; 33 import java.nio.ReadOnlyBufferException; 34 import java.nio.ShortBuffer; 35 import java.nio.charset.CharacterCodingException; 36 import java.nio.charset.CharsetDecoder; 37 import java.nio.charset.CharsetEncoder; 38 import java.util.EnumSet; 39 import java.util.Set; 40 41 import org.apache.mina.core.session.IoSession; 42 43 /** 44 * A byte buffer used by MINA applications. 45 * <p> 46 * This is a replacement for {@link ByteBuffer}. Please refer to 47 * {@link ByteBuffer} documentation for preliminary usage. MINA does not use NIO 48 * {@link ByteBuffer} directly for two reasons: 49 * <ul> 50 * <li>It doesn't provide useful getters and putters such as <code>fill</code>, 51 * <code>get/putString</code>, and <code>get/putAsciiInt()</code> enough.</li> 52 * <li>It is difficult to write variable-length data due to its fixed capacity</li> 53 * </ul> 54 * </p> 55 * 56 * <h2>Allocation</h2> 57 * <p> 58 * You can allocate a new heap buffer. 59 * 60 * <pre> 61 * IoBuffer buf = IoBuffer.allocate(1024, false); 62 * </pre> 63 * 64 * you can also allocate a new direct buffer: 65 * 66 * <pre> 67 * IoBuffer buf = IoBuffer.allocate(1024, true); 68 * </pre> 69 * 70 * or you can set the default buffer type. 71 * 72 * <pre> 73 * // Allocate heap buffer by default. 74 * IoBuffer.setUseDirectBuffer(false); 75 * // A new heap buffer is returned. 76 * IoBuffer buf = IoBuffer.allocate(1024); 77 * </pre> 78 * 79 * </p> 80 * 81 * <h2>Wrapping existing NIO buffers and arrays</h2> 82 * <p> 83 * This class provides a few <tt>wrap(...)</tt> methods that wraps any NIO 84 * buffers and byte arrays. 85 * 86 * <h2>AutoExpand</h2> 87 * <p> 88 * Writing variable-length data using NIO <tt>ByteBuffers</tt> is not really 89 * easy, and it is because its size is fixed. {@link IoBuffer} introduces 90 * <tt>autoExpand</tt> property. If <tt>autoExpand</tt> property is true, you 91 * never get {@link BufferOverflowException} or 92 * {@link IndexOutOfBoundsException} (except when index is negative). It 93 * automatically expands its capacity and limit value. For example: 94 * 95 * <pre> 96 * String greeting = messageBundle.getMessage("hello"); 97 * IoBuffer buf = IoBuffer.allocate(16); 98 * // Turn on autoExpand (it is off by default) 99 * buf.setAutoExpand(true); 100 * buf.putString(greeting, utf8encoder); 101 * </pre> 102 * 103 * The underlying {@link ByteBuffer} is reallocated by {@link IoBuffer} behind 104 * the scene if the encoded data is larger than 16 bytes in the example above. 105 * Its capacity will double, and its limit will increase to the last position 106 * the string is written. 107 * </p> 108 * 109 * <h2>AutoShrink</h2> 110 * <p> 111 * You might also want to decrease the capacity of the buffer when most of the 112 * allocated memory area is not being used. {@link IoBuffer} provides 113 * <tt>autoShrink</tt> property to take care of this issue. If 114 * <tt>autoShrink</tt> is turned on, {@link IoBuffer} halves the capacity of the 115 * buffer when {@link #compact()} is invoked and only 1/4 or less of the current 116 * capacity is being used. 117 * <p> 118 * You can also {@link #shrink()} method manually to shrink the capacity of the 119 * buffer. 120 * <p> 121 * The underlying {@link ByteBuffer} is reallocated by {@link IoBuffer} behind 122 * the scene, and therefore {@link #buf()} will return a different 123 * {@link ByteBuffer} instance once capacity changes. Please also note 124 * {@link #compact()} or {@link #shrink()} will not decrease the capacity if the 125 * new capacity is less than the {@link #minimumCapacity()} of the buffer. 126 * 127 * <h2>Derived Buffers</h2> 128 * <p> 129 * Derived buffers are the buffers which were created by {@link #duplicate()}, 130 * {@link #slice()}, or {@link #asReadOnlyBuffer()}. They are useful especially 131 * when you broadcast the same messages to multiple {@link IoSession}s. Please 132 * note that the buffer derived from and its derived buffers are not both 133 * auto-expandable neither auto-shrinkable. Trying to call 134 * {@link #setAutoExpand(boolean)} or {@link #setAutoShrink(boolean)} with 135 * <tt>true</tt> parameter will raise an {@link IllegalStateException}. 136 * </p> 137 * 138 * <h2>Changing Buffer Allocation Policy</h2> 139 * <p> 140 * {@link IoBufferAllocator} interface lets you override the default buffer 141 * management behavior. There are two allocators provided out-of-the-box: 142 * <ul> 143 * <li>{@link SimpleBufferAllocator} (default)</li> 144 * <li>{@link CachedBufferAllocator}</li> 145 * </ul> 146 * You can implement your own allocator and use it by calling 147 * {@link #setAllocator(IoBufferAllocator)}. 148 * </p> 149 * 150 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 151 */ 152 public abstract class IoBuffer implements Comparable<IoBuffer> { 153 /** The allocator used to create new buffers */ 154 private static IoBufferAllocator allocator = new SimpleBufferAllocator(); 155 156 /** A flag indicating which type of buffer we are using : heap or direct */ 157 private static boolean useDirectBuffer = false; 158 159 /** 160 * Returns the allocator used by existing and new buffers 161 */ 162 public static IoBufferAllocator getAllocator() { 163 return allocator; 164 } 165 166 /** 167 * Sets the allocator used by existing and new buffers 168 */ 169 public static void setAllocator(IoBufferAllocator newAllocator) { 170 if (newAllocator == null) { 171 throw new IllegalArgumentException("allocator"); 172 } 173 174 IoBufferAllocator oldAllocator = allocator; 175 176 allocator = newAllocator; 177 178 if (null != oldAllocator) { 179 oldAllocator.dispose(); 180 } 181 } 182 183 /** 184 * Returns <tt>true</tt> if and only if a direct buffer is allocated by 185 * default when the type of the new buffer is not specified. The default 186 * value is <tt>false</tt>. 187 */ 188 public static boolean isUseDirectBuffer() { 189 return useDirectBuffer; 190 } 191 192 /** 193 * Sets if a direct buffer should be allocated by default when the type of 194 * the new buffer is not specified. The default value is <tt>false</tt>. 195 */ 196 public static void setUseDirectBuffer(boolean useDirectBuffer) { 197 IoBuffer.useDirectBuffer = useDirectBuffer; 198 } 199 200 /** 201 * Returns the direct or heap buffer which is capable to store the specified 202 * amount of bytes. 203 * 204 * @param capacity 205 * the capacity of the buffer 206 * 207 * @see #setUseDirectBuffer(boolean) 208 */ 209 public static IoBuffer allocate(int capacity) { 210 return allocate(capacity, useDirectBuffer); 211 } 212 213 /** 214 * Returns the buffer which is capable of the specified size. 215 * 216 * @param capacity 217 * the capacity of the buffer 218 * @param direct 219 * <tt>true</tt> to get a direct buffer, <tt>false</tt> to get a 220 * heap buffer. 221 */ 222 public static IoBuffer allocate(int capacity, boolean direct) { 223 if (capacity < 0) { 224 throw new IllegalArgumentException("capacity: " + capacity); 225 } 226 227 return allocator.allocate(capacity, direct); 228 } 229 230 /** 231 * Wraps the specified NIO {@link ByteBuffer} into MINA buffer. 232 */ 233 public static IoBuffer wrap(ByteBuffer nioBuffer) { 234 return allocator.wrap(nioBuffer); 235 } 236 237 /** 238 * Wraps the specified byte array into MINA heap buffer. 239 */ 240 public static IoBuffer wrap(byte[] byteArray) { 241 return wrap(ByteBuffer.wrap(byteArray)); 242 } 243 244 /** 245 * Wraps the specified byte array into MINA heap buffer. 246 */ 247 public static IoBuffer wrap(byte[] byteArray, int offset, int length) { 248 return wrap(ByteBuffer.wrap(byteArray, offset, length)); 249 } 250 251 /** 252 * Normalizes the specified capacity of the buffer to power of 2, which is 253 * often helpful for optimal memory usage and performance. If it is greater 254 * than or equal to {@link Integer#MAX_VALUE}, it returns 255 * {@link Integer#MAX_VALUE}. If it is zero, it returns zero. 256 */ 257 protected static int normalizeCapacity(int requestedCapacity) { 258 if (requestedCapacity < 0) { 259 return Integer.MAX_VALUE; 260 } 261 262 int newCapacity = Integer.highestOneBit(requestedCapacity); 263 newCapacity <<= (newCapacity < requestedCapacity ? 1 : 0); 264 return newCapacity < 0 ? Integer.MAX_VALUE : newCapacity; 265 } 266 267 /** 268 * Creates a new instance. This is an empty constructor. 269 */ 270 protected IoBuffer() { 271 // Do nothing 272 } 273 274 /** 275 * Declares this buffer and all its derived buffers are not used anymore so 276 * that it can be reused by some {@link IoBufferAllocator} implementations. 277 * It is not mandatory to call this method, but you might want to invoke 278 * this method for maximum performance. 279 */ 280 public abstract void free(); 281 282 /** 283 * Returns the underlying NIO buffer instance. 284 */ 285 public abstract ByteBuffer buf(); 286 287 /** 288 * @see ByteBuffer#isDirect() 289 */ 290 public abstract boolean isDirect(); 291 292 /** 293 * returns <tt>true</tt> if and only if this buffer is derived from other 294 * buffer via {@link #duplicate()}, {@link #slice()} or 295 * {@link #asReadOnlyBuffer()}. 296 */ 297 public abstract boolean isDerived(); 298 299 /** 300 * @see ByteBuffer#isReadOnly() 301 */ 302 public abstract boolean isReadOnly(); 303 304 /** 305 * Returns the minimum capacity of this buffer which is used to determine 306 * the new capacity of the buffer shrunk by {@link #compact()} and 307 * {@link #shrink()} operation. The default value is the initial capacity of 308 * the buffer. 309 */ 310 public abstract int minimumCapacity(); 311 312 /** 313 * Sets the minimum capacity of this buffer which is used to determine the 314 * new capacity of the buffer shrunk by {@link #compact()} and 315 * {@link #shrink()} operation. The default value is the initial capacity of 316 * the buffer. 317 */ 318 public abstract IoBuffer minimumCapacity(int minimumCapacity); 319 320 /** 321 * @see ByteBuffer#capacity() 322 */ 323 public abstract int capacity(); 324 325 /** 326 * Increases the capacity of this buffer. If the new capacity is less than 327 * or equal to the current capacity, this method returns silently. If the 328 * new capacity is greater than the current capacity, the buffer is 329 * reallocated while retaining the position, limit, mark and the content of 330 * the buffer. 331 */ 332 public abstract IoBuffer capacity(int newCapacity); 333 334 /** 335 * Returns <tt>true</tt> if and only if <tt>autoExpand</tt> is turned on. 336 */ 337 public abstract boolean isAutoExpand(); 338 339 /** 340 * Turns on or off <tt>autoExpand</tt>. 341 */ 342 public abstract IoBuffer setAutoExpand(boolean autoExpand); 343 344 /** 345 * Returns <tt>true</tt> if and only if <tt>autoShrink</tt> is turned on. 346 */ 347 public abstract boolean isAutoShrink(); 348 349 /** 350 * Turns on or off <tt>autoShrink</tt>. 351 */ 352 public abstract IoBuffer setAutoShrink(boolean autoShrink); 353 354 /** 355 * Changes the capacity and limit of this buffer so this buffer get the 356 * specified <tt>expectedRemaining</tt> room from the current position. This 357 * method works even if you didn't set <tt>autoExpand</tt> to <tt>true</tt>. 358 */ 359 public abstract IoBuffer expand(int expectedRemaining); 360 361 /** 362 * Changes the capacity and limit of this buffer so this buffer get the 363 * specified <tt>expectedRemaining</tt> room from the specified 364 * <tt>position</tt>. This method works even if you didn't set 365 * <tt>autoExpand</tt> to <tt>true</tt>. 366 */ 367 public abstract IoBuffer expand(int position, int expectedRemaining); 368 369 /** 370 * Changes the capacity of this buffer so this buffer occupies as less 371 * memory as possible while retaining the position, limit and the buffer 372 * content between the position and limit. The capacity of the buffer never 373 * becomes less than {@link #minimumCapacity()}. The mark is discarded once 374 * the capacity changes. 375 */ 376 public abstract IoBuffer shrink(); 377 378 /** 379 * @see java.nio.Buffer#position() 380 */ 381 public abstract int position(); 382 383 /** 384 * @see java.nio.Buffer#position(int) 385 */ 386 public abstract IoBuffer position(int newPosition); 387 388 /** 389 * @see java.nio.Buffer#limit() 390 */ 391 public abstract int limit(); 392 393 /** 394 * @see java.nio.Buffer#limit(int) 395 */ 396 public abstract IoBuffer limit(int newLimit); 397 398 /** 399 * @see java.nio.Buffer#mark() 400 */ 401 public abstract IoBuffer mark(); 402 403 /** 404 * Returns the position of the current mark. This method returns <tt>-1</tt> 405 * if no mark is set. 406 */ 407 public abstract int markValue(); 408 409 /** 410 * @see java.nio.Buffer#reset() 411 */ 412 public abstract IoBuffer reset(); 413 414 /** 415 * @see java.nio.Buffer#clear() 416 */ 417 public abstract IoBuffer clear(); 418 419 /** 420 * Clears this buffer and fills its content with <tt>NUL</tt>. The position 421 * is set to zero, the limit is set to the capacity, and the mark is 422 * discarded. 423 */ 424 public abstract IoBuffer sweep(); 425 426 /** 427 * double Clears this buffer and fills its content with <tt>value</tt>. The 428 * position is set to zero, the limit is set to the capacity, and the mark 429 * is discarded. 430 */ 431 public abstract IoBuffer sweep(byte value); 432 433 /** 434 * @see java.nio.Buffer#flip() 435 */ 436 public abstract IoBuffer flip(); 437 438 /** 439 * @see java.nio.Buffer#rewind() 440 */ 441 public abstract IoBuffer rewind(); 442 443 /** 444 * @see java.nio.Buffer#remaining() 445 */ 446 public abstract int remaining(); 447 448 /** 449 * @see java.nio.Buffer#hasRemaining() 450 */ 451 public abstract boolean hasRemaining(); 452 453 /** 454 * @see ByteBuffer#duplicate() 455 */ 456 public abstract IoBuffer duplicate(); 457 458 /** 459 * @see ByteBuffer#slice() 460 */ 461 public abstract IoBuffer slice(); 462 463 /** 464 * @see ByteBuffer#asReadOnlyBuffer() 465 */ 466 public abstract IoBuffer asReadOnlyBuffer(); 467 468 /** 469 * @see ByteBuffer#hasArray() 470 */ 471 public abstract boolean hasArray(); 472 473 /** 474 * @see ByteBuffer#array() 475 */ 476 public abstract byte[] array(); 477 478 /** 479 * @see ByteBuffer#arrayOffset() 480 */ 481 public abstract int arrayOffset(); 482 483 /** 484 * @see ByteBuffer#get() 485 */ 486 public abstract byte get(); 487 488 /** 489 * Reads one unsigned byte as a short integer. 490 */ 491 public abstract short getUnsigned(); 492 493 /** 494 * @see ByteBuffer#put(byte) 495 */ 496 public abstract IoBuffer put(byte b); 497 498 /** 499 * @see ByteBuffer#get(int) 500 */ 501 public abstract byte get(int index); 502 503 /** 504 * Reads one byte as an unsigned short integer. 505 */ 506 public abstract short getUnsigned(int index); 507 508 /** 509 * @see ByteBuffer#put(int, byte) 510 */ 511 public abstract IoBuffer put(int index, byte b); 512 513 /** 514 * @see ByteBuffer#get(byte[], int, int) 515 */ 516 public abstract IoBuffer get(byte[] dst, int offset, int length); 517 518 /** 519 * @see ByteBuffer#get(byte[]) 520 */ 521 public abstract IoBuffer get(byte[] dst); 522 523 /** 524 * TODO document me. 525 */ 526 public abstract IoBuffer getSlice(int index, int length); 527 528 /** 529 * TODO document me. 530 */ 531 public abstract IoBuffer getSlice(int length); 532 533 /** 534 * Writes the content of the specified <tt>src</tt> into this buffer. 535 */ 536 public abstract IoBuffer put(ByteBuffer src); 537 538 /** 539 * Writes the content of the specified <tt>src</tt> into this buffer. 540 */ 541 public abstract IoBuffer put(IoBuffer src); 542 543 /** 544 * @see ByteBuffer#put(byte[], int, int) 545 */ 546 public abstract IoBuffer put(byte[] src, int offset, int length); 547 548 /** 549 * @see ByteBuffer#put(byte[]) 550 */ 551 public abstract IoBuffer put(byte[] src); 552 553 /** 554 * @see ByteBuffer#compact() 555 */ 556 public abstract IoBuffer compact(); 557 558 /** 559 * @see ByteBuffer#order() 560 */ 561 public abstract ByteOrder order(); 562 563 /** 564 * @see ByteBuffer#order(ByteOrder) 565 */ 566 public abstract IoBuffer order(ByteOrder bo); 567 568 /** 569 * @see ByteBuffer#getChar() 570 */ 571 public abstract char getChar(); 572 573 /** 574 * @see ByteBuffer#putChar(char) 575 */ 576 public abstract IoBuffer putChar(char value); 577 578 /** 579 * @see ByteBuffer#getChar(int) 580 */ 581 public abstract char getChar(int index); 582 583 /** 584 * @see ByteBuffer#putChar(int, char) 585 */ 586 public abstract IoBuffer putChar(int index, char value); 587 588 /** 589 * @see ByteBuffer#asCharBuffer() 590 */ 591 public abstract CharBuffer asCharBuffer(); 592 593 /** 594 * @see ByteBuffer#getShort() 595 */ 596 public abstract short getShort(); 597 598 /** 599 * Reads two bytes unsigned integer. 600 */ 601 public abstract int getUnsignedShort(); 602 603 /** 604 * @see ByteBuffer#putShort(short) 605 */ 606 public abstract IoBuffer putShort(short value); 607 608 /** 609 * @see ByteBuffer#getShort() 610 */ 611 public abstract short getShort(int index); 612 613 /** 614 * Reads two bytes unsigned integer. 615 */ 616 public abstract int getUnsignedShort(int index); 617 618 /** 619 * @see ByteBuffer#putShort(int, short) 620 */ 621 public abstract IoBuffer putShort(int index, short value); 622 623 /** 624 * @see ByteBuffer#asShortBuffer() 625 */ 626 public abstract ShortBuffer asShortBuffer(); 627 628 /** 629 * @see ByteBuffer#getInt() 630 */ 631 public abstract int getInt(); 632 633 /** 634 * Reads four bytes unsigned integer. 635 */ 636 public abstract long getUnsignedInt(); 637 638 /** 639 * Relative <i>get</i> method for reading a medium int value. 640 * 641 * <p> 642 * Reads the next three bytes at this buffer's current position, composing 643 * them into an int value according to the current byte order, and then 644 * increments the position by three. 645 * </p> 646 * 647 * @return The medium int value at the buffer's current position 648 */ 649 public abstract int getMediumInt(); 650 651 /** 652 * Relative <i>get</i> method for reading an unsigned medium int value. 653 * 654 * <p> 655 * Reads the next three bytes at this buffer's current position, composing 656 * them into an int value according to the current byte order, and then 657 * increments the position by three. 658 * </p> 659 * 660 * @return The unsigned medium int value at the buffer's current position 661 */ 662 public abstract int getUnsignedMediumInt(); 663 664 /** 665 * Absolute <i>get</i> method for reading a medium int value. 666 * 667 * <p> 668 * Reads the next three bytes at this buffer's current position, composing 669 * them into an int value according to the current byte order. 670 * </p> 671 * 672 * @param index 673 * The index from which the medium int will be read 674 * @return The medium int value at the given index 675 * 676 * @throws IndexOutOfBoundsException 677 * If <tt>index</tt> is negative or not smaller than the 678 * buffer's limit 679 */ 680 public abstract int getMediumInt(int index); 681 682 /** 683 * Absolute <i>get</i> method for reading an unsigned medium int value. 684 * 685 * <p> 686 * Reads the next three bytes at this buffer's current position, composing 687 * them into an int value according to the current byte order. 688 * </p> 689 * 690 * @param index 691 * The index from which the unsigned medium int will be read 692 * @return The unsigned medium int value at the given index 693 * 694 * @throws IndexOutOfBoundsException 695 * If <tt>index</tt> is negative or not smaller than the 696 * buffer's limit 697 */ 698 public abstract int getUnsignedMediumInt(int index); 699 700 /** 701 * Relative <i>put</i> method for writing a medium int value. 702 * 703 * <p> 704 * Writes three bytes containing the given int value, in the current byte 705 * order, into this buffer at the current position, and then increments the 706 * position by three. 707 * </p> 708 * 709 * @param value 710 * The medium int value to be written 711 * 712 * @return This buffer 713 * 714 * @throws BufferOverflowException 715 * If there are fewer than three bytes remaining in this buffer 716 * 717 * @throws ReadOnlyBufferException 718 * If this buffer is read-only 719 */ 720 public abstract IoBuffer putMediumInt(int value); 721 722 /** 723 * Absolute <i>put</i> method for writing a medium int value. 724 * 725 * <p> 726 * Writes three bytes containing the given int value, in the current byte 727 * order, into this buffer at the given index. 728 * </p> 729 * 730 * @param index 731 * The index at which the bytes will be written 732 * 733 * @param value 734 * The medium int value to be written 735 * 736 * @return This buffer 737 * 738 * @throws IndexOutOfBoundsException 739 * If <tt>index</tt> is negative or not smaller than the 740 * buffer's limit, minus three 741 * 742 * @throws ReadOnlyBufferException 743 * If this buffer is read-only 744 */ 745 public abstract IoBuffer putMediumInt(int index, int value); 746 747 /** 748 * @see ByteBuffer#putInt(int) 749 */ 750 public abstract IoBuffer putInt(int value); 751 752 /** 753 * @see ByteBuffer#getInt(int) 754 */ 755 public abstract int getInt(int index); 756 757 /** 758 * Reads four bytes unsigned integer. 759 */ 760 public abstract long getUnsignedInt(int index); 761 762 /** 763 * @see ByteBuffer#putInt(int, int) 764 */ 765 public abstract IoBuffer putInt(int index, int value); 766 767 /** 768 * @see ByteBuffer#asIntBuffer() 769 */ 770 public abstract IntBuffer asIntBuffer(); 771 772 /** 773 * @see ByteBuffer#getLong() 774 */ 775 public abstract long getLong(); 776 777 /** 778 * @see ByteBuffer#putLong(int, long) 779 */ 780 public abstract IoBuffer putLong(long value); 781 782 /** 783 * @see ByteBuffer#getLong(int) 784 */ 785 public abstract long getLong(int index); 786 787 /** 788 * @see ByteBuffer#putLong(int, long) 789 */ 790 public abstract IoBuffer putLong(int index, long value); 791 792 /** 793 * @see ByteBuffer#asLongBuffer() 794 */ 795 public abstract LongBuffer asLongBuffer(); 796 797 /** 798 * @see ByteBuffer#getFloat() 799 */ 800 public abstract float getFloat(); 801 802 /** 803 * @see ByteBuffer#putFloat(float) 804 */ 805 public abstract IoBuffer putFloat(float value); 806 807 /** 808 * @see ByteBuffer#getFloat(int) 809 */ 810 public abstract float getFloat(int index); 811 812 /** 813 * @see ByteBuffer#putFloat(int, float) 814 */ 815 public abstract IoBuffer putFloat(int index, float value); 816 817 /** 818 * @see ByteBuffer#asFloatBuffer() 819 */ 820 public abstract FloatBuffer asFloatBuffer(); 821 822 /** 823 * @see ByteBuffer#getDouble() 824 */ 825 public abstract double getDouble(); 826 827 /** 828 * @see ByteBuffer#putDouble(double) 829 */ 830 public abstract IoBuffer putDouble(double value); 831 832 /** 833 * @see ByteBuffer#getDouble(int) 834 */ 835 public abstract double getDouble(int index); 836 837 /** 838 * @see ByteBuffer#putDouble(int, double) 839 */ 840 public abstract IoBuffer putDouble(int index, double value); 841 842 /** 843 * @see ByteBuffer#asDoubleBuffer() 844 */ 845 public abstract DoubleBuffer asDoubleBuffer(); 846 847 /** 848 * Returns an {@link InputStream} that reads the data from this buffer. 849 * {@link InputStream#read()} returns <tt>-1</tt> if the buffer position 850 * reaches to the limit. 851 */ 852 public abstract InputStream asInputStream(); 853 854 /** 855 * Returns an {@link OutputStream} that appends the data into this buffer. 856 * Please note that the {@link OutputStream#write(int)} will throw a 857 * {@link BufferOverflowException} instead of an {@link IOException} in case 858 * of buffer overflow. Please set <tt>autoExpand</tt> property by calling 859 * {@link #setAutoExpand(boolean)} to prevent the unexpected runtime 860 * exception. 861 */ 862 public abstract OutputStream asOutputStream(); 863 864 /** 865 * Returns hexdump of this buffer. The data and pointer are not changed as a 866 * result of this method call. 867 * 868 * @return hexidecimal representation of this buffer 869 */ 870 public abstract String getHexDump(); 871 872 /** 873 * Return hexdump of this buffer with limited length. 874 * 875 * @param lengthLimit 876 * The maximum number of bytes to dump from the current buffer 877 * position. 878 * @return hexidecimal representation of this buffer 879 */ 880 public abstract String getHexDump(int lengthLimit); 881 882 // ////////////////////////////// 883 // String getters and putters // 884 // ////////////////////////////// 885 886 /** 887 * Reads a <code>NUL</code>-terminated string from this buffer using the 888 * specified <code>decoder</code> and returns it. This method reads until 889 * the limit of this buffer if no <tt>NUL</tt> is found. 890 */ 891 public abstract String getString(CharsetDecoder decoder) throws CharacterCodingException; 892 893 /** 894 * Reads a <code>NUL</code>-terminated string from this buffer using the 895 * specified <code>decoder</code> and returns it. 896 * 897 * @param fieldSize 898 * the maximum number of bytes to read 899 */ 900 public abstract String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException; 901 902 /** 903 * Writes the content of <code>in</code> into this buffer using the 904 * specified <code>encoder</code>. This method doesn't terminate string with 905 * <tt>NUL</tt>. You have to do it by yourself. 906 * 907 * @throws BufferOverflowException 908 * if the specified string doesn't fit 909 */ 910 public abstract IoBuffer putString(CharSequence val, CharsetEncoder encoder) throws CharacterCodingException; 911 912 /** 913 * Writes the content of <code>in</code> into this buffer as a 914 * <code>NUL</code>-terminated string using the specified 915 * <code>encoder</code>. 916 * <p> 917 * If the charset name of the encoder is UTF-16, you cannot specify odd 918 * <code>fieldSize</code>, and this method will append two <code>NUL</code>s 919 * as a terminator. 920 * <p> 921 * Please note that this method doesn't terminate with <code>NUL</code> if 922 * the input string is longer than <tt>fieldSize</tt>. 923 * 924 * @param fieldSize 925 * the maximum number of bytes to write 926 */ 927 public abstract IoBuffer putString(CharSequence val, int fieldSize, CharsetEncoder encoder) throws CharacterCodingException; 928 929 /** 930 * Reads a string which has a 16-bit length field before the actual encoded 931 * string, using the specified <code>decoder</code> and returns it. This 932 * method is a shortcut for <tt>getPrefixedString(2, decoder)</tt>. 933 */ 934 public abstract String getPrefixedString(CharsetDecoder decoder) throws CharacterCodingException; 935 936 /** 937 * Reads a string which has a length field before the actual encoded string, 938 * using the specified <code>decoder</code> and returns it. 939 * 940 * @param prefixLength 941 * the length of the length field (1, 2, or 4) 942 */ 943 public abstract String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException; 944 945 /** 946 * Writes the content of <code>in</code> into this buffer as a string which 947 * has a 16-bit length field before the actual encoded string, using the 948 * specified <code>encoder</code>. This method is a shortcut for 949 * <tt>putPrefixedString(in, 2, 0, encoder)</tt>. 950 * 951 * @throws BufferOverflowException 952 * if the specified string doesn't fit 953 */ 954 public abstract IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException; 955 956 /** 957 * Writes the content of <code>in</code> into this buffer as a string which 958 * has a 16-bit length field before the actual encoded string, using the 959 * specified <code>encoder</code>. This method is a shortcut for 960 * <tt>putPrefixedString(in, prefixLength, 0, encoder)</tt>. 961 * 962 * @param prefixLength 963 * the length of the length field (1, 2, or 4) 964 * 965 * @throws BufferOverflowException 966 * if the specified string doesn't fit 967 */ 968 public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder) 969 throws CharacterCodingException; 970 971 /** 972 * Writes the content of <code>in</code> into this buffer as a string which 973 * has a 16-bit length field before the actual encoded string, using the 974 * specified <code>encoder</code>. This method is a shortcut for 975 * <tt>putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)</tt> 976 * . 977 * 978 * @param prefixLength 979 * the length of the length field (1, 2, or 4) 980 * @param padding 981 * the number of padded <tt>NUL</tt>s (1 (or 0), 2, or 4) 982 * 983 * @throws BufferOverflowException 984 * if the specified string doesn't fit 985 */ 986 public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder) 987 throws CharacterCodingException; 988 989 /** 990 * Writes the content of <code>in</code> into this buffer as a string which 991 * has a 16-bit length field before the actual encoded string, using the 992 * specified <code>encoder</code>. 993 * 994 * @param prefixLength 995 * the length of the length field (1, 2, or 4) 996 * @param padding 997 * the number of padded bytes (1 (or 0), 2, or 4) 998 * @param padValue 999 * the value of padded bytes 1000 * 1001 * @throws BufferOverflowException 1002 * if the specified string doesn't fit 1003 */ 1004 public abstract IoBuffer putPrefixedString(CharSequence val, int prefixLength, int padding, byte padValue, 1005 CharsetEncoder encoder) throws CharacterCodingException; 1006 1007 /** 1008 * Reads a Java object from the buffer using the context {@link ClassLoader} 1009 * of the current thread. 1010 */ 1011 public abstract Object getObject() throws ClassNotFoundException; 1012 1013 /** 1014 * Reads a Java object from the buffer using the specified 1015 * <tt>classLoader</tt>. 1016 */ 1017 public abstract Object getObject(final ClassLoader classLoader) throws ClassNotFoundException; 1018 1019 /** 1020 * Writes the specified Java object to the buffer. 1021 */ 1022 public abstract IoBuffer putObject(Object o); 1023 1024 /** 1025 * Returns <tt>true</tt> if this buffer contains a data which has a data 1026 * length as a prefix and the buffer has remaining data as enough as 1027 * specified in the data length field. This method is identical with 1028 * <tt>prefixedDataAvailable( prefixLength, Integer.MAX_VALUE )</tt>. Please 1029 * not that using this method can allow DoS (Denial of Service) attack in 1030 * case the remote peer sends too big data length value. It is recommended 1031 * to use {@link #prefixedDataAvailable(int, int)} instead. 1032 * 1033 * @param prefixLength 1034 * the length of the prefix field (1, 2, or 4) 1035 * 1036 * @throws IllegalArgumentException 1037 * if prefixLength is wrong 1038 * @throws BufferDataException 1039 * if data length is negative 1040 */ 1041 public abstract boolean prefixedDataAvailable(int prefixLength); 1042 1043 /** 1044 * Returns <tt>true</tt> if this buffer contains a data which has a data 1045 * length as a prefix and the buffer has remaining data as enough as 1046 * specified in the data length field. 1047 * 1048 * @param prefixLength 1049 * the length of the prefix field (1, 2, or 4) 1050 * @param maxDataLength 1051 * the allowed maximum of the read data length 1052 * 1053 * @throws IllegalArgumentException 1054 * if prefixLength is wrong 1055 * @throws BufferDataException 1056 * if data length is negative or greater then 1057 * <tt>maxDataLength</tt> 1058 */ 1059 public abstract boolean prefixedDataAvailable(int prefixLength, int maxDataLength); 1060 1061 // /////////////////// 1062 // IndexOf methods // 1063 // /////////////////// 1064 1065 /** 1066 * Returns the first occurence position of the specified byte from the 1067 * current position to the current limit. 1068 * 1069 * @return <tt>-1</tt> if the specified byte is not found 1070 */ 1071 public abstract int indexOf(byte b); 1072 1073 // //////////////////////// 1074 // Skip or fill methods // 1075 // //////////////////////// 1076 1077 /** 1078 * Forwards the position of this buffer as the specified <code>size</code> 1079 * bytes. 1080 */ 1081 public abstract IoBuffer skip(int size); 1082 1083 /** 1084 * Fills this buffer with the specified value. This method moves buffer 1085 * position forward. 1086 */ 1087 public abstract IoBuffer fill(byte value, int size); 1088 1089 /** 1090 * Fills this buffer with the specified value. This method does not change 1091 * buffer position. 1092 */ 1093 public abstract IoBuffer fillAndReset(byte value, int size); 1094 1095 /** 1096 * Fills this buffer with <code>NUL (0x00)</code>. This method moves buffer 1097 * position forward. 1098 */ 1099 public abstract IoBuffer fill(int size); 1100 1101 /** 1102 * Fills this buffer with <code>NUL (0x00)</code>. This method does not 1103 * change buffer position. 1104 */ 1105 public abstract IoBuffer fillAndReset(int size); 1106 1107 // //////////////////////// 1108 // Enum methods // 1109 // //////////////////////// 1110 1111 /** 1112 * Reads a byte from the buffer and returns the correlating enum constant 1113 * defined by the specified enum type. 1114 * 1115 * @param <E> 1116 * The enum type to return 1117 * @param enumClass 1118 * The enum's class object 1119 */ 1120 public abstract <E extends Enum<E>> E getEnum(Class<E> enumClass); 1121 1122 /** 1123 * Reads a byte from the buffer and returns the correlating enum constant 1124 * defined by the specified enum type. 1125 * 1126 * @param <E> 1127 * The enum type to return 1128 * @param index 1129 * the index from which the byte will be read 1130 * @param enumClass 1131 * The enum's class object 1132 */ 1133 public abstract <E extends Enum<E>> E getEnum(int index, Class<E> enumClass); 1134 1135 /** 1136 * Reads a short from the buffer and returns the correlating enum constant 1137 * defined by the specified enum type. 1138 * 1139 * @param <E> 1140 * The enum type to return 1141 * @param enumClass 1142 * The enum's class object 1143 */ 1144 public abstract <E extends Enum<E>> E getEnumShort(Class<E> enumClass); 1145 1146 /** 1147 * Reads a short from the buffer and returns the correlating enum constant 1148 * defined by the specified enum type. 1149 * 1150 * @param <E> 1151 * The enum type to return 1152 * @param index 1153 * the index from which the bytes will be read 1154 * @param enumClass 1155 * The enum's class object 1156 */ 1157 public abstract <E extends Enum<E>> E getEnumShort(int index, Class<E> enumClass); 1158 1159 /** 1160 * Reads an int from the buffer and returns the correlating enum constant 1161 * defined by the specified enum type. 1162 * 1163 * @param <E> 1164 * The enum type to return 1165 * @param enumClass 1166 * The enum's class object 1167 */ 1168 public abstract <E extends Enum<E>> E getEnumInt(Class<E> enumClass); 1169 1170 /** 1171 * Reads an int from the buffer and returns the correlating enum constant 1172 * defined by the specified enum type. 1173 * 1174 * @param <E> 1175 * The enum type to return 1176 * @param index 1177 * the index from which the bytes will be read 1178 * @param enumClass 1179 * The enum's class object 1180 */ 1181 public abstract <E extends Enum<E>> E getEnumInt(int index, Class<E> enumClass); 1182 1183 /** 1184 * Writes an enum's ordinal value to the buffer as a byte. 1185 * 1186 * @param e 1187 * The enum to write to the buffer 1188 */ 1189 public abstract IoBuffer putEnum(Enum<?> e); 1190 1191 /** 1192 * Writes an enum's ordinal value to the buffer as a byte. 1193 * 1194 * @param index 1195 * The index at which the byte will be written 1196 * @param e 1197 * The enum to write to the buffer 1198 */ 1199 public abstract IoBuffer putEnum(int index, Enum<?> e); 1200 1201 /** 1202 * Writes an enum's ordinal value to the buffer as a short. 1203 * 1204 * @param e 1205 * The enum to write to the buffer 1206 */ 1207 public abstract IoBuffer putEnumShort(Enum<?> e); 1208 1209 /** 1210 * Writes an enum's ordinal value to the buffer as a short. 1211 * 1212 * @param index 1213 * The index at which the bytes will be written 1214 * @param e 1215 * The enum to write to the buffer 1216 */ 1217 public abstract IoBuffer putEnumShort(int index, Enum<?> e); 1218 1219 /** 1220 * Writes an enum's ordinal value to the buffer as an integer. 1221 * 1222 * @param e 1223 * The enum to write to the buffer 1224 */ 1225 public abstract IoBuffer putEnumInt(Enum<?> e); 1226 1227 /** 1228 * Writes an enum's ordinal value to the buffer as an integer. 1229 * 1230 * @param index 1231 * The index at which the bytes will be written 1232 * @param e 1233 * The enum to write to the buffer 1234 */ 1235 public abstract IoBuffer putEnumInt(int index, Enum<?> e); 1236 1237 // //////////////////////// 1238 // EnumSet methods // 1239 // //////////////////////// 1240 1241 /** 1242 * Reads a byte sized bit vector and converts it to an {@link EnumSet}. 1243 * 1244 * <p> 1245 * Each bit is mapped to a value in the specified enum. The least 1246 * significant bit maps to the first entry in the specified enum and each 1247 * subsequent bit maps to each subsequent bit as mapped to the subsequent 1248 * enum value. 1249 * </p> 1250 * 1251 * @param <E> 1252 * the enum type 1253 * @param enumClass 1254 * the enum class used to create the EnumSet 1255 * @return the EnumSet representation of the bit vector 1256 */ 1257 public abstract <E extends Enum<E>> EnumSet<E> getEnumSet(Class<E> enumClass); 1258 1259 /** 1260 * Reads a byte sized bit vector and converts it to an {@link EnumSet}. 1261 * 1262 * @see #getEnumSet(Class) 1263 * @param <E> 1264 * the enum type 1265 * @param index 1266 * the index from which the byte will be read 1267 * @param enumClass 1268 * the enum class used to create the EnumSet 1269 * @return the EnumSet representation of the bit vector 1270 */ 1271 public abstract <E extends Enum<E>> EnumSet<E> getEnumSet(int index, Class<E> enumClass); 1272 1273 /** 1274 * Reads a short sized bit vector and converts it to an {@link EnumSet}. 1275 * 1276 * @see #getEnumSet(Class) 1277 * @param <E> 1278 * the enum type 1279 * @param enumClass 1280 * the enum class used to create the EnumSet 1281 * @return the EnumSet representation of the bit vector 1282 */ 1283 public abstract <E extends Enum<E>> EnumSet<E> getEnumSetShort(Class<E> enumClass); 1284 1285 /** 1286 * Reads a short sized bit vector and converts it to an {@link EnumSet}. 1287 * 1288 * @see #getEnumSet(Class) 1289 * @param <E> 1290 * the enum type 1291 * @param index 1292 * the index from which the bytes will be read 1293 * @param enumClass 1294 * the enum class used to create the EnumSet 1295 * @return the EnumSet representation of the bit vector 1296 */ 1297 public abstract <E extends Enum<E>> EnumSet<E> getEnumSetShort(int index, Class<E> enumClass); 1298 1299 /** 1300 * Reads an int sized bit vector and converts it to an {@link EnumSet}. 1301 * 1302 * @see #getEnumSet(Class) 1303 * @param <E> 1304 * the enum type 1305 * @param enumClass 1306 * the enum class used to create the EnumSet 1307 * @return the EnumSet representation of the bit vector 1308 */ 1309 public abstract <E extends Enum<E>> EnumSet<E> getEnumSetInt(Class<E> enumClass); 1310 1311 /** 1312 * Reads an int sized bit vector and converts it to an {@link EnumSet}. 1313 * 1314 * @see #getEnumSet(Class) 1315 * @param <E> 1316 * the enum type 1317 * @param index 1318 * the index from which the bytes will be read 1319 * @param enumClass 1320 * the enum class used to create the EnumSet 1321 * @return the EnumSet representation of the bit vector 1322 */ 1323 public abstract <E extends Enum<E>> EnumSet<E> getEnumSetInt(int index, Class<E> enumClass); 1324 1325 /** 1326 * Reads a long sized bit vector and converts it to an {@link EnumSet}. 1327 * 1328 * @see #getEnumSet(Class) 1329 * @param <E> 1330 * the enum type 1331 * @param enumClass 1332 * the enum class used to create the EnumSet 1333 * @return the EnumSet representation of the bit vector 1334 */ 1335 public abstract <E extends Enum<E>> EnumSet<E> getEnumSetLong(Class<E> enumClass); 1336 1337 /** 1338 * Reads a long sized bit vector and converts it to an {@link EnumSet}. 1339 * 1340 * @see #getEnumSet(Class) 1341 * @param <E> 1342 * the enum type 1343 * @param index 1344 * the index from which the bytes will be read 1345 * @param enumClass 1346 * the enum class used to create the EnumSet 1347 * @return the EnumSet representation of the bit vector 1348 */ 1349 public abstract <E extends Enum<E>> EnumSet<E> getEnumSetLong(int index, Class<E> enumClass); 1350 1351 /** 1352 * Writes the specified {@link Set} to the buffer as a byte sized bit 1353 * vector. 1354 * 1355 * @param <E> 1356 * the enum type of the Set 1357 * @param set 1358 * the enum set to write to the buffer 1359 */ 1360 public abstract <E extends Enum<E>> IoBuffer putEnumSet(Set<E> set); 1361 1362 /** 1363 * Writes the specified {@link Set} to the buffer as a byte sized bit 1364 * vector. 1365 * 1366 * @param <E> 1367 * the enum type of the Set 1368 * @param index 1369 * the index at which the byte will be written 1370 * @param set 1371 * the enum set to write to the buffer 1372 */ 1373 public abstract <E extends Enum<E>> IoBuffer putEnumSet(int index, Set<E> set); 1374 1375 /** 1376 * Writes the specified {@link Set} to the buffer as a short sized bit 1377 * vector. 1378 * 1379 * @param <E> 1380 * the enum type of the Set 1381 * @param set 1382 * the enum set to write to the buffer 1383 */ 1384 public abstract <E extends Enum<E>> IoBuffer putEnumSetShort(Set<E> set); 1385 1386 /** 1387 * Writes the specified {@link Set} to the buffer as a short sized bit 1388 * vector. 1389 * 1390 * @param <E> 1391 * the enum type of the Set 1392 * @param index 1393 * the index at which the bytes will be written 1394 * @param set 1395 * the enum set to write to the buffer 1396 */ 1397 public abstract <E extends Enum<E>> IoBuffer putEnumSetShort(int index, Set<E> set); 1398 1399 /** 1400 * Writes the specified {@link Set} to the buffer as an int sized bit 1401 * vector. 1402 * 1403 * @param <E> 1404 * the enum type of the Set 1405 * @param set 1406 * the enum set to write to the buffer 1407 */ 1408 public abstract <E extends Enum<E>> IoBuffer putEnumSetInt(Set<E> set); 1409 1410 /** 1411 * Writes the specified {@link Set} to the buffer as an int sized bit 1412 * vector. 1413 * 1414 * @param <E> 1415 * the enum type of the Set 1416 * @param index 1417 * the index at which the bytes will be written 1418 * @param set 1419 * the enum set to write to the buffer 1420 */ 1421 public abstract <E extends Enum<E>> IoBuffer putEnumSetInt(int index, Set<E> set); 1422 1423 /** 1424 * Writes the specified {@link Set} to the buffer as a long sized bit 1425 * vector. 1426 * 1427 * @param <E> 1428 * the enum type of the Set 1429 * @param set 1430 * the enum set to write to the buffer 1431 */ 1432 public abstract <E extends Enum<E>> IoBuffer putEnumSetLong(Set<E> set); 1433 1434 /** 1435 * Writes the specified {@link Set} to the buffer as a long sized bit 1436 * vector. 1437 * 1438 * @param <E> 1439 * the enum type of the Set 1440 * @param index 1441 * the index at which the bytes will be written 1442 * @param set 1443 * the enum set to write to the buffer 1444 */ 1445 public abstract <E extends Enum<E>> IoBuffer putEnumSetLong(int index, Set<E> set); 1446 }