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