1. /*
  2. * @(#)StringBuffer.java 1.99 04/07/15
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.lang;
  8. import sun.misc.FloatingDecimal;
  9. /**
  10. * A thread-safe, mutable sequence of characters.
  11. * A string buffer is like a {@link String}, but can be modified. At any
  12. * point in time it contains some particular sequence of characters, but
  13. * the length and content of the sequence can be changed through certain
  14. * method calls.
  15. * <p>
  16. * String buffers are safe for use by multiple threads. The methods
  17. * are synchronized where necessary so that all the operations on any
  18. * particular instance behave as if they occur in some serial order
  19. * that is consistent with the order of the method calls made by each of
  20. * the individual threads involved.
  21. * <p>
  22. * The principal operations on a <code>StringBuffer</code> are the
  23. * <code>append</code> and <code>insert</code> methods, which are
  24. * overloaded so as to accept data of any type. Each effectively
  25. * converts a given datum to a string and then appends or inserts the
  26. * characters of that string to the string buffer. The
  27. * <code>append</code> method always adds these characters at the end
  28. * of the buffer; the <code>insert</code> method adds the characters at
  29. * a specified point.
  30. * <p>
  31. * For example, if <code>z</code> refers to a string buffer object
  32. * whose current contents are "<code>start</code>", then
  33. * the method call <code>z.append("le")</code> would cause the string
  34. * buffer to contain "<code>startle</code>", whereas
  35. * <code>z.insert(4, "le")</code> would alter the string buffer to
  36. * contain "<code>starlet</code>".
  37. * <p>
  38. * In general, if sb refers to an instance of a <code>StringBuffer</code>,
  39. * then <code>sb.append(x)</code> has the same effect as
  40. * <code>sb.insert(sb.length(), x)</code>.
  41. * <p>
  42. * Whenever an operation occurs involving a source sequence (such as
  43. * appending or inserting from a source sequence) this class synchronizes
  44. * only on the string buffer performing the operation, not on the source.
  45. * <p>
  46. * Every string buffer has a capacity. As long as the length of the
  47. * character sequence contained in the string buffer does not exceed
  48. * the capacity, it is not necessary to allocate a new internal
  49. * buffer array. If the internal buffer overflows, it is
  50. * automatically made larger.
  51. *
  52. * As of release JDK 5, this class has been supplemented with an equivalent
  53. * class designed for use by a single thread, {@link StringBuilder}. The
  54. * <tt>StringBuilder</tt> class should generally be used in preference to
  55. * this one, as it supports all of the same operations but it is faster, as
  56. * it performs no synchronization.
  57. *
  58. * @author Arthur van Hoff
  59. * @version 1.99, 07/15/04
  60. * @see java.lang.StringBuilder
  61. * @see java.lang.String
  62. * @since JDK1.0
  63. */
  64. public final class StringBuffer
  65. extends AbstractStringBuilder
  66. implements java.io.Serializable, CharSequence
  67. {
  68. /** use serialVersionUID from JDK 1.0.2 for interoperability */
  69. static final long serialVersionUID = 3388685877147921107L;
  70. /**
  71. * Constructs a string buffer with no characters in it and an
  72. * initial capacity of 16 characters.
  73. */
  74. public StringBuffer() {
  75. super(16);
  76. }
  77. /**
  78. * Constructs a string buffer with no characters in it and
  79. * the specified initial capacity.
  80. *
  81. * @param capacity the initial capacity.
  82. * @exception NegativeArraySizeException if the <code>capacity</code>
  83. * argument is less than <code>0</code>.
  84. */
  85. public StringBuffer(int capacity) {
  86. super(capacity);
  87. }
  88. /**
  89. * Constructs a string buffer initialized to the contents of the
  90. * specified string. The initial capacity of the string buffer is
  91. * <code>16</code> plus the length of the string argument.
  92. *
  93. * @param str the initial contents of the buffer.
  94. * @exception NullPointerException if <code>str</code> is <code>null</code>
  95. */
  96. public StringBuffer(String str) {
  97. super(str.length() + 16);
  98. append(str);
  99. }
  100. /**
  101. * Constructs a string buffer that contains the same characters
  102. * as the specified <code>CharSequence</code>. The initial capacity of
  103. * the string buffer is <code>16</code> plus the length of the
  104. * <code>CharSequence</code> argument.
  105. * <p>
  106. * If the length of the specified <code>CharSequence</code> is
  107. * less than or equal to zero, then an empty buffer of capacity
  108. * <code>16</code> is returned.
  109. *
  110. * @param seq the sequence to copy.
  111. * @exception NullPointerException if <code>seq</code> is <code>null</code>
  112. * @since 1.5
  113. */
  114. public StringBuffer(CharSequence seq) {
  115. this(seq.length() + 16);
  116. append(seq);
  117. }
  118. public synchronized int length() {
  119. return count;
  120. }
  121. public synchronized int capacity() {
  122. return value.length;
  123. }
  124. public synchronized void ensureCapacity(int minimumCapacity) {
  125. if (minimumCapacity > value.length) {
  126. expandCapacity(minimumCapacity);
  127. }
  128. }
  129. /**
  130. * @since 1.5
  131. */
  132. public synchronized void trimToSize() {
  133. super.trimToSize();
  134. }
  135. /**
  136. * @throws IndexOutOfBoundsException {@inheritDoc}
  137. * @see #length()
  138. */
  139. public synchronized void setLength(int newLength) {
  140. super.setLength(newLength);
  141. }
  142. /**
  143. * @throws IndexOutOfBoundsException {@inheritDoc}
  144. * @see #length()
  145. */
  146. public synchronized char charAt(int index) {
  147. if ((index < 0) || (index >= count))
  148. throw new StringIndexOutOfBoundsException(index);
  149. return value[index];
  150. }
  151. /**
  152. * @since 1.5
  153. */
  154. public synchronized int codePointAt(int index) {
  155. return super.codePointAt(index);
  156. }
  157. /**
  158. * @since 1.5
  159. */
  160. public synchronized int codePointBefore(int index) {
  161. return super.codePointBefore(index);
  162. }
  163. /**
  164. * @since 1.5
  165. */
  166. public synchronized int codePointCount(int beginIndex, int endIndex) {
  167. return super.codePointCount(beginIndex, endIndex);
  168. }
  169. /**
  170. * @since 1.5
  171. */
  172. public synchronized int offsetByCodePoints(int index, int codePointOffset) {
  173. return super.offsetByCodePoints(index, codePointOffset);
  174. }
  175. /**
  176. * @throws NullPointerException {@inheritDoc}
  177. * @throws IndexOutOfBoundsException {@inheritDoc}
  178. */
  179. public synchronized void getChars(int srcBegin, int srcEnd, char dst[],
  180. int dstBegin)
  181. {
  182. super.getChars(srcBegin, srcEnd, dst, dstBegin);
  183. }
  184. /**
  185. * @throws IndexOutOfBoundsException {@inheritDoc}
  186. * @see #length()
  187. */
  188. public synchronized void setCharAt(int index, char ch) {
  189. if ((index < 0) || (index >= count))
  190. throw new StringIndexOutOfBoundsException(index);
  191. value[index] = ch;
  192. }
  193. /**
  194. * @see java.lang.String#valueOf(java.lang.Object)
  195. * @see #append(java.lang.String)
  196. */
  197. public synchronized StringBuffer append(Object obj) {
  198. super.append(String.valueOf(obj));
  199. return this;
  200. }
  201. public synchronized StringBuffer append(String str) {
  202. super.append(str);
  203. return this;
  204. }
  205. /**
  206. * Appends the specified <tt>StringBuffer</tt> to this sequence.
  207. * <p>
  208. * The characters of the <tt>StringBuffer</tt> argument are appended,
  209. * in order, to the contents of this <tt>StringBuffer</tt>, increasing the
  210. * length of this <tt>StringBuffer</tt> by the length of the argument.
  211. * If <tt>sb</tt> is <tt>null</tt>, then the four characters
  212. * <tt>"null"</tt> are appended to this <tt>StringBuffer</tt>.
  213. * <p>
  214. * Let <i>n</i> be the length of the old character sequence, the one
  215. * contained in the <tt>StringBuffer</tt> just prior to execution of the
  216. * <tt>append</tt> method. Then the character at index <i>k</i> in
  217. * the new character sequence is equal to the character at index <i>k</i>
  218. * in the old character sequence, if <i>k</i> is less than <i>n</i>
  219. * otherwise, it is equal to the character at index <i>k-n</i> in the
  220. * argument <code>sb</code>.
  221. * <p>
  222. * This method synchronizes on <code>this</code> (the destination)
  223. * object but does not synchronize on the source (<code>sb</code>).
  224. *
  225. * @param sb the <tt>StringBuffer</tt> to append.
  226. * @return a reference to this object.
  227. * @since 1.4
  228. */
  229. public synchronized StringBuffer append(StringBuffer sb) {
  230. super.append(sb);
  231. return this;
  232. }
  233. /**
  234. * Appends the specified <code>CharSequence</code> to this
  235. * sequence.
  236. * <p>
  237. * The characters of the <code>CharSequence</code> argument are appended,
  238. * in order, increasing the length of this sequence by the length of the
  239. * argument.
  240. *
  241. * <p>The result of this method is exactly the same as if it were an
  242. * invocation of this.append(s, 0, s.length());
  243. *
  244. * <p>This method synchronizes on this (the destination)
  245. * object but does not synchronize on the source (<code>s</code>).
  246. *
  247. * <p>If <code>s</code> is <code>null</code>, then the four characters
  248. * <code>"null"</code> are appended.
  249. *
  250. * @param s the <code>CharSequence</code> to append.
  251. * @return a reference to this object.
  252. * @since 1.5
  253. */
  254. public StringBuffer append(CharSequence s) {
  255. // Note, synchronization achieved via other invocations
  256. if (s == null)
  257. s = "null";
  258. if (s instanceof String)
  259. return this.append((String)s);
  260. if (s instanceof StringBuffer)
  261. return this.append((StringBuffer)s);
  262. return this.append(s, 0, s.length());
  263. }
  264. /**
  265. * @throws IndexOutOfBoundsException {@inheritDoc}
  266. * @since 1.5
  267. */
  268. public synchronized StringBuffer append(CharSequence s, int start, int end)
  269. {
  270. super.append(s, start, end);
  271. return this;
  272. }
  273. public synchronized StringBuffer append(char str[]) {
  274. super.append(str);
  275. return this;
  276. }
  277. public synchronized StringBuffer append(char str[], int offset, int len) {
  278. super.append(str, offset, len);
  279. return this;
  280. }
  281. /**
  282. * @see java.lang.String#valueOf(boolean)
  283. * @see #append(java.lang.String)
  284. */
  285. public synchronized StringBuffer append(boolean b) {
  286. super.append(b);
  287. return this;
  288. }
  289. public synchronized StringBuffer append(char c) {
  290. super.append(c);
  291. return this;
  292. }
  293. /**
  294. * @see java.lang.String#valueOf(int)
  295. * @see #append(java.lang.String)
  296. */
  297. public synchronized StringBuffer append(int i) {
  298. super.append(i);
  299. return this;
  300. }
  301. /**
  302. * @since 1.5
  303. */
  304. public synchronized StringBuffer appendCodePoint(int codePoint) {
  305. super.appendCodePoint(codePoint);
  306. return this;
  307. }
  308. /**
  309. * @see java.lang.String#valueOf(long)
  310. * @see #append(java.lang.String)
  311. */
  312. public synchronized StringBuffer append(long lng) {
  313. super.append(lng);
  314. return this;
  315. }
  316. /**
  317. * @see java.lang.String#valueOf(float)
  318. * @see #append(java.lang.String)
  319. */
  320. public synchronized StringBuffer append(float f) {
  321. new FloatingDecimal(f).appendTo(this);
  322. return this;
  323. }
  324. /**
  325. * @see java.lang.String#valueOf(double)
  326. * @see #append(java.lang.String)
  327. */
  328. public synchronized StringBuffer append(double d) {
  329. new FloatingDecimal(d).appendTo(this);
  330. return this;
  331. }
  332. /**
  333. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  334. * @since 1.2
  335. */
  336. public synchronized StringBuffer delete(int start, int end) {
  337. super.delete(start, end);
  338. return this;
  339. }
  340. /**
  341. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  342. * @since 1.2
  343. */
  344. public synchronized StringBuffer deleteCharAt(int index) {
  345. super.deleteCharAt(index);
  346. return this;
  347. }
  348. /**
  349. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  350. * @since 1.2
  351. */
  352. public synchronized StringBuffer replace(int start, int end, String str) {
  353. super.replace(start, end, str);
  354. return this;
  355. }
  356. /**
  357. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  358. * @since 1.2
  359. */
  360. public synchronized String substring(int start) {
  361. return substring(start, count);
  362. }
  363. /**
  364. * @throws IndexOutOfBoundsException {@inheritDoc}
  365. * @since 1.4
  366. */
  367. public synchronized CharSequence subSequence(int start, int end) {
  368. return super.substring(start, end);
  369. }
  370. /**
  371. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  372. * @since 1.2
  373. */
  374. public synchronized String substring(int start, int end) {
  375. return super.substring(start, end);
  376. }
  377. /**
  378. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  379. * @since 1.2
  380. */
  381. public synchronized StringBuffer insert(int index, char str[], int offset,
  382. int len)
  383. {
  384. super.insert(index, str, offset, len);
  385. return this;
  386. }
  387. /**
  388. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  389. * @see java.lang.String#valueOf(java.lang.Object)
  390. * @see #insert(int, java.lang.String)
  391. * @see #length()
  392. */
  393. public synchronized StringBuffer insert(int offset, Object obj) {
  394. super.insert(offset, String.valueOf(obj));
  395. return this;
  396. }
  397. /**
  398. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  399. * @see #length()
  400. */
  401. public synchronized StringBuffer insert(int offset, String str) {
  402. super.insert(offset, str);
  403. return this;
  404. }
  405. /**
  406. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  407. */
  408. public synchronized StringBuffer insert(int offset, char str[]) {
  409. super.insert(offset, str);
  410. return this;
  411. }
  412. /**
  413. * @throws IndexOutOfBoundsException {@inheritDoc}
  414. * @since 1.5
  415. */
  416. public StringBuffer insert(int dstOffset, CharSequence s) {
  417. // Note, synchronization achieved via other invocations
  418. if (s == null)
  419. s = "null";
  420. if (s instanceof String)
  421. return this.insert(dstOffset, (String)s);
  422. return this.insert(dstOffset, s, 0, s.length());
  423. }
  424. /**
  425. * @throws IndexOutOfBoundsException {@inheritDoc}
  426. * @since 1.5
  427. */
  428. public synchronized StringBuffer insert(int dstOffset, CharSequence s,
  429. int start, int end)
  430. {
  431. super.insert(dstOffset, s, start, end);
  432. return this;
  433. }
  434. /**
  435. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  436. * @see java.lang.String#valueOf(boolean)
  437. * @see #insert(int, java.lang.String)
  438. * @see #length()
  439. */
  440. public StringBuffer insert(int offset, boolean b) {
  441. return insert(offset, String.valueOf(b));
  442. }
  443. /**
  444. * @throws IndexOutOfBoundsException {@inheritDoc}
  445. * @see #length()
  446. */
  447. public synchronized StringBuffer insert(int offset, char c) {
  448. super.insert(offset, c);
  449. return this;
  450. }
  451. /**
  452. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  453. * @see java.lang.String#valueOf(int)
  454. * @see #insert(int, java.lang.String)
  455. * @see #length()
  456. */
  457. public StringBuffer insert(int offset, int i) {
  458. return insert(offset, String.valueOf(i));
  459. }
  460. /**
  461. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  462. * @see java.lang.String#valueOf(long)
  463. * @see #insert(int, java.lang.String)
  464. * @see #length()
  465. */
  466. public StringBuffer insert(int offset, long l) {
  467. return insert(offset, String.valueOf(l));
  468. }
  469. /**
  470. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  471. * @see java.lang.String#valueOf(float)
  472. * @see #insert(int, java.lang.String)
  473. * @see #length()
  474. */
  475. public StringBuffer insert(int offset, float f) {
  476. return insert(offset, String.valueOf(f));
  477. }
  478. /**
  479. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  480. * @see java.lang.String#valueOf(double)
  481. * @see #insert(int, java.lang.String)
  482. * @see #length()
  483. */
  484. public StringBuffer insert(int offset, double d) {
  485. return insert(offset, String.valueOf(d));
  486. }
  487. /**
  488. * @throws NullPointerException {@inheritDoc}
  489. * @since 1.4
  490. */
  491. public int indexOf(String str) {
  492. return indexOf(str, 0);
  493. }
  494. /**
  495. * @throws NullPointerException {@inheritDoc}
  496. * @since 1.4
  497. */
  498. public synchronized int indexOf(String str, int fromIndex) {
  499. return String.indexOf(value, 0, count,
  500. str.toCharArray(), 0, str.length(), fromIndex);
  501. }
  502. /**
  503. * @throws NullPointerException {@inheritDoc}
  504. * @since 1.4
  505. */
  506. public int lastIndexOf(String str) {
  507. // Note, synchronization achieved via other invocations
  508. return lastIndexOf(str, count);
  509. }
  510. /**
  511. * @throws NullPointerException {@inheritDoc}
  512. * @since 1.4
  513. */
  514. public synchronized int lastIndexOf(String str, int fromIndex) {
  515. return String.lastIndexOf(value, 0, count,
  516. str.toCharArray(), 0, str.length(), fromIndex);
  517. }
  518. /**
  519. * @since JDK1.0.2
  520. */
  521. public synchronized StringBuffer reverse() {
  522. super.reverse();
  523. return this;
  524. }
  525. public synchronized String toString() {
  526. return new String(value, 0, count);
  527. }
  528. /**
  529. * Serializable fields for StringBuffer.
  530. *
  531. * @serialField value char[]
  532. * The backing character array of this StringBuffer.
  533. * @serialField count int
  534. * The number of characters in this StringBuffer.
  535. * @serialField shared boolean
  536. * A flag indicating whether the backing array is shared.
  537. * The value is ignored upon deserialization.
  538. */
  539. private static final java.io.ObjectStreamField[] serialPersistentFields =
  540. {
  541. new java.io.ObjectStreamField("value", char[].class),
  542. new java.io.ObjectStreamField("count", Integer.TYPE),
  543. new java.io.ObjectStreamField("shared", Boolean.TYPE),
  544. };
  545. /**
  546. * readObject is called to restore the state of the StringBuffer from
  547. * a stream.
  548. */
  549. private synchronized void writeObject(java.io.ObjectOutputStream s)
  550. throws java.io.IOException {
  551. java.io.ObjectOutputStream.PutField fields = s.putFields();
  552. fields.put("value", value);
  553. fields.put("count", count);
  554. fields.put("shared", false);
  555. s.writeFields();
  556. }
  557. /**
  558. * readObject is called to restore the state of the StringBuffer from
  559. * a stream.
  560. */
  561. private void readObject(java.io.ObjectInputStream s)
  562. throws java.io.IOException, ClassNotFoundException {
  563. java.io.ObjectInputStream.GetField fields = s.readFields();
  564. value = (char[])fields.get("value", null);
  565. count = (int)fields.get("count", 0);
  566. }
  567. }