GNU Classpath (0.20) | |
Frames | No Frames |
1: /* ByteBuffer.java -- 2: Copyright (C) 2002, 2003, 2004 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 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 (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 (Object obj) 306: { 307: ByteBuffer other = (ByteBuffer) obj; 308: 309: int num = Math.min(remaining(), other.remaining()); 310: int pos_this = position(); 311: int pos_other = other.position(); 312: 313: for (int count = 0; count < num; count++) 314: { 315: byte a = get(pos_this++); 316: byte b = other.get(pos_other++); 317: 318: if (a == b) 319: continue; 320: 321: if (a < b) 322: return -1; 323: 324: return 1; 325: } 326: 327: return remaining() - other.remaining(); 328: } 329: 330: /** 331: * Returns the byte order of this buffer. 332: */ 333: public final ByteOrder order () 334: { 335: return endian; 336: } 337: 338: /** 339: * Modifies this buffer's byte order. 340: */ 341: public final ByteBuffer order (ByteOrder endian) 342: { 343: this.endian = endian; 344: return this; 345: } 346: 347: /** 348: * Reads the <code>byte</code> at this buffer's current position, 349: * and then increments the position. 350: * 351: * @exception BufferUnderflowException If there are no remaining 352: * <code>byte</code>s in this buffer. 353: */ 354: public abstract byte get (); 355: 356: /** 357: * Writes the <code>byte</code> at this buffer's current position, 358: * and then increments the position. 359: * 360: * @exception BufferOverflowException If there no remaining 361: * <code>byte</code>s in this buffer. 362: * @exception ReadOnlyBufferException If this buffer is read-only. 363: */ 364: public abstract ByteBuffer put (byte b); 365: 366: /** 367: * Absolute get method. 368: * 369: * @exception IndexOutOfBoundsException If index is negative or not smaller 370: * than the buffer's limit. 371: */ 372: public abstract byte get (int index); 373: 374: /** 375: * Absolute put method. 376: * 377: * @exception IndexOutOfBoundsException If index is negative or not smaller 378: * than the buffer's limit. 379: * @exception ReadOnlyBufferException If this buffer is read-only. 380: */ 381: public abstract ByteBuffer put (int index, byte b); 382: 383: /** 384: * Compacts this buffer. 385: * 386: * @exception ReadOnlyBufferException If this buffer is read-only. 387: */ 388: public abstract ByteBuffer compact (); 389: 390: void shiftDown (int dst_offset, int src_offset, int count) 391: { 392: for (int i = 0; i < count; i++) 393: put(dst_offset + i, get(src_offset + i)); 394: } 395: 396: /** 397: * Tells whether or not this buffer is direct. 398: */ 399: public abstract boolean isDirect (); 400: 401: /** 402: * Creates a new <code>ByteBuffer</code> whose content is a shared 403: * subsequence of this buffer's content. 404: */ 405: public abstract ByteBuffer slice (); 406: 407: /** 408: * Creates a new <code>ByteBuffer</code> that shares this buffer's 409: * content. 410: */ 411: public abstract ByteBuffer duplicate (); 412: 413: /** 414: * Creates a new read-only <code>ByteBuffer</code> that shares this 415: * buffer's content. 416: */ 417: public abstract ByteBuffer asReadOnlyBuffer (); 418: 419: /** 420: * Creates a view of this byte buffer as a short buffer. 421: */ 422: public abstract ShortBuffer asShortBuffer (); 423: 424: /** 425: * Creates a view of this byte buffer as a char buffer. 426: */ 427: public abstract CharBuffer asCharBuffer (); 428: 429: /** 430: * Creates a view of this byte buffer as an integer buffer. 431: */ 432: public abstract IntBuffer asIntBuffer (); 433: 434: /** 435: * Creates a view of this byte buffer as a long buffer. 436: */ 437: public abstract LongBuffer asLongBuffer (); 438: 439: /** 440: * Creates a view of this byte buffer as a float buffer. 441: */ 442: public abstract FloatBuffer asFloatBuffer (); 443: 444: /** 445: * Creates a view of this byte buffer as a double buffer. 446: */ 447: public abstract DoubleBuffer asDoubleBuffer (); 448: 449: /** 450: * Relative get method for reading a character value. 451: * 452: * @exception BufferUnderflowException If there are fewer than two bytes 453: * remaining in this buffer. 454: */ 455: public abstract char getChar (); 456: 457: /** 458: * Relative put method for writing a character value. 459: * 460: * @exception BufferOverflowException If this buffer's current position is 461: * not smaller than its limit. 462: */ 463: public abstract ByteBuffer putChar (char value); 464: 465: /** 466: * Absolute get method for reading a character value. 467: * 468: * @exception IndexOutOfBoundsException If there are fewer than two bytes 469: * remaining in this buffer 470: */ 471: public abstract char getChar (int index); 472: 473: /** 474: * Absolute put method for writing a character value. 475: * 476: * @exception IndexOutOfBoundsException If index is negative or not smaller 477: * than the buffer's limit, minus one. 478: */ 479: public abstract ByteBuffer putChar (int index, char value); 480: 481: /** 482: * Relative get method for reading a short value. 483: * 484: * @exception BufferUnderflowException If index is negative or not smaller 485: * than the buffer's limit, minus one. 486: */ 487: public abstract short getShort (); 488: 489: /** 490: * Relative put method for writing a short value. 491: * 492: * @exception BufferOverflowException If this buffer's current position is 493: * not smaller than its limit. 494: */ 495: public abstract ByteBuffer putShort (short value); 496: 497: /** 498: * Absolute get method for reading a short value. 499: * 500: * @exception IndexOutOfBoundsException If there are fewer than two bytes 501: * remaining in this buffer 502: */ 503: public abstract short getShort (int index); 504: 505: /** 506: * Absolute put method for writing a short value. 507: * 508: * @exception IndexOutOfBoundsException If index is negative or not smaller 509: * than the buffer's limit, minus one. 510: */ 511: public abstract ByteBuffer putShort (int index, short value); 512: 513: /** 514: * Relative get method for reading an integer value. 515: * 516: * @exception BufferUnderflowException If there are fewer than four bytes 517: * remaining in this buffer. 518: */ 519: public abstract int getInt (); 520: 521: /** 522: * Relative put method for writing an integer value. 523: * 524: * @exception BufferOverflowException If this buffer's current position is 525: * not smaller than its limit. 526: */ 527: public abstract ByteBuffer putInt (int value); 528: 529: /** 530: * Absolute get method for reading an integer value. 531: * 532: * @exception IndexOutOfBoundsException If index is negative or not smaller 533: * than the buffer's limit, minus three. 534: */ 535: public abstract int getInt (int index); 536: 537: /** 538: * Absolute put method for writing an integer value. 539: * 540: * @exception IndexOutOfBoundsException If index is negative or not smaller 541: * than the buffer's limit, minus three. 542: */ 543: public abstract ByteBuffer putInt (int index, int value); 544: 545: /** 546: * Relative get method for reading a long value. 547: * 548: * @exception BufferUnderflowException If there are fewer than eight bytes 549: * remaining in this buffer. 550: */ 551: public abstract long getLong (); 552: 553: /** 554: * Relative put method for writing a long value. 555: * 556: * @exception BufferOverflowException If this buffer's current position is 557: * not smaller than its limit. 558: */ 559: public abstract ByteBuffer putLong (long value); 560: 561: /** 562: * Absolute get method for reading a long value. 563: * 564: * @exception IndexOutOfBoundsException If index is negative or not smaller 565: * than the buffer's limit, minus seven. 566: */ 567: public abstract long getLong (int index); 568: 569: /** 570: * Absolute put method for writing a float value. 571: * 572: * @exception IndexOutOfBoundsException If index is negative or not smaller 573: * than the buffer's limit, minus seven. 574: */ 575: public abstract ByteBuffer putLong (int index, long value); 576: 577: /** 578: * Relative get method for reading a float value. 579: * 580: * @exception BufferUnderflowException If there are fewer than four bytes 581: * remaining in this buffer. 582: */ 583: public abstract float getFloat (); 584: 585: /** 586: * Relative put method for writing a float value. 587: * 588: * @exception BufferOverflowException If there are fewer than four bytes 589: * remaining in this buffer. 590: */ 591: public abstract ByteBuffer putFloat (float value); 592: 593: /** 594: * Absolute get method for reading a float value. 595: * 596: * @exception IndexOutOfBoundsException If index is negative or not smaller 597: * than the buffer's limit, minus three. 598: */ 599: public abstract float getFloat (int index); 600: 601: /** 602: * Relative put method for writing a float value. 603: * 604: * @exception IndexOutOfBoundsException If index is negative or not smaller 605: * than the buffer's limit, minus three. 606: */ 607: public abstract ByteBuffer putFloat (int index, float value); 608: 609: /** 610: * Relative get method for reading a double value. 611: * 612: * @exception BufferUnderflowException If there are fewer than eight bytes 613: * remaining in this buffer. 614: */ 615: public abstract double getDouble (); 616: 617: /** 618: * Relative put method for writing a double value. 619: * 620: * @exception BufferOverflowException If this buffer's current position is 621: * not smaller than its limit. 622: */ 623: public abstract ByteBuffer putDouble (double value); 624: 625: /** 626: * Absolute get method for reading a double value. 627: * 628: * @exception IndexOutOfBoundsException If index is negative or not smaller 629: * than the buffer's limit, minus seven. 630: */ 631: public abstract double getDouble (int index); 632: 633: /** 634: * Absolute put method for writing a double value. 635: * 636: * @exception IndexOutOfBoundsException If index is negative or not smaller 637: * than the buffer's limit, minus seven. 638: */ 639: public abstract ByteBuffer putDouble (int index, double value); 640: 641: /** 642: * Returns a string summarizing the state of this buffer. 643: */ 644: public String toString () 645: { 646: return getClass ().getName () + 647: "[pos=" + position () + 648: " lim=" + limit () + 649: " cap=" + capacity () + "]"; 650: } 651: }
GNU Classpath (0.20) |