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