Source for java.nio.ByteBuffer

   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: }