home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / sybase / starbuck / java.z / StringBuffer.java < prev    next >
Text File  |  1996-05-03  |  14KB  |  465 lines

  1. /*
  2.  * @(#)StringBuffer.java    1.28 96/02/14  
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.lang;
  21.  
  22. /**
  23.  * This Class is a growable buffer for characters. It is mainly used
  24.  * to create Strings. The compiler uses it to implement the "+" operator.
  25.  * For example:
  26.  * <pre>
  27.  *    "a" + 4 + "c"
  28.  * </pre>
  29.  * is compiled to:
  30.  * <pre>
  31.  *    new StringBuffer().append("a").append(4).append("c").toString()
  32.  * </pre>
  33.  * 
  34.  * Note that the method toString() does not create a copy of the internal buffer. Instead
  35.  * the buffer is marked as shared. Any further changes to the buffer will
  36.  * cause a copy to be made. <p>
  37.  *
  38.  * @see        String
  39.  * @see        java.io.ByteArrayOutputStream
  40.  * @version     1.28, 14 Feb 1996
  41.  * @author    Arthur van Hoff
  42.  */
  43.  
  44. public final class StringBuffer {
  45.     /** The value is used for character storage. */
  46.     private char value[];
  47.  
  48.     /** The count is the number of characters in the buffer. */
  49.     private int count;
  50.  
  51.     /** A flag indicating whether the buffer is shared */
  52.     private boolean shared;
  53.  
  54.     /**
  55.      * Constructs an empty String buffer.
  56.      */
  57.     public StringBuffer() {
  58.     this(16);
  59.     }
  60.  
  61.     /**
  62.      * Constructs an empty String buffer with the specified initial length.
  63.      * @param length    the initial length
  64.      */
  65.     public StringBuffer(int length) {
  66.     value = new char[length];
  67.     shared = false;
  68.     }
  69.  
  70.     /**
  71.      * Constructs a String buffer with the specified initial value.
  72.      * @param str    the initial value of the buffer
  73.      */
  74.     public StringBuffer(String str) {
  75.     this(str.length() + 16);
  76.     append(str);
  77.     }
  78.  
  79.     /**
  80.      * Returns the length (character count) of the buffer.
  81.      */
  82.     public int length() {
  83.     return count;
  84.     }
  85.  
  86.     /**
  87.      * Returns the current capacity of the String buffer. The capacity
  88.      * is the amount of storage available for newly inserted
  89.      * characters; beyond which an allocation will occur.
  90.      */
  91.     public int capacity() {
  92.     return value.length;
  93.     }
  94.  
  95.     /**
  96.      * Copies the buffer value if it is shared.
  97.      */
  98.     private final void copyWhenShared() {
  99.     if (shared) {
  100.         char newValue[] = new char[value.length];
  101.         System.arraycopy(value, 0, newValue, 0, count);
  102.         value = newValue;
  103.         shared = false;
  104.     }
  105.     }
  106.  
  107.     /**
  108.      * Ensures that the capacity of the buffer is at least equal to the
  109.      * specified minimum.
  110.      * @param minimumCapacity    the minimum desired capacity
  111.      */
  112.     public synchronized void ensureCapacity(int minimumCapacity) {
  113.     int maxCapacity = value.length;
  114.  
  115.     if (minimumCapacity > maxCapacity) {
  116.         int newCapacity = (maxCapacity + 1) * 2;
  117.         if (minimumCapacity > newCapacity) {
  118.         newCapacity = minimumCapacity;
  119.         }
  120.  
  121.         char newValue[] = new char[newCapacity];
  122.         System.arraycopy(value, 0, newValue, 0, count);
  123.         value = newValue;
  124.         shared = false;
  125.     }
  126.     }
  127.  
  128.     /**
  129.      * Sets the length of the String. If the length is reduced, characters
  130.      * are lost. If the length is extended, the values of the new characters
  131.      * are set to 0.
  132.      * @param newLength    the new length of the buffer
  133.      * @exception StringIndexOutOfBoundsException  If the length is invalid.
  134.      */
  135.     public synchronized void setLength(int newLength) {
  136.     if (newLength < 0) {
  137.         throw new StringIndexOutOfBoundsException(newLength);
  138.     }
  139.     ensureCapacity(newLength);
  140.  
  141.     if (count < newLength) {
  142.         copyWhenShared();
  143.         for (; count < newLength; count++) {
  144.         value[count] = '\0';
  145.         }
  146.     }
  147.     count = newLength;
  148.     }
  149.  
  150.     /**
  151.      * Returns the character at the specified index. An index ranges
  152.      * from 0..length()-1.
  153.      * @param index    the index of the desired character
  154.      * @exception StringIndexOutOfBoundsException If the index is invalid.
  155.      */
  156.     public synchronized char charAt(int index) {
  157.     if ((index < 0) || (index >= count)) {
  158.         throw new StringIndexOutOfBoundsException(index);
  159.     }
  160.     return value[index];
  161.     }
  162.  
  163.     /**
  164.      * Copies the characters of the specified substring (determined by
  165.      * srcBegin and srcEnd) into the character array, starting at the
  166.      * array's dstBegin location. Both srcBegin and srcEnd must be legal
  167.      * indexes into the buffer.
  168.      * @param srcBegin    begin copy at this offset in the String
  169.      * @param srcEnd    stop copying at this offset in the String
  170.      * @param dst        the array to copy the data into
  171.      * @param dstBegin    offset into dst
  172.      * @exception StringIndexOutOfBoundsException If there is an invalid index into the buffer.
  173.      */
  174.     public synchronized void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
  175.     if ((srcBegin < 0) || (srcBegin >= count)) {
  176.         throw new StringIndexOutOfBoundsException(srcBegin);
  177.     }
  178.     if ((srcEnd < 0) || (srcEnd > count)) {
  179.         throw new StringIndexOutOfBoundsException(srcEnd);
  180.     }
  181.     if (srcBegin < srcEnd) {
  182.         System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
  183.     }
  184.     }
  185.  
  186.     /**
  187.      * Changes the character at the specified index to be ch.
  188.      * @param index    the index of the character
  189.      * @param ch        the new character
  190.      * @exception    StringIndexOutOfBoundsException If the index is invalid.
  191.      */
  192.     public synchronized void setCharAt(int index, char ch) {
  193.     if ((index < 0) || (index >= count)) {
  194.         throw new StringIndexOutOfBoundsException(index);
  195.     }
  196.     copyWhenShared();
  197.     value[index] = ch;
  198.     }
  199.  
  200.     /**
  201.      * Appends an object to the end of this buffer.
  202.      * @param obj    the object to be appended
  203.      * @return     the StringBuffer itself, NOT a new one.
  204.      */
  205.     public synchronized StringBuffer append(Object obj) {
  206.     return append(String.valueOf(obj));
  207.     }
  208.  
  209.     /**
  210.      * Appends a String to the end of this buffer.
  211.      * @param str    the String to be appended
  212.      * @return     the StringBuffer itself, NOT a new one.
  213.      */
  214.     public synchronized StringBuffer append(String str) {
  215.     if (str == null) {
  216.         str = String.valueOf(str);
  217.     }
  218.  
  219.     int len = str.length();
  220.     ensureCapacity(count + len);
  221.     copyWhenShared();
  222.     str.getChars(0, len, value, count);
  223.     count += len;
  224.     return this;
  225.     }
  226.  
  227.     /**
  228.      * Appends an array of characters to the end of this buffer.
  229.      * @param str    the characters to be appended
  230.      * @return     the StringBuffer itself, NOT a new one.
  231.      */
  232.     public synchronized StringBuffer append(char str[]) {
  233.     int len = str.length;
  234.     ensureCapacity(count + len);
  235.     copyWhenShared();
  236.     System.arraycopy(str, 0, value, count, len);
  237.     count += len;
  238.     return this;
  239.     }
  240.  
  241.     /**
  242.      * Appends a part of an array of characters to the end of this buffer.
  243.      * @param str    the characters to be appended
  244.      * @param offset    where to start
  245.      * @param len    the number of characters to add
  246.      * @return     the StringBuffer itself, NOT a new one.
  247.      */
  248.     public synchronized StringBuffer append(char str[], int offset, int len) {
  249.     ensureCapacity(count + len);
  250.     copyWhenShared();
  251.     System.arraycopy(str, offset, value, count, len);
  252.     count += len;
  253.     return this;
  254.     }
  255.  
  256.     /**
  257.      * Appends a boolean to the end of this buffer.
  258.      * @param b    the boolean to be appended
  259.      * @return     the StringBuffer itself, NOT a new one.
  260.      */
  261.     public StringBuffer append(boolean b) {
  262.     return append(String.valueOf(b));
  263.     }
  264.  
  265.     /**
  266.      * Appends a character to the end of this buffer.
  267.      * @param ch    the character to be appended
  268.      * @return     the StringBuffer itself, NOT a new one.
  269.      */
  270.     public synchronized StringBuffer append(char c) {
  271.     ensureCapacity(count + 1);
  272.     copyWhenShared();
  273.     value[count++] = c;
  274.     return this;
  275.     }
  276.  
  277.     /**
  278.      * Appends an integer to the end of this buffer.
  279.      * @param i    the integer to be appended
  280.      * @return     the StringBuffer itself, NOT a new one.
  281.      */
  282.     public StringBuffer append(int i) {
  283.     return append(String.valueOf(i));
  284.     }
  285.  
  286.     /**
  287.      * Appends a long to the end of this buffer.
  288.      * @param l    the long to be appended
  289.      * @return     the StringBuffer itself, NOT a new one.
  290.      */
  291.     public StringBuffer append(long l) {
  292.     return append(String.valueOf(l));
  293.     }
  294.  
  295.     /**
  296.      * Appends a float to the end of this buffer.
  297.      * @param f    the float to be appended
  298.      * @return     the StringBuffer itself, NOT a new one.
  299.      */
  300.     public StringBuffer append(float f) {
  301.     return append(String.valueOf(f));
  302.     }
  303.  
  304.     /**
  305.      * Appends a double to the end of this buffer.
  306.      * @param d    the double to be appended
  307.      * @return     the StringBuffer itself, NOT a new one.
  308.      */
  309.     public StringBuffer append(double d) {
  310.     return append(String.valueOf(d));
  311.     }
  312.  
  313.     /**
  314.      * Inserts an object into the String buffer.
  315.      * @param offset    the offset at which to insert
  316.      * @param obj        the object to insert
  317.      * @return         the StringBuffer itself, NOT a new one.
  318.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  319.      */
  320.     public synchronized StringBuffer insert(int offset, Object obj) {
  321.     return insert(offset, String.valueOf(obj));
  322.     }
  323.  
  324.     /**
  325.      * Inserts a String into the String buffer.
  326.      * @param offset    the offset at which to insert
  327.      * @param str        the String to insert
  328.      * @return         the StringBuffer itself, NOT a new one.
  329.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  330.      */
  331.     public synchronized StringBuffer insert(int offset, String str) {
  332.     if ((offset < 0) || (offset > count)) {
  333.         throw new StringIndexOutOfBoundsException();
  334.     }
  335.     int len = str.length();
  336.     ensureCapacity(count + len);
  337.     copyWhenShared();
  338.     System.arraycopy(value, offset, value, offset + len, count - offset);
  339.     str.getChars(0, len, value, offset);
  340.     count += len;
  341.     return this;
  342.     }
  343.  
  344.     /**
  345.      * Inserts an array of characters into the String buffer.
  346.      * @param offset    the offset at which to insert
  347.      * @param str        the characters to insert
  348.      * @return         the StringBuffer itself, NOT a new one.
  349.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  350.      */
  351.     public synchronized StringBuffer insert(int offset, char str[]) {
  352.     if ((offset < 0) || (offset > count)) {
  353.         throw new StringIndexOutOfBoundsException();
  354.     }
  355.     int len = str.length;
  356.     ensureCapacity(count + len);
  357.     copyWhenShared();
  358.     System.arraycopy(value, offset, value, offset + len, count - offset);
  359.     System.arraycopy(str, 0, value, offset, len);
  360.     count += len;
  361.     return this;
  362.     }
  363.  
  364.     /**
  365.      * Inserts a boolean into the String buffer.
  366.      * @param offset    the offset at which to insert
  367.      * @param b        the boolean to insert
  368.      * @return         the StringBuffer itself, NOT a new one.
  369.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  370.      */
  371.     public StringBuffer insert(int offset, boolean b) {
  372.     return insert(offset, String.valueOf(b));
  373.     }
  374.  
  375.     /**
  376.      * Inserts a character into the String buffer.
  377.      * @param offset    the offset at which to insert
  378.      * @param ch        the character to insert
  379.      * @return         the StringBuffer itself, NOT a new one.
  380.      * @exception    StringIndexOutOfBoundsException If the offset invalid.
  381.      */
  382.     public synchronized StringBuffer insert(int offset, char c) {
  383.     ensureCapacity(count + 1);
  384.     copyWhenShared();
  385.     System.arraycopy(value, offset, value, offset + 1, count - offset);
  386.     value[offset] = c;
  387.     count += 1;
  388.     return this;
  389.     }
  390.  
  391.     /**
  392.      * Inserts an integer into the String buffer.
  393.      * @param offset    the offset at which to insert
  394.      * @param i        the integer to insert
  395.      * @return         the StringBuffer itself, NOT a new one.
  396.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  397.      */
  398.     public StringBuffer insert(int offset, int i) {
  399.     return insert(offset, String.valueOf(i));
  400.     }
  401.  
  402.     /**
  403.      * Inserts a long into the String buffer.
  404.      * @param offset    the offset at which to insert
  405.      * @param l        the long to insert
  406.      * @return         the StringBuffer itself, NOT a new one.
  407.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  408.      */
  409.     public StringBuffer insert(int offset, long l) {
  410.     return insert(offset, String.valueOf(l));
  411.     }
  412.  
  413.     /**
  414.      * Inserts a float into the String buffer.
  415.      * @param offset    the offset at which to insert
  416.      * @param f        the float to insert
  417.      * @return         the StringBuffer itself, NOT a new one.
  418.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  419.      */
  420.     public StringBuffer insert(int offset, float f) {
  421.     return insert(offset, String.valueOf(f));
  422.     }
  423.  
  424.     /**
  425.      * Inserts a double into the String buffer.
  426.      * @param offset    the offset at which to insert
  427.      * @param d        the double to insert
  428.      * @return         the StringBuffer itself, NOT a new one.
  429.      * @exception    StringIndexOutOfBoundsException If the offset is invalid.
  430.      */
  431.     public StringBuffer insert(int offset, double d) {
  432.     return insert(offset, String.valueOf(d));
  433.     }
  434.  
  435.     /**
  436.      * Reverse the order of the characters in the String buffer.
  437.      */
  438.     public synchronized StringBuffer reverse() {
  439.     copyWhenShared();
  440.     int n = count - 1;
  441.     for (int j = (n-1) >> 1; j >= 0; --j) {
  442.         char temp = value[j];
  443.         value[j] = value[n - j];
  444.         value[n - j] = temp;
  445.     }
  446.     return this;
  447.     }
  448.  
  449.  
  450.     /**
  451.      * Converts to a String representing the data in the buffer.
  452.      */
  453.     public String toString() {
  454.     return new String(this);
  455.     }
  456.  
  457.  
  458.     //
  459.     // The following two methods are needed by String to efficiently
  460.     // convert a StringBuffer into a String.  They are not public.
  461.     // They shouldn't be called by anyone but String.
  462.     final void setShared() { shared = true; } 
  463.     final char[] getValue() { return value; }
  464. }
  465.