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