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