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