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