/[classpath]/classpath/java/lang/StringBuffer.java
ViewVC logotype

Diff of /classpath/java/lang/StringBuffer.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.19 by ericb, Thu Mar 7 07:33:32 2002 UTC revision 1.20 by ericb, Sat Mar 9 04:01:12 2002 UTC
# Line 59  import java.io.Serializable; Line 59  import java.io.Serializable;
59   * <code>new StringBuffer().append(a).append(b).toString()</code>.   * <code>new StringBuffer().append(a).append(b).toString()</code>.
60   *   *
61   * <p>Classpath's StringBuffer is capable of sharing memory with Strings for   * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
62   * efficiency.  This will help in two instances: first, when a StringBuffer   * efficiency.  This will help when a StringBuffer is converted to a String
63   * is created from a String but is never changed, and second, when a   * and the StringBuffer is not changed after that (quite common when performing
64   * StringBuffer is converted to a String and the StringBuffer is not changed   * string concatenation).
  * after that.  
65   *   *
66   * @author Paul Fisher   * @author Paul Fisher
67   * @author John Keiser   * @author John Keiser
# Line 138  public final class StringBuffer implemen Line 137  public final class StringBuffer implemen
137     *     *
138     * @param str the <code>String</code> to convert     * @param str the <code>String</code> to convert
139     * @throws NullPointerException if str is null     * @throws NullPointerException if str is null
    * @XXX Optimize for sharing.  
