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