Source for java.nio.CharBuffer

   1: /* CharBuffer.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 CharBuffer extends Buffer
  45:   implements Comparable, CharSequence
  46: {
  47:   int array_offset;
  48:   char[] backing_buffer;
  49: 
  50:   CharBuffer (int capacity, int limit, int position, int mark)
  51:   {
  52:     super (capacity, limit, position, mark);
  53:     array_offset = 0;
  54:   }
  55: 
  56:   /**
  57:    * Allocates a new <code>CharBuffer</code> object with a given capacity.
  58:    */
  59:   public static CharBuffer allocate (int capacity)
  60:   {
  61:     return new CharBufferImpl (capacity);
  62:   }
  63: 
  64:   /**
  65:    * Wraps a <code>char</code> array into a <code>CharBuffer</code>
  66:    * object.
  67:    *
  68:    * @param array the array to wrap
  69:    * @param offset the offset of the region in the array to wrap
  70:    * @param length the length of the region in the array to wrap
  71:    *
  72:    * @return a new <code>CharBuffer</code> object
  73:    * 
  74:    * @exception IndexOutOfBoundsException If the preconditions on the offset
  75:    * and length parameters do not hold
  76:    */
  77:   public static final CharBuffer wrap(char[] array, int offset, int length)
  78:   {
  79:     return new CharBufferImpl(array, 0, array.length, offset + length, offset, -1, false);
  80:   }
  81:   
  82:   /**
  83:    * Wraps a character sequence into a <code>CharBuffer</code> object.
  84:    *
  85:    * @param seq the sequence to wrap
  86:    *
  87:    * @return a new <code>CharBuffer</code> object
  88:    */
  89:   public static final CharBuffer wrap(CharSequence seq)
  90:   {
  91:     return wrap(seq, 0, seq.length());
  92:   }
  93:   
  94:   /**
  95:    * Wraps a character sequence into a <code>CharBuffer</code> object.
  96:    * 
  97:    * @param seq the sequence to wrap
  98:    * @param start the index of the first character to wrap
  99:    * @param end the index of the first character not to wrap
 100:    *
 101:    * @return a new <code>CharBuffer</code> object
 102:    * 
 103:    * @exception IndexOutOfBoundsException If the preconditions on the offset
 104:    * and length parameters do not hold
 105:    */
 106:   public static final CharBuffer wrap(CharSequence seq, int start, int end)
 107:   {
 108:     // FIXME: implement better handling of java.lang.String.
 109:     // Probably share data with String via reflection.
 110:       
 111:     if ((start < 0)
 112:         || (start > seq.length())
 113:         || (end < start)
 114:         || (end > (seq.length() - start)))
 115:       throw new IndexOutOfBoundsException();
 116:     
 117:     int len = end - start;
 118:     char[] buffer = new char[len];
 119:     
 120:     for (int i = 0; i < len; i++)
 121:       buffer[i] = seq.charAt(i + start);
 122:     
 123:     return wrap(buffer, 0, len).asReadOnlyBuffer();
 124:   }
 125: 
 126:   /**
 127:    * Wraps a <code>char</code> array into a <code>CharBuffer</code>
 128:    * object.
 129:    *
 130:    * @param array the array to wrap
 131:    *
 132:    * @return a new <code>CharBuffer</code> object
 133:    */
 134:   public static final CharBuffer wrap(char[] array)
 135:   {
 136:     return wrap(array, 0, array.length);
 137:   }
 138:   
 139:   /**
 140:    * This method transfers <code>char</code>s from this buffer into the given
 141:    * destination array. Before the transfer, it checks if there are fewer than
 142:    * length <code>char</code>s remaining in this buffer. 
 143:    *
 144:    * @param dst The destination array
 145:    * @param offset The offset within the array of the first <code>char</code>
 146:    * to be written; must be non-negative and no larger than dst.length.
 147:    * @param length The maximum number of bytes to be written to the given array;
 148:    * must be non-negative and no larger than dst.length - offset.
 149:    *
 150:    * @exception BufferUnderflowException If there are fewer than length
 151:    * <code>char</code>s remaining in this buffer.
 152:    * @exception IndexOutOfBoundsException If the preconditions on the offset
 153:    * and length parameters do not hold.
 154:    */
 155:   public CharBuffer get (char[] dst, int offset, int length)
 156:   {
 157:     checkArraySize(dst.length, offset, length);
 158:     checkForUnderflow(length);
 159: 
 160:     for (int i = offset; i < offset + length; i++)
 161:       {
 162:         dst [i] = get ();
 163:       }
 164: 
 165:     return this;
 166:   }
 167: 
 168:   /**
 169:    * This method transfers <code>char</code>s from this buffer into the given
 170:    * destination array.
 171:    *
 172:    * @param dst The byte array to write into.
 173:    *
 174:    * @exception BufferUnderflowException If there are fewer than dst.length
 175:    * <code>char</code>s remaining in this buffer.
 176:    */
 177:   public CharBuffer get (char[] dst)
 178:   {
 179:     return get (dst, 0, dst.length);
 180:   }
 181: 
 182:   /**
 183:    * Writes the content of the the <code>CharBUFFER</code> src
 184:    * into the buffer. Before the transfer, it checks if there is fewer than
 185:    * <code>src.remaining()</code> space remaining in this buffer.
 186:    *
 187:    * @param src The source data.
 188:    *
 189:    * @exception BufferOverflowException If there is insufficient space in this
 190:    * buffer for the remaining <code>char</code>s in the source buffer.
 191:    * @exception IllegalArgumentException If the source buffer is this buffer.
 192:    * @exception ReadOnlyBufferException If this buffer is read-only.
 193:    */
 194:   public CharBuffer put (CharBuffer src)
 195:   {
 196:     if (src == this)
 197:       throw new IllegalArgumentException ();
 198: 
 199:     checkForOverflow(src.remaining());
 200: 
 201:     if (src.remaining () > 0)
 202:       {
 203:         char[] toPut = new char [src.remaining ()];
 204:         src.get (toPut);
 205:     put (toPut);
 206:       }
 207: 
 208:     return this;
 209:   }
 210: 
 211:   /**
 212:    * Writes the content of the the <code>char array</code> src
 213:    * into the buffer. Before the transfer, it checks if there is fewer than
 214:    * length space remaining in this buffer.
 215:    *
 216:    * @param src The array to copy into the buffer.
 217:    * @param offset The offset within the array of the first byte to be read;
 218:    * must be non-negative and no larger than src.length.
 219:    * @param length The number of bytes to be read from the given array;
 220:    * must be non-negative and no larger than src.length - offset.
 221:    * 
 222:    * @exception BufferOverflowException If there is insufficient space in this
 223:    * buffer for the remaining <code>char</code>s in the source array.
 224:    * @exception IndexOutOfBoundsException If the preconditions on the offset
 225:    * and length parameters do not hold
 226:    * @exception ReadOnlyBufferException If this buffer is read-only.
 227:    */
 228:   public CharBuffer put (char[] src, int offset, int length)
 229:   {
 230:     checkArraySize(src.length, offset, length);
 231:     checkForOverflow(length);
 232:             
 233:     for (int i = offset; i < offset + length; i++)
 234:       put (src [i]);
 235: 
 236:     return this;
 237:   }
 238: 
 239:   /**
 240:    * Writes the content of the the <code>char array</code> src
 241:    * into the buffer.
 242:    *
 243:    * @param src The array to copy into the buffer.
 244:    * 
 245:    * @exception BufferOverflowException If there is insufficient space in this
 246:    * buffer for the remaining <code>char</code>s in the source array.
 247:    * @exception ReadOnlyBufferException If this buffer is read-only.
 248:    */
 249:   public final CharBuffer put (char[] src)
 250:   {
 251:     return put (src, 0, src.length);
 252:   }
 253: 
 254:   /**
 255:    * Tells whether ot not this buffer is backed by an accessible
 256:    * <code>char</code> array.
 257:    */
 258:   public final boolean hasArray ()
 259:   {
 260:     return (backing_buffer != null
 261:             && !isReadOnly ());
 262:   }
 263: 
 264:   /**
 265:    * Returns the <code>char</code> array that backs this buffer.
 266:    *
 267:    * @exception ReadOnlyBufferException If this buffer is read-only.
 268:    * @exception UnsupportedOperationException If this buffer is not backed
 269:    * by an accessible array.
 270:    */
 271:   public final char[] array ()
 272:   {
 273:     if (backing_buffer == null)
 274:       throw new UnsupportedOperationException ();
 275: 
 276:     checkIfReadOnly();
 277: 
 278:     return backing_buffer;
 279:   }
 280: 
 281:   /**
 282:    * Returns the offset within this buffer's backing array of the first element.
 283:    *
 284:    * @exception ReadOnlyBufferException If this buffer is read-only.
 285:    * @exception UnsupportedOperationException If this buffer is not backed
 286:    * by an accessible array.
 287:    */
 288:   public final int arrayOffset ()
 289:   {
 290:     if (backing_buffer == null)
 291:       throw new UnsupportedOperationException ();
 292: 
 293:     checkIfReadOnly();
 294:     
 295:     return array_offset;
 296:   }
 297: 
 298:   /**
 299:    * Calculates a hash code for this buffer.
 300:    *
 301:    * This is done with int arithmetic,
 302:    * where ** represents exponentiation, by this formula:<br>
 303:    * <code>s[position()] + 31 + (s[position()+1] + 30)*31**1 + ... +
 304:    * (s[limit()-1]+30)*31**(limit()-1)</code>.
 305:    * Where s is the buffer data. Note that the hashcode is dependent
 306:    * on buffer content, and therefore is not useful if the buffer
 307:    * content may change.
 308:    */
 309:   public int hashCode ()
 310:   {
 311:     int hashCode = get(position()) + 31;
 312:     int multiplier = 1;
 313:     for (int i = position() + 1; i < limit(); ++i)
 314:       {
 315:       multiplier *= 31;
 316:       hashCode += (get(i) + 30)*multiplier;
 317:       }
 318:     return hashCode;
 319:   }
 320: 
 321:   /**
 322:    * Checks if this buffer is equal to obj.
 323:    */
 324:   public boolean equals (Object obj)
 325:   {
 326:     if (obj instanceof CharBuffer)
 327:       {
 328:         return compareTo (obj) == 0;
 329:       }
 330: 
 331:     return false;
 332:   }
 333: 
 334:   /**
 335:    * Compares two <code>CharBuffer</code> objects.
 336:    *
 337:    * @exception ClassCastException If obj is not an object derived from
 338:    * <code>CharBuffer</code>.
 339:    */
 340:   public int compareTo (Object obj)
 341:   {
 342:     CharBuffer other = (CharBuffer) obj;
 343: 
 344:     int num = Math.min(remaining(), other.remaining());
 345:     int pos_this = position();
 346:     int pos_other = other.position();
 347:     
 348:     for (int count = 0; count < num; count++)
 349:       {
 350:      char a = get(pos_this++);
 351:      char b = other.get(pos_other++);
 352:            
 353:      if (a == b)
 354:        continue;
 355:              
 356:      if (a < b)
 357:        return -1;
 358:              
 359:      return 1;
 360:       }
 361:       
 362:      return remaining() - other.remaining();
 363:   }
 364: 
 365:   /**
 366:    * Returns the byte order of this buffer.
 367:    */
 368:   public abstract ByteOrder order ();
 369: 
 370:   /**
 371:    * Reads the <code>char</code> at this buffer's current position,
 372:    * and then increments the position.
 373:    *
 374:    * @exception BufferUnderflowException If there are no remaining
 375:    * <code>char</code>s in this buffer.
 376:    */
 377:   public abstract char get ();
 378: 
 379:   /**
 380:    * Writes the <code>char</code> at this buffer's current position,
 381:    * and then increments the position.
 382:    *
 383:    * @exception BufferOverflowException If there no remaining 
 384:    * <code>char</code>s in this buffer.
 385:    * @exception ReadOnlyBufferException If this buffer is read-only.
 386:    */
 387:   public abstract CharBuffer put (char b);
 388: 
 389:   /**
 390:    * Absolute get method.
 391:    *
 392:    * @exception IndexOutOfBoundsException If index is negative or not smaller
 393:    * than the buffer's limit.
 394:    */
 395:   public abstract char get (int index);
 396:   
 397:   /**
 398:    * Absolute put method.
 399:    *
 400:    * @exception IndexOutOfBoundsException If index is negative or not smaller
 401:    * than the buffer's limit.
 402:    * @exception ReadOnlyBufferException If this buffer is read-only.
 403:    */
 404:   public abstract CharBuffer put (int index, char b);
 405: 
 406:   /**
 407:    * Compacts this buffer.
 408:    * 
 409:    * @exception ReadOnlyBufferException If this buffer is read-only.
 410:    */
 411:   public abstract CharBuffer compact ();
 412: 
 413:   /**
 414:    * Tells wether or not this buffer is direct.
 415:    */
 416:   public abstract boolean isDirect ();
 417: 
 418:   /**
 419:    * Creates a new <code>CharBuffer</code> whose content is a shared
 420:    * subsequence of this buffer's content.
 421:    */
 422:   public abstract CharBuffer slice ();
 423: 
 424:   /**
 425:    * Creates a new <code>CharBuffer</code> that shares this buffer's
 426:    * content.
 427:    */
 428:   public abstract CharBuffer duplicate ();
 429: 
 430:   /**
 431:    * Creates a new read-only <code>CharBuffer</code> that shares this
 432:    * buffer's content.
 433:    */
 434:   public abstract CharBuffer asReadOnlyBuffer ();
 435:   
 436:   /**
 437:    * Returns the remaining content of the buffer as a string.
 438:    */
 439:   public String toString ()
 440:   {
 441:     if (hasArray ())
 442:       return new String (array (), position (), length ());
 443: 
 444:     char[] buf = new char [length ()];
 445:     int pos = position ();
 446:     get (buf, 0, buf.length);
 447:     position (pos);
 448:     return new String (buf);
 449:   }
 450: 
 451:   /**
 452:    * Returns the length of the remaining chars in this buffer.
 453:    */
 454:   public final int length ()
 455:   { 
 456:     return remaining ();
 457:   }
 458: 
 459:   /**
 460:    * Creates a new character buffer that represents the specified subsequence
 461:    * of this buffer, relative to the current position.
 462:    *
 463:    * @exception IndexOutOfBoundsException If the preconditions on start and
 464:    * end do not hold.
 465:    */
 466:   public abstract CharSequence subSequence (int start, int length);
 467: 
 468:   /**
 469:    * Relative put method.
 470:    * 
 471:    * @exception BufferOverflowException If there is insufficient space in this
 472:    * buffer.
 473:    * @exception IndexOutOfBoundsException If the preconditions on the start
 474:    * and end parameters do not hold.
 475:    * @exception ReadOnlyBufferException If this buffer is read-only.
 476:    */
 477:   public CharBuffer put (String str, int start, int length)
 478:   {
 479:     return put (str.toCharArray (), start, length);
 480:   }
 481:   
 482:   /**
 483:    * Relative put method.
 484:    * 
 485:    * @exception BufferOverflowException If there is insufficient space in this
 486:    * buffer.
 487:    * @exception ReadOnlyBufferException If this buffer is read-only.
 488:    */
 489:   public final CharBuffer put (String str)
 490:   {
 491:     return put (str.toCharArray (), 0, str.length ());
 492:   }
 493:   
 494:   /**
 495:    * Returns the character at <code>position() + index</code>.
 496:    * 
 497:    * @exception IndexOutOfBoundsException If index is negative not smaller than
 498:    * <code>remaining()</code>.
 499:    */
 500:   public final char charAt (int index)
 501:   {
 502:     if (index < 0
 503:         || index >= remaining ())
 504:       throw new IndexOutOfBoundsException ();
 505:     
 506:     return get (position () + index);
 507:   }
 508: }