GNU Classpath (0.95) | |
Frames | No Frames |
1: /* ByteBuffer.java -- 2: Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.nio; 40: 41: /** 42: * @since 1.4 43: */ 44: public abstract class ByteBuffer extends Buffer 45: implements Comparable<ByteBuffer> 46: { 47: ByteOrder endian = ByteOrder.BIG_ENDIAN; 48: 49: int array_offset; 50: byte[] backing_buffer; 51: 52: ByteBuffer (int capacity, int limit, int position, int mark) 53: { 54: super (capacity, limit, position, mark); 55: } 56: 57: /** 58: * Allocates a new direct byte buffer. 59: */ 60: public static ByteBuffer allocateDirect (int capacity) 61: { 62: return DirectByteBufferImpl.allocate (capacity); 63: } 64: 65: /** 66: * Allocates a new <code>ByteBuffer</code> object with a given capacity. 67: */ 68: public static ByteBuffer allocate (int capacity) 69: { 70: return wrap(new byte[capacity], 0, capacity); 71: } 72: 73: /** 74: * Wraps a <code>byte</code> array into a <code>ByteBuffer</code> 75: * object. 76: * 77: * @exception IndexOutOfBoundsException If the preconditions on the offset 78: * and length parameters do not hold 79: */ 80: public static final ByteBuffer wrap (byte[] array, int offset, int length) 81: { 82: // FIXME: In GCJ and other implementations where arrays may not 83: // move we might consider, at least when offset==0: 84: // return new DirectByteBufferImpl(array, 85: // address_of_data(array) + offset, 86: // length, length, 0, false); 87: // This may be more efficient, mainly because we can then use the 88: // same logic for all ByteBuffers. 89: 90: return new ByteBufferImpl (array, 0, array.length, offset + length, offset, -1, false); 91: } 92: 93: /** 94: * Wraps a <code>byte</code> array into a <code>ByteBuffer</code> 95: * object. 96: */ 97: public static final ByteBuffer wrap (byte[] array) 98: { 99: return wrap (array, 0, array.length); 100: } 101: 102: /** 103: * This method transfers <code>byte</code>s from this buffer into the given 104: * destination array. Before the transfer, it checks if there are fewer than 105: * length <code>byte</code>s remaining in this buffer. 106: * 107: * @param dst The destination array 108: * @param offset The offset within the array of the first <code>byte</code> 109: * to be written; must be non-negative and no larger than dst.length. 110: * @param length The maximum number of bytes to be written to the given array; 111: * must be non-negative and no larger than dst.length - offset. 112: * 113: * @exception BufferUnderflowException If there are fewer than length 114: * <code>byte</code>s remaining in this buffer. 115: * @exception IndexOutOfBoundsException If the preconditions on the offset 116: * and length parameters do not hold. 117: */ 118: public ByteBuffer get (byte[] dst, int offset, int length) 119: { 120: checkArraySize(dst.length, offset, length); 121: checkForUnderflow(length); 122: 123: for (int i = offset; i < offset + length; i++) 124: { 125: dst [i] = get (); 126: } 127: 128: return this; 129: } 130: 131: /** 132: * This method transfers <code>byte</code>s from this buffer into the given 133: * destination array. 134: * 135: * @param dst The byte array to write into. 136: * 137: * @exception BufferUnderflowException If there are fewer than dst.length 138: * <code>byte</code>s remaining in this buffer. 139: */ 140: public ByteBuffer get (byte[] dst) 141: { 142: return get (dst, 0, dst.length); 143: } 144: 145: /** 146: * Writes the content of the the <code>ByteBUFFER</code> src 147: * into the buffer. Before the transfer, it checks if there is fewer than 148: * <code>src.remaining()</code> space remaining in this buffer. 149: * 150: * @param src The source data. 151: * 152: * @exception BufferOverflowException If there is insufficient space in this 153: * buffer for the remaining <code>byte</code>s in the source buffer. 154: * @exception IllegalArgumentException If the source buffer is this buffer. 155: * @exception ReadOnlyBufferException If this buffer is read-only. 156: */ 157: public ByteBuffer put (ByteBuffer src) 158: { 159: if (src == this) 160: throw new IllegalArgumentException (); 161: 162: checkForOverflow(src.remaining()); 163: 164: if (src.remaining () > 0) 165: { 166: byte[] toPut = new byte [src.remaining ()]; 167: src.get (toPut); 168: put (toPut); 169: } 170: 171: return this; 172: } 173: 174: /** 175: * Writes the content of the the <code>byte array</code> src 176: * into the buffer. Before the transfer, it checks if there is fewer than 177: * length space remaining in this buffer. 178: * 179: * @param src The array to copy into the buffer. 180: * @param offset The offset within the array of the first byte to be read; 181: * must be non-negative and no larger than src.length. 182: * @param length The number of bytes to be read from the given array; 183: * must be non-negative and no larger than src.length - offset. 184: * 185: * @exception BufferOverflowException If there is insufficient space in this 186: * buffer for the remaining <code>byte</code>s in the source array. 187: * @exception IndexOutOfBoundsException If the preconditions on the offset 188: * and length parameters do not hold 189: * @exception ReadOnlyBufferException If this buffer is read-only. 190: */ 191: public ByteBuffer put (byte[] src, int offset, int length) 192: { 193: checkArraySize(src.length, offset, length); 194: checkForOverflow(length); 195: 196: for (int i = offset; i < offset + length; i++) 197: put (src [i]); 198: 199: return this; 200: } 201: 202: /** 203: * Writes the content of the the <code>byte array</code> src 204: * into the buffer. 205: * 206: * @param src The array to copy into the buffer. 207: * 208: * @exception BufferOverflowException If there is insufficient space in this 209: * buffer for the remaining <code>byte</code>s in the source array. 210: * @exception ReadOnlyBufferException If this buffer is read-only. 211: */ 212: public final ByteBuffer put (byte[] src) 213: { 214: return put (src, 0, src.length); 215: } 216: 217: /** 218: * Tells whether ot not this buffer is backed by an accessible 219: * <code>byte</code> array. 220: */ 221: public final boolean hasArray () 222: { 223: return (backing_buffer != null 224: && !isReadOnly ()); 225: } 226: 227: /** 228: * Returns the <code>byte</code> array that backs this buffer. 229: * 230: * @exception ReadOnlyBufferException If this buffer is read-only. 231: * @exception UnsupportedOperationException If this buffer is not backed 232: * by an accessible array. 233: */ 234: public final byte[] array () 235: { 236: if (backing_buffer == null) 237: throw new UnsupportedOperationException (); 238: 239: checkIfReadOnly(); 240: 241: return backing_buffer; 242: } 243: 244: /** 245: * Returns the offset within this buffer's backing array of the first element. 246: * 247: * @exception ReadOnlyBufferException If this buffer is read-only. 248: * @exception UnsupportedOperationException If this buffer is not backed 249: * by an accessible array. 250: */ 251: public final int arrayOffset () 252: { 253: if (backing_buffer == null) 254: throw new UnsupportedOperationException (); 255: 256: checkIfReadOnly(); 257: 258: return array_offset; 259: } 260: 261: /** 262: * Calculates a hash code for this buffer. 263: * 264: * This is done with <code>int</code> arithmetic, 265: * where ** represents exponentiation, by this formula:<br> 266: * <code>s[position()] + 31 + (s[position()+1] + 30)*31**1 + ... + 267: * (s[limit()-1]+30)*31**(limit()-1)</code>. 268: * Where s is the buffer data. Note that the hashcode is dependent 269: * on buffer content, and therefore is not useful if the buffer 270: * content may change. 271: * 272: * @return the hash code 273: */ 274: public int hashCode () 275: { 276: int hashCode = get(position()) + 31; 277: int multiplier = 1; 278: for (int i = position() + 1; i < limit(); ++i) 279: { 280: multiplier *= 31; 281: hashCode += (get(i) + 30)*multiplier; 282: } 283: return hashCode; 284: } 285: 286: /** 287: * Checks if this buffer is equal to obj. 288: */ 289: public boolean equals (Object obj) 290: { 291: if (obj instanceof ByteBuffer) 292: { 293: return compareTo ((ByteBuffer) obj) == 0; 294: } 295: 296: return false; 297: } 298: 299: /** 300: * Compares two <code>ByteBuffer</code> objects. 301: * 302: * @exception ClassCastException If obj is not an object derived from 303: * <code>ByteBuffer</code>. 304: */ 305: public int compareTo (ByteBuffer other) 306: { 307: int num = Math.min(remaining(), other.remaining()); 308: int pos_this = position(); 309: int pos_other = other.position(); 310: 311: for (int count = 0; count < num; count++) 312: { 313: byte a = get(pos_this++); 314: byte b = other.get(pos_other++); 315: 316: if (a == b) 317: continue; 318: 319: if (a < b) 320: return -1; 321: 322: return 1; 323: } 324: 325: return remaining() - other.remaining(); 326: } 327: 328: /** 329: * Returns the byte order of this buffer. 330: */ 331: public final ByteOrder order () 332: { 333: return endian; 334: } 335: 336: /** 337: * Modifies this buffer's byte order. 338: */ 339: public final ByteBuffer order (ByteOrder endian) 340: { 341: this.endian = endian; 342: return this; 343: } 344: 345: /** 346: * Reads the <code>byte</code> at this buffer's current position, 347: * and then increments the position. 348: * 349: * @exception BufferUnderflowException If there are no remaining 350: * <code>byte</code>s in this buffer. 351: */ 352: public abstract byte get (); 353: 354: /** 355: * Writes the <code>byte</code> at this buffer's current position, 356: * and then increments the position. 357: * 358: * @exception BufferOverflowException If there no remaining 359: * <code>byte</code>s in this buffer. 360: * @exception ReadOnlyBufferException If this buffer is read-only. 361: */ 362: public abstract ByteBuffer put (byte b); 363: 364: /** 365: * Absolute get method. 366: * 367: * @exception IndexOutOfBoundsException If index is negative or not smaller 368: * than the buffer's limit. 369: */ 370: public abstract byte get (int index); 371: 372: /** 373: * Absolute put method. 374: * 375: * @exception IndexOutOfBoundsException If index is negative or not smaller 376: * than the buffer's limit. 377: * @exception ReadOnlyBufferException If this buffer is read-only. 378: */ 379: public abstract ByteBuffer put (int index, byte b); 380: 381: /** 382: * Compacts this buffer. 383: * 384: * @exception ReadOnlyBufferException If this buffer is read-only. 385: */ 386: public abstract ByteBuffer compact (); 387: 388: void shiftDown (int dst_offset, int src_offset, int count) 389: { 390: for (int i = 0; i < count; i++) 391: put(dst_offset + i, get(src_offset + i)); 392: } 393: 394: /** 395: * Tells whether or not this buffer is direct. 396: */ 397: public abstract boolean isDirect (); 398: 399: /** 400: * Creates a new <code>ByteBuffer</code> whose content is a shared 401: * subsequence of this buffer's content. 402: */ 403: public abstract ByteBuffer slice (); 404: 405: /** 406: * Creates a new <code>ByteBuffer</code> that shares this buffer's 407: * content. 408: */ 409: public abstract ByteBuffer duplicate (); 410: 411: /** 412: * Creates a new read-only <code>ByteBuffer</code> that shares this 413: * buffer's content. 414: */ 415: public abstract ByteBuffer asReadOnlyBuffer (); 416: 417: /** 418: * Creates a view of this byte buffer as a short buffer. 419: */ 420: public abstract ShortBuffer asShortBuffer (); 421: 422: /** 423: * Creates a view of this byte buffer as a char buffer. 424: */ 425: public abstract CharBuffer asCharBuffer (); 426: 427: /** 428: * Creates a view of this byte buffer as an integer buffer. 429: */ 430: public abstract IntBuffer asIntBuffer (); 431: 432: /** 433: * Creates a view of this byte buffer as a long buffer. 434: */ 435: public abstract LongBuffer asLongBuffer (); 436: 437: /** 438: * Creates a view of this byte buffer as a float buffer. 439: */ 440: public abstract FloatBuffer asFloatBuffer (); 441: 442: /** 443: * Creates a view of this byte buffer as a double buffer. 444: */ 445: public abstract DoubleBuffer asDoubleBuffer (); 446: 447: /** 448: * Relative get method for reading a character value. 449: * 450: * @exception BufferUnderflowException If there are fewer than two bytes 451: * remaining in this buffer. 452: */ 453: public abstract char getChar (); 454: 455: /** 456: * Relative put method for writing a character value. 457: * 458: * @exception BufferOverflowException If this buffer's current position is 459: * not smaller than its limit. 460: */ 461: public abstract ByteBuffer putChar (char value); 462: 463: /** 464: * Absolute get method for reading a character value. 465: * 466: * @exception IndexOutOfBoundsException If there are fewer than two bytes 467: * remaining in this buffer 468: */ 469: public abstract char getChar (int index); 470: 471: /** 472: * Absolute put method for writing a character value. 473: * 474: * @exception IndexOutOfBoundsException If index is negative or not smaller 475: * than the buffer's limit, minus one. 476: */ 477: public abstract ByteBuffer putChar (int index, char value); 478: 479: /** 480: * Relative get method for reading a short value. 481: * 482: * @exception BufferUnderflowException If index is negative or not smaller 483: * than the buffer's limit, minus one. 484: */ 485: public abstract short getShort (); 486: 487: /** 488: * Relative put method for writing a short value. 489: * 490: * @exception BufferOverflowException If this buffer's current position is 491: * not smaller than its limit. 492: */ 493: public abstract ByteBuffer putShort (short value); 494: 495: /** 496: * Absolute get method for reading a short value. 497: * 498: * @exception IndexOutOfBoundsException If there are fewer than two bytes 499: * remaining in this buffer 500: */ 501: public abstract short getShort (int index); 502: 503: /** 504: * Absolute put method for writing a short value. 505: * 506: * @exception IndexOutOfBoundsException If index is negative or not smaller 507: * than the buffer's limit, minus one. 508: */ 509: public abstract ByteBuffer putShort (int index, short value); 510: 511: /** 512: * Relative get method for reading an integer value. 513: * 514: * @exception BufferUnderflowException If there are fewer than four bytes 515: * remaining in this buffer. 516: */ 517: public abstract int getInt (); 518: 519: /** 520: * Relative put method for writing an integer value. 521: * 522: * @exception BufferOverflowException If this buffer's current position is 523: * not smaller than its limit. 524: */ 525: public abstract ByteBuffer putInt (int value); 526: 527: /** 528: * Absolute get method for reading an integer value. 529: * 530: * @exception IndexOutOfBoundsException If index is negative or not smaller 531: * than the buffer's limit, minus three. 532: */ 533: public abstract int getInt (int index); 534: 535: /** 536: * Absolute put method for writing an integer value. 537: * 538: * @exception IndexOutOfBoundsException If index is negative or not smaller 539: * than the buffer's limit, minus three. 540: */ 541: public abstract ByteBuffer putInt (int index, int value); 542: 543: /** 544: * Relative get method for reading a long value. 545: * 546: * @exception BufferUnderflowException If there are fewer than eight bytes 547: * remaining in this buffer. 548: */ 549: public abstract long getLong (); 550: 551: /** 552: * Relative put method for writing a long value. 553: * 554: * @exception BufferOverflowException If this buffer's current position is 555: * not smaller than its limit. 556: */ 557: public abstract ByteBuffer putLong (long value); 558: 559: /** 560: * Absolute get method for reading a long value. 561: * 562: * @exception IndexOutOfBoundsException If index is negative or not smaller 563: * than the buffer's limit, minus seven. 564: */ 565: public abstract long getLong (int index); 566: 567: /** 568: * Absolute put method for writing a float value. 569: * 570: * @exception IndexOutOfBoundsException If index is negative or not smaller 571: * than the buffer's limit, minus seven. 572: */ 573: public abstract ByteBuffer putLong (int index, long value); 574: 575: /** 576: * Relative get method for reading a float value. 577: * 578: * @exception BufferUnderflowException If there are fewer than four bytes 579: * remaining in this buffer. 580: */ 581: public abstract float getFloat (); 582: 583: /** 584: * Relative put method for writing a float value. 585: * 586: * @exception BufferOverflowException If there are fewer than four bytes 587: * remaining in this buffer. 588: */ 589: public abstract ByteBuffer putFloat (float value); 590: 591: /** 592: * Absolute get method for reading a float value. 593: * 594: * @exception IndexOutOfBoundsException If index is negative or not smaller 595: * than the buffer's limit, minus three. 596: */ 597: public abstract float getFloat (int index); 598: 599: /** 600: * Relative put method for writing a float value. 601: * 602: * @exception IndexOutOfBoundsException If index is negative or not smaller 603: * than the buffer's limit, minus three. 604: */ 605: public abstract ByteBuffer putFloat (int index, float value); 606: 607: /** 608: * Relative get method for reading a double value. 609: * 610: * @exception BufferUnderflowException If there are fewer than eight bytes 611: * remaining in this buffer. 612: */ 613: public abstract double getDouble (); 614: 615: /** 616: * Relative put method for writing a double value. 617: * 618: * @exception BufferOverflowException If this buffer's current position is 619: * not smaller than its limit. 620: */ 621: public abstract ByteBuffer putDouble (double value); 622: 623: /** 624: * Absolute get method for reading a double value. 625: * 626: * @exception IndexOutOfBoundsException If index is negative or not smaller 627: * than the buffer's limit, minus seven. 628: */ 629: public abstract double getDouble (int index); 630: 631: /** 632: * Absolute put method for writing a double value. 633: * 634: * @exception IndexOutOfBoundsException If index is negative or not smaller 635: * than the buffer's limit, minus seven. 636: */ 637: public abstract ByteBuffer putDouble (int index, double value); 638: 639: /** 640: * Returns a string summarizing the state of this buffer. 641: */ 642: public String toString () 643: { 644: return getClass ().getName () + 645: "[pos=" + position () + 646: " lim=" + limit () + 647: " cap=" + capacity () + "]"; 648: } 649: }
GNU Classpath (0.95) |