140     */     */
141    public StringBuffer(String str)    public StringBuffer(String str)
142    {    {
143      count = str.length();      // Unfortunately, because the size is 16 larger, we cannot share.
144        count = str.count;
145      value = new char[count + DEFAULT_CAPACITY];      value = new char[count + DEFAULT_CAPACITY];
146      str.getChars(0, count, value, 0);      str.getChars(0, count, value, 0);
147    }    }
# Line 207  public final class StringBuffer implemen Line 206  public final class StringBuffer implemen
206        throw new StringIndexOutOfBoundsException(newLength);        throw new StringIndexOutOfBoundsException(newLength);
207    
208      ensureCapacity_unsynchronized(newLength);      ensureCapacity_unsynchronized(newLength);
209      for (int i = count; i < newLength; ++i)      while (count < newLength)
210        value[i] = '\0';        value[count++] = '\0';
211      count = newLength;      count = newLength;
212    }    }
213    
# Line 222  public final class StringBuffer implemen Line 221  public final class StringBuffer implemen
221     */     */
222    public synchronized char charAt(int index)    public synchronized char charAt(int index)
223    {    {
224      if (index >= count)      if (index < 0 || index >= count)
225        throw new StringIndexOutOfBoundsException(index);        throw new StringIndexOutOfBoundsException(index);
226      return value[index];      return value[index];
227    }    }
# Line 237  public final class StringBuffer implemen Line 236  public final class StringBuffer implemen
236     * @param dstOffset the index to start copying into     * @param dstOffset the index to start copying into
237     * @throws NullPointerException if dst is null     * @throws NullPointerException if dst is null
238     * @throws IndexOutOfBoundsException if any source or target indices are     * @throws IndexOutOfBoundsException if any source or target indices are
239     *         out of range (while unspecified, this is a     *         out of range (while unspecified, source problems cause a
240     *         StringIndexOutOfBoundsException)     *         StringIndexOutOfBoundsException, and dest problems cause an
241       *         ArrayIndexOutOfBoundsException)
242     * @see System#arraycopy(Object, int, Object, int, int)     * @see System#arraycopy(Object, int, Object, int, int)
243     */     */
244    public synchronized void getChars(int srcOffset, int srcEnd,    public synchronized void getChars(int srcOffset, int srcEnd,
245                                      char[] dst, int dstOffset)                                      char[] dst, int dstOffset)
246    {    {
     if (srcOffset < 0 || srcOffset > srcEnd)  
       throw new StringIndexOutOfBoundsException(srcOffset);  
247      int todo = srcEnd - srcOffset;      int todo = srcEnd - srcOffset;
248      if (srcEnd > count || dstOffset + todo > count)      if (srcOffset < 0 || srcEnd > count || todo < 0)
249        throw new StringIndexOutOfBoundsException(srcEnd);        throw new StringIndexOutOfBoundsException();
250      System.arraycopy(value, srcOffset, dst, dstOffset, todo);      System.arraycopy(value, srcOffset, dst, dstOffset, todo);
251    }    }
252    
# Line 281  public final class StringBuffer implemen Line 279  public final class StringBuffer implemen
279     */     */
280    public StringBuffer append(Object obj)    public StringBuffer append(Object obj)
281    {    {
282      return append(String.valueOf(obj));      return append(obj == null ? "null" : obj.toString());
283    }    }
284    
285    /**    /**
# Line 295  public final class StringBuffer implemen Line 293  public final class StringBuffer implemen
293    {    {
294      if (str == null)      if (str == null)
295        str = "null";        str = "null";
296      int len = str.length();      int len = str.count;
297      ensureCapacity_unsynchronized(count + len);      ensureCapacity_unsynchronized(count + len);
298      str.getChars(0, len, value, count);      str.getChars(0, len, value, count);
299      count += len;      count += len;
# Line 312  public final class StringBuffer implemen Line 310  public final class StringBuffer implemen
310     * @see #append(Object)     * @see #append(Object)
311     * @since 1.4     * @since 1.4
312     */     */
313    public StringBuffer append(StringBuffer stringBuffer)    public synchronized StringBuffer append(StringBuffer stringBuffer)
314    {    {
315      // XXX The point of this method was to AVOID creating the String...      if (stringBuffer == null)
316      return append(stringBuffer.toString());        return append("null");
317        synchronized (stringBuffer)
318          {
319            int len = stringBuffer.count;
320            ensureCapacity_unsynchronized(count + len);
321            System.arraycopy(stringBuffer.value, 0, value, count, len);
322            count += len;
323          }
324        return this;
325    }    }
326    
327    /**    /**
# Line 366  public final class StringBuffer implemen Line 372  public final class StringBuffer implemen
372     */     */
373    public StringBuffer append(boolean bool)    public StringBuffer append(boolean bool)
374    {    {
375      return append(String.valueOf(bool));      return append(bool ? "true" : "false");
376    }    }
377    
378    /**    /**
# Line 391  public final class StringBuffer implemen Line 397  public final class StringBuffer implemen
397     * @return this <code>StringBuffer</code>     * @return this <code>StringBuffer</code>
398     * @see String#valueOf(int)     * @see String#valueOf(int)
399     */     */
400      // This is native in libgcj, for efficiency.
401    public StringBuffer append(int inum)    public StringBuffer append(int inum)
402    {    {
403      return append(String.valueOf(inum));      return append(String.valueOf(inum));
# Line 407  public final class StringBuffer implemen Line 414  public final class StringBuffer implemen
414     */     */
415    public StringBuffer append(long lnum)    public StringBuffer append(long lnum)
416    {    {
417      return append(String.valueOf(lnum));      return append(Long.toString(lnum, 10));
418    }    }
419    
420    /**    /**
# Line 421  public final class StringBuffer implemen Line 428  public final class StringBuffer implemen
428     */     */
429    public StringBuffer append(float fnum)    public StringBuffer append(float fnum)
430    {    {
431      return append(String.valueOf(fnum));      return append(Float.toString(fnum));
432    }    }
433    
434    /**    /**
# Line 435  public final class StringBuffer implemen Line 442  public final class StringBuffer implemen
442     */     */
443    public StringBuffer append(double dnum)    public StringBuffer append(double dnum)
444    {    {
445      return append(String.valueOf(dnum));      return append(Double.toString(dnum));
446    }    }
447    
448    /**    /**
# Line 495  public final class StringBuffer implemen Line 502  public final class StringBuffer implemen
502      if (start < 0 || start > count || start > end)      if (start < 0 || start > count || start > end)
503        throw new StringIndexOutOfBoundsException(start);        throw new StringIndexOutOfBoundsException(start);
504    
505      int len = str.length();      int len = str.count;
506      // Calculate the difference in 'count' after the replace.      // Calculate the difference in 'count' after the replace.
507      int delta = len - ((end > count ? count : end) - start);      int delta = len - (end > count ? count : end) + start;
508      ensureCapacity_unsynchronized(count + delta);      ensureCapacity_unsynchronized(count + delta);
509    
510      if (delta != 0 && end < count)      if (delta != 0 && end < count)
# Line 555  public final class StringBuffer implemen Line 562  public final class StringBuffer implemen
562     */     */
563    public synchronized String substring(int beginIndex, int endIndex)    public synchronized String substring(int beginIndex, int endIndex)
564    {    {
565      if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)      int len = endIndex - beginIndex;
566        if (beginIndex < 0 || endIndex > count || len < 0)
567        throw new StringIndexOutOfBoundsException();        throw new StringIndexOutOfBoundsException();
568      // XXX FIXME: for libgcj it would be possible, and more efficient, to      if (len == 0)
569      // enable sharing here.        return "";
570      return new String(value, beginIndex, endIndex - beginIndex);      // Share the char[] unless 3/4 empty.
571        if (beginIndex != 0 || (endIndex << 2) < value.length)
572          return new String(value, beginIndex, len);
573        // XXX Todo: share even when beginIndex != 0.
574        shared = true;
575        // Package constructor avoids an array copy.
576        return new String(value, len);
577    }    }
578    
579    /**    /**
# Line 578  public final class StringBuffer implemen Line 592  public final class StringBuffer implemen
592    public synchronized StringBuffer insert(int offset,    public synchronized StringBuffer insert(int offset,
593                                            char[] str, int str_offset, int len)                                            char[] str, int str_offset, int len)
594    {    {
595      if (offset < 0 || offset > count)      if (offset < 0 || offset > count || len < 0
596        throw new StringIndexOutOfBoundsException(offset);          || str_offset < 0 || str_offset + len > str.length)
597      if (len < 0)        throw new StringIndexOutOfBoundsException();
       throw new StringIndexOutOfBoundsException(len);  
     if (str_offset < 0 || str_offset + len > str.length)  
       throw new StringIndexOutOfBoundsException(str_offset);  
598      ensureCapacity_unsynchronized(count + len);      ensureCapacity_unsynchronized(count + len);
599      System.arraycopy(value, offset, value, offset + len, count - offset);      System.arraycopy(value, offset, value, offset + len, count - offset);
600      System.arraycopy(str, str_offset, value, offset, len);      System.arraycopy(str, str_offset, value, offset, len);
# Line 604  public final class StringBuffer implemen Line 615  public final class StringBuffer implemen
615     */     */
616    public StringBuffer insert(int offset, Object obj)    public StringBuffer insert(int offset, Object obj)
617    {    {
618      return insert(offset, String.valueOf(obj));      return insert(offset, obj == null ? "null" : obj.toString());
619    }    }
620    
621    /**    /**
# Line 623  public final class StringBuffer implemen Line 634  public final class StringBuffer implemen
634        throw new StringIndexOutOfBoundsException(offset);        throw new StringIndexOutOfBoundsException(offset);
635      if (str == null)      if (str == null)
636        str = "null";        str = "null";
637      int len = str.length();      int len = str.count;
638      ensureCapacity_unsynchronized(count + len);      ensureCapacity_unsynchronized(count + len);
639      System.arraycopy(value, offset, value, offset + len, count - offset);      System.arraycopy(value, offset, value, offset + len, count - offset);
640      str.getChars(0, len, value, offset);      str.getChars(0, len, value, offset);
# Line 644  public final class StringBuffer implemen Line 655  public final class StringBuffer implemen
655     */     */
656    public StringBuffer insert(int offset, char[] data)    public StringBuffer insert(int offset, char[] data)
657    {    {
658      // Sun checks offset before checking if data is null, hence this delay      return insert(offset, data, 0, data.length);
     // of dereferencing data.  
     return insert(offset, data, 0, data == null ? 0 : data.length);  
659    }    }
660    
661    /**    /**
# Line 713  public final class StringBuffer implemen Line 722  public final class StringBuffer implemen
722     */     */
723    public StringBuffer insert(int offset, long lnum)    public StringBuffer insert(int offset, long lnum)
724    {    {
725      return insert(offset, String.valueOf(lnum));      return insert(offset, Long.toString(lnum, 10));
726    }    }
727    
728    /**    /**
# Line 729  public final class StringBuffer implemen Line 738  public final class StringBuffer implemen
738     */     */
739    public StringBuffer insert(int offset, float fnum)    public StringBuffer insert(int offset, float fnum)
740    {    {
741      return insert(offset, String.valueOf(fnum));      return insert(offset, Float.toString(fnum));
742    }    }
743    
744    /**    /**
# Line 745  public final class StringBuffer implemen Line 754  public final class StringBuffer implemen
754     */     */
755    public StringBuffer insert(int offset, double dnum)    public StringBuffer insert(int offset, double dnum)
756    {    {
757      return insert(offset, String.valueOf(dnum));      return insert(offset, Double.toString(dnum));
758    }    }
759    
760    /**    /**
# Line 776  public final class StringBuffer implemen Line 785  public final class StringBuffer implemen
785     */     */
786    public synchronized int indexOf(String str, int fromIndex)    public synchronized int indexOf(String str, int fromIndex)
787    {    {
788      // XXX Avoid the object creation here.      if (fromIndex < 0)
789      return this.toString().indexOf(str, fromIndex);        fromIndex = 0;
790        int limit = count - str.count;
791        for ( ; fromIndex <= limit; fromIndex++)
792          if (regionMatches(fromIndex, str))
793            return fromIndex;
794        return -1;
795    }    }
796    
797    /**    /**
# Line 808  public final class StringBuffer implemen Line 822  public final class StringBuffer implemen
822     */     */
823    public synchronized int lastIndexOf(String str, int fromIndex)    public synchronized int lastIndexOf(String str, int fromIndex)
824    {    {
825      // XXX Avoid the object creation here.      fromIndex = Math.min(fromIndex, count - str.count);
826      return this.toString().lastIndexOf(str, fromIndex);      for ( ; fromIndex >= 0; fromIndex--)
827          if (regionMatches(fromIndex, str))
828            return fromIndex;
829        return -1;
830    }    }
831    
832    /**    /**
# Line 822  public final class StringBuffer implemen Line 839  public final class StringBuffer implemen
839    {    {
840      // Call ensureCapacity to enforce copy-on-write.      // Call ensureCapacity to enforce copy-on-write.
841      ensureCapacity_unsynchronized(count);      ensureCapacity_unsynchronized(count);
842      for (int i = 0; i < count / 2; ++i)      for (int i = count >> 1, j = count - i; --i >= 0; ++j)
843        {        {
844          char c = value[i];          char c = value[i];
845          value[i] = value[count - i - 1];          value[i] = value[j];
846          value[count - i - 1] = c;          value[j] = c;
847        }        }
848      return this;      return this;
849    }    }
# Line 841  public final class StringBuffer implemen Line 858  public final class StringBuffer implemen
858     */     */
859    public String toString()    public String toString()
860    {    {
861      // XXX Implement sharing with this call, to match libgcj.      // The string will set this.shared = true.
862      return new String(this);      return new String(this);
863    }    }
864    
# Line 871  public final class StringBuffer implemen Line 888  public final class StringBuffer implemen
888          shared = false;          shared = false;
889        }        }
890    }    }
891    
892      /**
893       * Predicate which determines if a substring of this matches another String
894       * starting at a specified offset for each String and continuing for a
895       * specified length. This is more efficient than creating a String to call
896       * indexOf on.
897       *
898       * @param toffset index to start comparison at for this String
899       * @param other String to compare region to this String
900       * @return true if regions match, false otherwise
901       * @see #indexOf(String, int)
902       * @see #lastIndexOf(String, int)
903       * @see String#regionMatches(boolean, int, String, int, int)
904       */
905      private boolean regionMatches(int toffset, String other)
906      {
907        for (int index = 0, len = other.count; --len >= 0; toffset++, index++)
908          // Note that libgcj requires other.charAt() instead of other.value[].
909          if (value[toffset] != other.value[index])
910            return false;
911        return true;
912      }
913  }  }

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.20

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26