1. /*
  2. * @(#)StringBuffer.java 1.62 00/04/21
  3. *
  4. * Copyright 1994-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.lang;
  11. /**
  12. * A string buffer implements a mutable sequence of characters.
  13. * A string buffer is like a {@link String}, but can be modified. At any
  14. * point in time it contains some particular sequence of characters, but
  15. * the length and content of the sequence can be changed through certain
  16. * method calls.
  17. * <p>
  18. * String buffers are safe for use by multiple threads. The methods
  19. * are synchronized where necessary so that all the operations on any
  20. * particular instance behave as if they occur in some serial order
  21. * that is consistent with the order of the method calls made by each of
  22. * the individual threads involved.
  23. * <p>
  24. * String buffers are used by the compiler to implement the binary
  25. * string concatenation operator <code>+</code>. For example, the code:
  26. * <p><blockquote><pre>
  27. * x = "a" + 4 + "c"
  28. * </pre></blockquote><p>
  29. * is compiled to the equivalent of:
  30. * <p><blockquote><pre>
  31. * x = new StringBuffer().append("a").append(4).append("c")
  32. * .toString()
  33. * </pre></blockquote>
  34. * which creates a new string buffer (initially empty), appends the string
  35. * representation of each operand to the string buffer in turn, and then
  36. * converts the contents of the string buffer to a string. Overall, this avoids
  37. * creating many temporary strings.
  38. * <p>
  39. * The principal operations on a <code>StringBuffer</code> are the
  40. * <code>append</code> and <code>insert</code> methods, which are
  41. * overloaded so as to accept data of any type. Each effectively
  42. * converts a given datum to a string and then appends or inserts the
  43. * characters of that string to the string buffer. The
  44. * <code>append</code> method always adds these characters at the end
  45. * of the buffer; the <code>insert</code> method adds the characters at
  46. * a specified point.
  47. * <p>
  48. * For example, if <code>z</code> refers to a string buffer object
  49. * whose current contents are "<code>start</code>", then
  50. * the method call <code>z.append("le")</code> would cause the string
  51. * buffer to contain "<code>startle</code>", whereas
  52. * <code>z.insert(4, "le")</code> would alter the string buffer to
  53. * contain "<code>starlet</code>".
  54. * <p>
  55. * In general, if sb refers to an instance of a <code>StringBuffer</code>,
  56. * then <code>sb.append(x)</code> has the same effect as
  57. * <code>sb.insert(sb.length(), x)</code>.
  58. * <p>
  59. * Every string buffer has a capacity. As long as the length of the
  60. * character sequence contained in the string buffer does not exceed
  61. * the capacity, it is not necessary to allocate a new internal
  62. * buffer array. If the internal buffer overflows, it is
  63. * automatically made larger.
  64. *
  65. * @author Arthur van Hoff
  66. * @version 1.62, 04/21/00
  67. * @see java.io.ByteArrayOutputStream
  68. * @see java.lang.String
  69. * @since JDK1.0
  70. */
  71. public final class StringBuffer implements java.io.Serializable {
  72. /**
  73. * The value is used for character storage.
  74. *
  75. * @serial
  76. */
  77. private char value[];
  78. /**
  79. * The count is the number of characters in the buffer.
  80. *
  81. * @serial
  82. */
  83. private int count;
  84. /**
  85. * A flag indicating whether the buffer is shared
  86. *
  87. * @serial
  88. */
  89. private boolean shared;
  90. /** use serialVersionUID from JDK 1.0.2 for interoperability */
  91. static final long serialVersionUID = 3388685877147921107L;
  92. /**
  93. * Constructs a string buffer with no characters in it and an
  94. * initial capacity of 16 characters.
  95. */
  96. public StringBuffer() {
  97. this(16);
  98. }
  99. /**
  100. * Constructs a string buffer with no characters in it and an
  101. * initial capacity specified by the <code>length</code> argument.
  102. *
  103. * @param length the initial capacity.
  104. * @exception NegativeArraySizeException if the <code>length</code>
  105. * argument is less than <code>0</code>.
  106. */
  107. public StringBuffer(int length) {
  108. value = new char[length];
  109. shared = false;
  110. }
  111. /**
  112. * Constructs a string buffer so that it represents the same
  113. * sequence of characters as the string argument; in other
  114. * words, the initial contents of the string buffer is a copy of the
  115. * argument string. The initial capacity of the string buffer is
  116. * <code>16</code> plus the length of the string argument.
  117. *
  118. * @param str the initial contents of the buffer.
  119. */
  120. public StringBuffer(String str) {
  121. this(str.length() + 16);
  122. append(str);
  123. }
  124. /**
  125. * Returns the length (character count) of this string buffer.
  126. *
  127. * @return the length of the sequence of characters currently
  128. * represented by this string buffer.
  129. */
  130. public int length() {
  131. return count;
  132. }
  133. /**
  134. * Returns the current capacity of the String buffer. The capacity
  135. * is the amount of storage available for newly inserted
  136. * characters; beyond which an allocation will occur.
  137. *
  138. * @return the current capacity of this string buffer.
  139. */
  140. public int capacity() {
  141. return value.length;
  142. }
  143. /**
  144. * Copies the buffer value. This is normally only called when shared
  145. * is true. It should only be called from a synchronized method.
  146. */
  147. private final void copy() {
  148. char newValue[] = new char[value.length];
  149. System.arraycopy(value, 0, newValue, 0, count);
  150. value = newValue;
  151. shared = false;
  152. }
  153. /**
  154. * Ensures that the capacity of the buffer is at least equal to the
  155. * specified minimum.
  156. * If the current capacity of this string buffer is less than the
  157. * argument, then a new internal buffer is allocated with greater
  158. * capacity. The new capacity is the larger of:
  159. * <ul>
  160. * <li>The <code>minimumCapacity</code> argument.
  161. * <li>Twice the old capacity, plus <code>2</code>.
  162. * </ul>
  163. * If the <code>minimumCapacity</code> argument is nonpositive, this
  164. * method takes no action and simply returns.
  165. *
  166. * @param minimumCapacity the minimum desired capacity.
  167. */
  168. public synchronized void ensureCapacity(int minimumCapacity) {
  169. if (minimumCapacity > value.length) {
  170. expandCapacity(minimumCapacity);
  171. }
  172. }
  173. /**
  174. * This implements the expansion semantics of ensureCapacity but is
  175. * unsynchronized for use internally by methods which are already
  176. * synchronized.
  177. *
  178. * @see java.lang.StringBuffer#ensureCapacity(int)
  179. */
  180. private void expandCapacity(int minimumCapacity) {
  181. int newCapacity = (value.length + 1) * 2;
  182. if (newCapacity < 0) {
  183. newCapacity = Integer.MAX_VALUE;
  184. } else if (minimumCapacity > newCapacity) {
  185. newCapacity = minimumCapacity;
  186. }
  187. char newValue[] = new char[newCapacity];
  188. System.arraycopy(value, 0, newValue, 0, count);
  189. value = newValue;
  190. shared = false;
  191. }
  192. /**
  193. * Sets the length of this String buffer.
  194. * This string buffer is altered to represent a new character sequence
  195. * whose length is specified by the argument. For every nonnegative
  196. * index <i>k</i> less than <code>newLength</code>, the character at
  197. * index <i>k</i> in the new character sequence is the same as the
  198. * character at index <i>k</i> in the old sequence if <i>k</i> is less
  199. * than the length of the old character sequence; otherwise, it is the
  200. * null character <code>'\u0000'</code>.
  201. *
  202. * In other words, if the <code>newLength</code> argument is less than
  203. * the current length of the string buffer, the string buffer is
  204. * truncated to contain exactly the number of characters given by the
  205. * <code>newLength</code> argument.
  206. * <p>
  207. * If the <code>newLength</code> argument is greater than or equal
  208. * to the current length, sufficient null characters
  209. * (<code>'\u0000'</code>) are appended to the string buffer so that
  210. * length becomes the <code>newLength</code> argument.
  211. * <p>
  212. * The <code>newLength</code> argument must be greater than or equal
  213. * to <code>0</code>.
  214. *
  215. * @param newLength the new length of the buffer.
  216. * @exception IndexOutOfBoundsException if the
  217. * <code>newLength</code> argument is negative.
  218. * @see java.lang.StringBuffer#length()
  219. */
  220. public synchronized void setLength(int newLength) {
  221. if (newLength < 0) {
  222. throw new StringIndexOutOfBoundsException(newLength);
  223. }
  224. if (newLength > value.length) {
  225. expandCapacity(newLength);
  226. }
  227. if (count < newLength) {
  228. if (shared) copy();
  229. for (; count < newLength; count++) {
  230. value[count] = '\0';
  231. }
  232. } else {
  233. count = newLength;
  234. if (shared) {
  235. if (newLength > 0) {
  236. copy();
  237. } else {
  238. // If newLength is zero, assume the StringBuffer is being
  239. // stripped for reuse; Make new buffer of default size
  240. value = new char[16];
  241. shared = false;
  242. }
  243. }
  244. }
  245. }
  246. /**
  247. * The specified character of the sequence currently represented by
  248. * the string buffer, as indicated by the <code>index</code> argument,
  249. * is returned. The first character of a string buffer is at index
  250. * <code>0</code>, the next at index <code>1</code>, and so on, for
  251. * array indexing.
  252. * <p>
  253. * The index argument must be greater than or equal to
  254. * <code>0</code>, and less than the length of this string buffer.
  255. *
  256. * @param index the index of the desired character.
  257. * @return the character at the specified index of this string buffer.
  258. * @exception IndexOutOfBoundsException if <code>index</code> is
  259. * negative or greater than or equal to <code>length()</code>.
  260. * @see java.lang.StringBuffer#length()
  261. */
  262. public synchronized char charAt(int index) {
  263. if ((index < 0) || (index >= count)) {
  264. throw new StringIndexOutOfBoundsException(index);
  265. }
  266. return value[index];
  267. }
  268. /**
  269. * Characters are copied from this string buffer into the
  270. * destination character array <code>dst</code>. The first character to
  271. * be copied is at index <code>srcBegin</code> the last character to
  272. * be copied is at index <code>srcEnd-1</code>. The total number of
  273. * characters to be copied is <code>srcEnd-srcBegin</code>. The
  274. * characters are copied into the subarray of <code>dst</code> starting
  275. * at index <code>dstBegin</code> and ending at index:
  276. * <p><blockquote><pre>
  277. * dstbegin + (srcEnd-srcBegin) - 1
  278. * </pre></blockquote>
  279. *
  280. * @param srcBegin start copying at this offset in the string buffer.
  281. * @param srcEnd stop copying at this offset in the string buffer.
  282. * @param dst the array to copy the data into.
  283. * @param dstBegin offset into <code>dst</code>.
  284. * @exception NullPointerException if <code>dst</code> is
  285. * <code>null</code>.
  286. * @exception IndexOutOfBoundsException if any of the following is true:
  287. * <ul>
  288. * <li><code>srcBegin</code> is negative
  289. * <li><code>dstBegin</code> is negative
  290. * <li>the <code>srcBegin</code> argument is greater than
  291. * the <code>srcEnd</code> argument.
  292. * <li><code>srcEnd</code> is greater than
  293. * <code>this.length()</code>, the current length of this
  294. * string buffer.
  295. * <li><code>dstBegin+srcEnd-srcBegin</code> is greater than
  296. * <code>dst.length</code>
  297. * </ul>
  298. */
  299. public synchronized void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
  300. if (srcBegin < 0) {
  301. throw new StringIndexOutOfBoundsException(srcBegin);
  302. }
  303. if ((srcEnd < 0) || (srcEnd > count)) {
  304. throw new StringIndexOutOfBoundsException(srcEnd);
  305. }
  306. if (srcBegin > srcEnd) {
  307. throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
  308. }
  309. System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
  310. }
  311. /**
  312. * The character at the specified index of this string buffer is set
  313. * to <code>ch</code>. The string buffer is altered to represent a new
  314. * character sequence that is identical to the old character sequence,
  315. * except that it contains the character <code>ch</code> at position
  316. * <code>index</code>.
  317. * <p>
  318. * The offset argument must be greater than or equal to
  319. * <code>0</code>, and less than the length of this string buffer.
  320. *
  321. * @param index the index of the character to modify.
  322. * @param ch the new character.
  323. * @exception IndexOutOfBoundsException if <code>index</code> is
  324. * negative or greater than or equal to <code>length()</code>.
  325. * @see java.lang.StringBuffer#length()
  326. */
  327. public synchronized void setCharAt(int index, char ch) {
  328. if ((index < 0) || (index >= count)) {
  329. throw new StringIndexOutOfBoundsException(index);
  330. }
  331. if (shared) copy();
  332. value[index] = ch;
  333. }
  334. /**
  335. * Appends the string representation of the <code>Object</code>
  336. * argument to this string buffer.
  337. * <p>
  338. * The argument is converted to a string as if by the method
  339. * <code>String.valueOf</code>, and the characters of that
  340. * string are then appended to this string buffer.
  341. *
  342. * @param obj an <code>Object</code>.
  343. * @return a reference to this <code>StringBuffer</code> object.
  344. * @see java.lang.String#valueOf(java.lang.Object)
  345. * @see java.lang.StringBuffer#append(java.lang.String)
  346. */
  347. public synchronized StringBuffer append(Object obj) {
  348. return append(String.valueOf(obj));
  349. }
  350. /**
  351. * Appends the string to this string buffer.
  352. * <p>
  353. * The characters of the <code>String</code> argument are appended, in
  354. * order, to the contents of this string buffer, increasing the
  355. * length of this string buffer by the length of the argument.
  356. * If <code>str</code> is <code>null</code>, then the four characters
  357. * <code>"null"</code> are appended to this string buffer.
  358. * <p>
  359. * Let <i>n</i> be the length of the old character sequence, the one
  360. * contained in the string buffer just prior to execution of the
  361. * <code>append</code> method. Then the character at index <i>k</i> in
  362. * the new character sequence is equal to the character at index <i>k</i>
  363. * in the old character sequence, if <i>k</i> is less than <i>n</i>
  364. * otherwise, it is equal to the character at index <i>k-n</i> in the
  365. * argument <code>str</code>.
  366. *
  367. * @param str a string.
  368. * @return a reference to this <code>StringBuffer</code>.
  369. */
  370. public synchronized StringBuffer append(String str) {
  371. if (str == null) {
  372. str = String.valueOf(str);
  373. }
  374. int len = str.length();
  375. int newcount = count + len;
  376. if (newcount > value.length)
  377. expandCapacity(newcount);
  378. str.getChars(0, len, value, count);
  379. count = newcount;
  380. return this;
  381. }
  382. /**
  383. * Appends the string representation of the <code>char</code> array
  384. * argument to this string buffer.
  385. * <p>
  386. * The characters of the array argument are appended, in order, to
  387. * the contents of this string buffer. The length of this string
  388. * buffer increases by the length of the argument.
  389. * <p>
  390. * The overall effect is exactly as if the argument were converted to
  391. * a string by the method {@link String#valueOf(char[])} and the
  392. * characters of that string were then {@link #append(String) appended}
  393. * to this <code>StringBuffer</code> object.
  394. *
  395. * @param str the characters to be appended.
  396. * @return a reference to this <code>StringBuffer</code> object.
  397. */
  398. public synchronized StringBuffer append(char str[]) {
  399. int len = str.length;
  400. int newcount = count + len;
  401. if (newcount > value.length)
  402. expandCapacity(newcount);
  403. System.arraycopy(str, 0, value, count, len);
  404. count = newcount;
  405. return this;
  406. }
  407. /**
  408. * Appends the string representation of a subarray of the
  409. * <code>char</code> array argument to this string buffer.
  410. * <p>
  411. * Characters of the character array <code>str</code>, starting at
  412. * index <code>offset</code>, are appended, in order, to the contents
  413. * of this string buffer. The length of this string buffer increases
  414. * by the value of <code>len</code>.
  415. * <p>
  416. * The overall effect is exactly as if the arguments were converted to
  417. * a string by the method {@link String#valueOf(char[],int,int)} and the
  418. * characters of that string were then {@link #append(String) appended}
  419. * to this <code>StringBuffer</code> object.
  420. *
  421. * @param str the characters to be appended.
  422. * @param offset the index of the first character to append.
  423. * @param len the number of characters to append.
  424. * @return a reference to this <code>StringBuffer</code> object.
  425. */
  426. public synchronized StringBuffer append(char str[], int offset, int len) {
  427. int newcount = count + len;
  428. if (newcount > value.length)
  429. expandCapacity(newcount);
  430. System.arraycopy(str, offset, value, count, len);
  431. count = newcount;
  432. return this;
  433. }
  434. /**
  435. * Appends the string representation of the <code>boolean</code>
  436. * argument to the string buffer.
  437. * <p>
  438. * The argument is converted to a string as if by the method
  439. * <code>String.valueOf</code>, and the characters of that
  440. * string are then appended to this string buffer.
  441. *
  442. * @param b a <code>boolean</code>.
  443. * @return a reference to this <code>StringBuffer</code>.
  444. * @see java.lang.String#valueOf(boolean)
  445. * @see java.lang.StringBuffer#append(java.lang.String)
  446. */
  447. public StringBuffer append(boolean b) {
  448. return append(String.valueOf(b));
  449. }
  450. /**
  451. * Appends the string representation of the <code>char</code>
  452. * argument to this string buffer.
  453. * <p>
  454. * The argument is appended to the contents of this string buffer.
  455. * The length of this string buffer increases by <code>1</code>.
  456. * <p>
  457. * The overall effect is exactly as if the argument were converted to
  458. * a string by the method {@link String#valueOf(char)} and the character
  459. * in that string were then {@link #append(String) appended} to this
  460. * <code>StringBuffer</code> object.
  461. *
  462. * @param c a <code>char</code>.
  463. * @return a reference to this <code>StringBuffer</code> object.
  464. */
  465. public synchronized StringBuffer append(char c) {
  466. int newcount = count + 1;
  467. if (newcount > value.length)
  468. expandCapacity(newcount);
  469. value[count++] = c;
  470. return this;
  471. }
  472. /**
  473. * Appends the string representation of the <code>int</code>
  474. * argument to this string buffer.
  475. * <p>
  476. * The argument is converted to a string as if by the method
  477. * <code>String.valueOf</code>, and the characters of that
  478. * string are then appended to this string buffer.
  479. *
  480. * @param i an <code>int</code>.
  481. * @return a reference to this <code>StringBuffer</code> object.
  482. * @see java.lang.String#valueOf(int)
  483. * @see java.lang.StringBuffer#append(java.lang.String)
  484. */
  485. public StringBuffer append(int i) {
  486. return append(String.valueOf(i));
  487. }
  488. /**
  489. * Appends the string representation of the <code>long</code>
  490. * argument to this string buffer.
  491. * <p>
  492. * The argument is converted to a string as if by the method
  493. * <code>String.valueOf</code>, and the characters of that
  494. * string are then appended to this string buffer.
  495. *
  496. * @param l a <code>long</code>.
  497. * @return a referenct to this <code>StringBuffer</code> object.
  498. * @see java.lang.String#valueOf(long)
  499. * @see java.lang.StringBuffer#append(java.lang.String)
  500. */
  501. public StringBuffer append(long l) {
  502. return append(String.valueOf(l));
  503. }
  504. /**
  505. * Appends the string representation of the <code>float</code>
  506. * argument to this string buffer.
  507. * <p>
  508. * The argument is converted to a string as if by the method
  509. * <code>String.valueOf</code>, and the characters of that
  510. * string are then appended to this string buffer.
  511. *
  512. * @param f a <code>float</code>.
  513. * @return a reference to this <code>StringBuffer</code> object.
  514. * @see java.lang.String#valueOf(float)
  515. * @see java.lang.StringBuffer#append(java.lang.String)
  516. */
  517. public StringBuffer append(float f) {
  518. return append(String.valueOf(f));
  519. }
  520. /**
  521. * Appends the string representation of the <code>double</code>
  522. * argument to this string buffer.
  523. * <p>
  524. * The argument is converted to a string as if by the method
  525. * <code>String.valueOf</code>, and the characters of that
  526. * string are then appended to this string buffer.
  527. *
  528. * @param d a <code>double</code>.
  529. * @return a reference to this <code>StringBuffer</code> object.
  530. * @see java.lang.String#valueOf(double)
  531. * @see java.lang.StringBuffer#append(java.lang.String)
  532. */
  533. public StringBuffer append(double d) {
  534. return append(String.valueOf(d));
  535. }
  536. /**
  537. * Removes the characters in a substring of this <code>StringBuffer</code>.
  538. * The substring begins at the specified <code>start</code> and extends to
  539. * the character at index <code>end - 1</code> or to the end of the
  540. * <code>StringBuffer</code> if no such character exists. If
  541. * <code>start</code> is equal to <code>end</code>, no changes are made.
  542. *
  543. * @param start The beginning index, inclusive.
  544. * @param end The ending index, exclusive.
  545. * @return This string buffer.
  546. * @exception StringIndexOutOfBoundsException if <code>start</code>
  547. * is negative, greater than <code>length()</code>, or
  548. * greater than <code>end</code>.
  549. * @since 1.2
  550. */
  551. public synchronized StringBuffer delete(int start, int end) {
  552. if (start < 0)
  553. throw new StringIndexOutOfBoundsException(start);
  554. if (end > count)
  555. end = count;
  556. if (start > end)
  557. throw new StringIndexOutOfBoundsException();
  558. int len = end - start;
  559. if (len > 0) {
  560. if (shared)
  561. copy();
  562. System.arraycopy(value, start+len, value, start, count-end);
  563. count -= len;
  564. }
  565. return this;
  566. }
  567. /**
  568. * Removes the character at the specified position in this
  569. * <code>StringBuffer</code> (shortening the <code>StringBuffer</code>
  570. * by one character).
  571. *
  572. * @param index Index of character to remove
  573. * @return This string buffer.
  574. * @exception StringIndexOutOfBoundsException if the <code>index</code>
  575. * is negative or greater than or equal to
  576. * <code>length()</code>.
  577. * @since 1.2
  578. */
  579. public synchronized StringBuffer deleteCharAt(int index) {
  580. if ((index < 0) || (index >= count))
  581. throw new StringIndexOutOfBoundsException();
  582. if (shared)
  583. copy();
  584. System.arraycopy(value, index+1, value, index, count-index-1);
  585. count--;
  586. return this;
  587. }
  588. /**
  589. * Replaces the characters in a substring of this <code>StringBuffer</code>
  590. * with characters in the specified <code>String</code>. The substring
  591. * begins at the specified <code>start</code> and extends to the character
  592. * at index <code>end - 1</code> or to the end of the
  593. * <code>StringBuffer</code> if no such character exists. First the
  594. * characters in the substring are removed and then the specified
  595. * <code>String</code> is inserted at <code>start</code>. (The
  596. * <code>StringBuffer</code> will be lengthened to accommodate the
  597. * specified String if necessary.)
  598. *
  599. * @param start The beginning index, inclusive.
  600. * @param end The ending index, exclusive.
  601. * @param str String that will replace previous contents.
  602. * @return This string buffer.
  603. * @exception StringIndexOutOfBoundsException if <code>start</code>
  604. * is negative, greater than <code>length()</code>, or
  605. * greater than <code>end</code>.
  606. * @since 1.2
  607. */
  608. public synchronized StringBuffer replace(int start, int end, String str) {
  609. if (start < 0)
  610. throw new StringIndexOutOfBoundsException(start);
  611. if (end > count)
  612. end = count;
  613. if (start > end)
  614. throw new StringIndexOutOfBoundsException();
  615. int len = str.length();
  616. int newCount = count + len - (end - start);
  617. if (newCount > value.length)
  618. expandCapacity(newCount);
  619. else if (shared)
  620. copy();
  621. System.arraycopy(value, end, value, start + len, count - end);
  622. str.getChars(0, len, value, start);
  623. count = newCount;
  624. return this;
  625. }
  626. /**
  627. * Returns a new <code>String</code> that contains a subsequence of
  628. * characters currently contained in this <code>StringBuffer</code>.The
  629. * substring begins at the specified index and extends to the end of the
  630. * <code>StringBuffer</code>.
  631. *
  632. * @param start The beginning index, inclusive.
  633. * @return The new string.
  634. * @exception StringIndexOutOfBoundsException if <code>start</code> is
  635. * less than zero, or greater than the length of this
  636. * <code>StringBuffer</code>.
  637. * @since 1.2
  638. */
  639. public String substring(int start) {
  640. return substring(start, count);
  641. }
  642. /**
  643. * Returns a new <code>String</code> that contains a subsequence of
  644. * characters currently contained in this <code>StringBuffer</code>. The
  645. * substring begins at the specified <code>start</code> and
  646. * extends to the character at index <code>end - 1</code>. An
  647. * exception is thrown if
  648. *
  649. * @param start The beginning index, inclusive.
  650. * @param end The ending index, exclusive.
  651. * @return The new string.
  652. * @exception StringIndexOutOfBoundsException if <code>start</code>
  653. * or <code>end</code> are negative or greater than
  654. * <code>length()</code>, or <code>start</code> is
  655. * greater than <code>end</code>.
  656. * @since 1.2
  657. */
  658. public synchronized String substring(int start, int end) {
  659. if (start < 0)
  660. throw new StringIndexOutOfBoundsException(start);
  661. if (end > count)
  662. throw new StringIndexOutOfBoundsException(end);
  663. if (start > end)
  664. throw new StringIndexOutOfBoundsException(end - start);
  665. return new String(value, start, end - start);
  666. }
  667. /**
  668. * Inserts the string representation of a subarray of the <code>str</code>
  669. * array argument into this string buffer. The subarray begins at the
  670. * specified <code>offset</code> and extends <code>len</code> characters.
  671. * The characters of the subarray are inserted into this string buffer at
  672. * the position indicated by <code>index</code>. The length of this
  673. * <code>StringBuffer</code> increases by <code>len</code> characters.
  674. *
  675. * @param index position at which to insert subarray.
  676. * @param str A character array.
  677. * @param offset the index of the first character in subarray to
  678. * to be inserted.
  679. * @param len the number of characters in the subarray to
  680. * to be inserted.
  681. * @return This string buffer.
  682. * @exception StringIndexOutOfBoundsException if <code>index</code>
  683. * is negative or greater than <code>length()</code>, or
  684. * <code>offset</code> or <code>len</code> are negative, or
  685. * <code>(offset+len)</code> is greater than
  686. * <code>str.length</code>.
  687. * @since 1.2
  688. */
  689. public synchronized StringBuffer insert(int index, char str[], int offset,
  690. int len) {
  691. if ((index < 0) || (index > count))
  692. throw new StringIndexOutOfBoundsException();
  693. if ((offset < 0) || (offset + len < 0) || (offset + len > str.length))
  694. throw new StringIndexOutOfBoundsException(offset);
  695. if (len < 0)
  696. throw new StringIndexOutOfBoundsException(len);
  697. int newCount = count + len;
  698. if (newCount > value.length)
  699. expandCapacity(newCount);
  700. else if (shared)
  701. copy();
  702. System.arraycopy(value, index, value, index + len, count - index);
  703. System.arraycopy(str, offset, value, index, len);
  704. count = newCount;
  705. return this;
  706. }
  707. /**
  708. * Inserts the string representation of the <code>Object</code>
  709. * argument into this string buffer.
  710. * <p>
  711. * The second argument is converted to a string as if by the method
  712. * <code>String.valueOf</code>, and the characters of that
  713. * string are then inserted into this string buffer at the indicated
  714. * offset.
  715. * <p>
  716. * The offset argument must be greater than or equal to
  717. * <code>0</code>, and less than or equal to the length of this
  718. * string buffer.
  719. *
  720. * @param offset the offset.
  721. * @param obj an <code>Object</code>.
  722. * @return a reference to this <code>StringBuffer</code> object.
  723. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  724. * @see java.lang.String#valueOf(java.lang.Object)
  725. * @see java.lang.StringBuffer#insert(int, java.lang.String)
  726. * @see java.lang.StringBuffer#length()
  727. */
  728. public synchronized StringBuffer insert(int offset, Object obj) {
  729. return insert(offset, String.valueOf(obj));
  730. }
  731. /**
  732. * Inserts the string into this string buffer.
  733. * <p>
  734. * The characters of the <code>String</code> argument are inserted, in
  735. * order, into this string buffer at the indicated offset, moving up any
  736. * characters originally above that position and increasing the length
  737. * of this string buffer by the length of the argument. If
  738. * <code>str</code> is <code>null</code>, then the four characters
  739. * <code>"null"</code> are inserted into this string buffer.
  740. * <p>
  741. * The character at index <i>k</i> in the new character sequence is
  742. * equal to:
  743. * <ul>
  744. * <li>the character at index <i>k</i> in the old character sequence, if
  745. * <i>k</i> is less than <code>offset</code>
  746. * <li>the character at index <i>k</i><code>-offset</code> in the
  747. * argument <code>str</code>, if <i>k</i> is not less than
  748. * <code>offset</code> but is less than <code>offset+str.length()</code>
  749. * <li>the character at index <i>k</i><code>-str.length()</code> in the
  750. * old character sequence, if <i>k</i> is not less than
  751. * <code>offset+str.length()</code>
  752. * </ul><p>
  753. * The offset argument must be greater than or equal to
  754. * <code>0</code>, and less than or equal to the length of this
  755. * string buffer.
  756. *
  757. * @param offset the offset.
  758. * @param str a string.
  759. * @return a reference to this <code>StringBuffer</code> object.
  760. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  761. * @see java.lang.StringBuffer#length()
  762. */
  763. public synchronized StringBuffer insert(int offset, String str) {
  764. if ((offset < 0) || (offset > count)) {
  765. throw new StringIndexOutOfBoundsException();
  766. }
  767. if (str == null) {
  768. str = String.valueOf(str);
  769. }
  770. int len = str.length();
  771. int newcount = count + len;
  772. if (newcount > value.length)
  773. expandCapacity(newcount);
  774. else if (shared)
  775. copy();
  776. System.arraycopy(value, offset, value, offset + len, count - offset);
  777. str.getChars(0, len, value, offset);
  778. count = newcount;
  779. return this;
  780. }
  781. /**
  782. * Inserts the string representation of the <code>char</code> array
  783. * argument into this string buffer.
  784. * <p>
  785. * The characters of the array argument are inserted into the
  786. * contents of this string buffer at the position indicated by
  787. * <code>offset</code>. The length of this string buffer increases by
  788. * the length of the argument.
  789. * <p>
  790. * The overall effect is exactly as if the argument were converted to
  791. * a string by the method {@link String#valueOf(char[])} and the
  792. * characters of that string were then
  793. * {@link #insert(int,String) inserted} into this
  794. * <code>StringBuffer</code> object at the position indicated by
  795. * <code>offset</code>.
  796. *
  797. * @param offset the offset.
  798. * @param str a character array.
  799. * @return a reference to this <code>StringBuffer</code> object.
  800. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  801. */
  802. public synchronized StringBuffer insert(int offset, char str[]) {
  803. if ((offset < 0) || (offset > count)) {
  804. throw new StringIndexOutOfBoundsException();
  805. }
  806. int len = str.length;
  807. int newcount = count + len;
  808. if (newcount > value.length)
  809. expandCapacity(newcount);
  810. else if (shared)
  811. copy();
  812. System.arraycopy(value, offset, value, offset + len, count - offset);
  813. System.arraycopy(str, 0, value, offset, len);
  814. count = newcount;
  815. return this;
  816. }
  817. /**
  818. * Inserts the string representation of the <code>boolean</code>
  819. * argument into this string buffer.
  820. * <p>
  821. * The second argument is converted to a string as if by the method
  822. * <code>String.valueOf</code>, and the characters of that
  823. * string are then inserted into this string buffer at the indicated
  824. * offset.
  825. * <p>
  826. * The offset argument must be greater than or equal to
  827. * <code>0</code>, and less than or equal to the length of this
  828. * string buffer.
  829. *
  830. * @param offset the offset.
  831. * @param b a <code>boolean</code>.
  832. * @return a reference to this <code>StringBuffer</code> object.
  833. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  834. * @see java.lang.String#valueOf(boolean)
  835. * @see java.lang.StringBuffer#insert(int, java.lang.String)
  836. * @see java.lang.StringBuffer#length()
  837. */
  838. public StringBuffer insert(int offset, boolean b) {
  839. return insert(offset, String.valueOf(b));
  840. }
  841. /**
  842. * Inserts the string representation of the <code>char</code>
  843. * argument into this string buffer.
  844. * <p>
  845. * The second argument is inserted into the contents of this string
  846. * buffer at the position indicated by <code>offset</code>. The length
  847. * of this string buffer increases by one.
  848. * <p>
  849. * The overall effect is exactly as if the argument were converted to
  850. * a string by the method {@link String#valueOf(char)} and the character
  851. * in that string were then {@link #insert(int, String) inserted} into
  852. * this <code>StringBuffer</code> object at the position indicated by
  853. * <code>offset</code>.
  854. * <p>
  855. * The offset argument must be greater than or equal to
  856. * <code>0</code>, and less than or equal to the length of this
  857. * string buffer.
  858. *
  859. * @param offset the offset.
  860. * @param c a <code>char</code>.
  861. * @return a reference to this <code>StringBuffer</code> object.
  862. * @exception IndexOutOfBoundsException if the offset is invalid.
  863. * @see java.lang.StringBuffer#length()
  864. */
  865. public synchronized StringBuffer insert(int offset, char c) {
  866. int newcount = count + 1;
  867. if (newcount > value.length)
  868. expandCapacity(newcount);
  869. else if (shared)
  870. copy();
  871. System.arraycopy(value, offset, value, offset + 1, count - offset);
  872. value[offset] = c;
  873. count = newcount;
  874. return this;
  875. }
  876. /**
  877. * Inserts the string representation of the second <code>int</code>
  878. * argument into this string buffer.
  879. * <p>
  880. * The second argument is converted to a string as if by the method
  881. * <code>String.valueOf</code>, and the characters of that
  882. * string are then inserted into this string buffer at the indicated
  883. * offset.
  884. * <p>
  885. * The offset argument must be greater than or equal to
  886. * <code>0</code>, and less than or equal to the length of this
  887. * string buffer.
  888. *
  889. * @param offset the offset.
  890. * @param i an <code>int</code>.
  891. * @return a reference to this <code>StringBuffer</code> object.
  892. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  893. * @see java.lang.String#valueOf(int)
  894. * @see java.lang.StringBuffer#insert(int, java.lang.String)
  895. * @see java.lang.StringBuffer#length()
  896. */
  897. public StringBuffer insert(int offset, int i) {
  898. return insert(offset, String.valueOf(i));
  899. }
  900. /**
  901. * Inserts the string representation of the <code>long</code>
  902. * argument into this string buffer.
  903. * <p>
  904. * The second argument is converted to a string as if by the method
  905. * <code>String.valueOf</code>, and the characters of that
  906. * string are then inserted into this string buffer at the position
  907. * indicated by <code>offset</code>.
  908. * <p>
  909. * The offset argument must be greater than or equal to
  910. * <code>0</code>, and less than or equal to the length of this
  911. * string buffer.
  912. *
  913. * @param offset the offset.
  914. * @param l a <code>long</code>.
  915. * @return a reference to this <code>StringBuffer</code> object.
  916. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  917. * @see java.lang.String#valueOf(long)
  918. * @see java.lang.StringBuffer#insert(int, java.lang.String)
  919. * @see java.lang.StringBuffer#length()
  920. */
  921. public StringBuffer insert(int offset, long l) {
  922. return insert(offset, String.valueOf(l));
  923. }
  924. /**
  925. * Inserts the string representation of the <code>float</code>
  926. * argument into this string buffer.
  927. * <p>
  928. * The second argument is converted to a string as if by the method
  929. * <code>String.valueOf</code>, and the characters of that
  930. * string are then inserted into this string buffer at the indicated
  931. * offset.
  932. * <p>
  933. * The offset argument must be greater than or equal to
  934. * <code>0</code>, and less than or equal to the length of this
  935. * string buffer.
  936. *
  937. * @param offset the offset.
  938. * @param f a <code>float</code>.
  939. * @return a reference to this <code>StringBuffer</code> object.
  940. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  941. * @see java.lang.String#valueOf(float)
  942. * @see java.lang.StringBuffer#insert(int, java.lang.String)
  943. * @see java.lang.StringBuffer#length()
  944. */
  945. public StringBuffer insert(int offset, float f) {
  946. return insert(offset, String.valueOf(f));
  947. }
  948. /**
  949. * Inserts the string representation of the <code>double</code>
  950. * argument into this string buffer.
  951. * <p>
  952. * The second argument is converted to a string as if by the method
  953. * <code>String.valueOf</code>, and the characters of that
  954. * string are then inserted into this string buffer at the indicated
  955. * offset.
  956. * <p>
  957. * The offset argument must be greater than or equal to
  958. * <code>0</code>, and less than or equal to the length of this
  959. * string buffer.
  960. *
  961. * @param offset the offset.
  962. * @param d a <code>double</code>.
  963. * @return a reference to this <code>StringBuffer</code> object.
  964. * @exception StringIndexOutOfBoundsException if the offset is invalid.
  965. * @see java.lang.String#valueOf(double)
  966. * @see java.lang.StringBuffer#insert(int, java.lang.String)
  967. * @see java.lang.StringBuffer#length()
  968. */
  969. public StringBuffer insert(int offset, double d) {
  970. return insert(offset, String.valueOf(d));
  971. }
  972. /**
  973. * The character sequence contained in this string buffer is
  974. * replaced by the reverse of the sequence.
  975. * <p>
  976. * Let <i>n</i> be the length of the old character sequence, the one
  977. * contained in the string buffer just prior to execution of the
  978. * <code>reverse</code> method. Then the character at index <i>k</i> in
  979. * the new character sequence is equal to the character at index
  980. * <i>n-k-1</i> in the old character sequence.
  981. *
  982. * @return a reference to this <codeStringBuffer</code> object..
  983. * @since JDK1.0.2
  984. */
  985. public synchronized StringBuffer reverse() {
  986. if (shared) copy();
  987. int n = count - 1;
  988. for (int j = (n-1) >> 1; j >= 0; --j) {
  989. char temp = value[j];
  990. value[j] = value[n - j];
  991. value[n - j] = temp;
  992. }
  993. return this;
  994. }
  995. /**
  996. * Converts to a string representing the data in this string buffer.
  997. * A new <code>String</code> object is allocated and initialized to
  998. * contain the character sequence currently represented by this
  999. * string buffer. This <code>String</code> is then returned. Subsequent
  1000. * changes to the string buffer do not affect the contents of the
  1001. * <code>String</code>.
  1002. * <p>
  1003. * Implementation advice: This method can be coded so as to create a new
  1004. * <code>String</code> object without allocating new memory to hold a
  1005. * copy of the character sequence. Instead, the string can share the
  1006. * memory used by the string buffer. Any subsequent operation that alters
  1007. * the content or capacity of the string buffer must then make a copy of
  1008. * the internal buffer at that time. This strategy is effective for
  1009. * reducing the amount of memory allocated by a string concatenation
  1010. * operation when it is implemented using a string buffer.
  1011. *
  1012. * @return a string representation of the string buffer.
  1013. */
  1014. public String toString() {
  1015. return new String(this);
  1016. }
  1017. //
  1018. // The following two methods are needed by String to efficiently
  1019. // convert a StringBuffer into a String. They are not public.
  1020. // They shouldn't be called by anyone but String.
  1021. final void setShared() { shared = true; }
  1022. final char[] getValue() { return value; }
  1023. /**
  1024. * readObject is called to restore the state of the StringBuffer from
  1025. * a stream.
  1026. */
  1027. private synchronized void readObject(java.io.ObjectInputStream s)
  1028. throws java.io.IOException, ClassNotFoundException {
  1029. s.defaultReadObject();
  1030. value = (char[]) value.clone();
  1031. shared = false;
  1032. }
  1033. }