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