< prev index next >

src/java.base/share/classes/java/lang/AbstractStringBuilder.java

Print this page




  53  * @author      Ulf Zibis
  54  * @since       1.5
  55  */
  56 abstract class AbstractStringBuilder implements Appendable, CharSequence {
  57     /**
  58      * The value is used for character storage.
  59      */
  60     byte[] value;
  61 
  62     /**
  63      * The id of the encoding used to encode the bytes in {@code value}.
  64      */
  65     byte coder;
  66 
  67     /**
  68      * The count is the number of characters used.
  69      */
  70     int count;
  71 
  72     /**





  73      * This no-arg constructor is necessary for serialization of subclasses.
  74      */
  75     AbstractStringBuilder() {
  76     }
  77 
  78     /**
  79      * Creates an AbstractStringBuilder of the specified capacity.
  80      */
  81     AbstractStringBuilder(int capacity) {
  82         if (COMPACT_STRINGS) {
  83             value = new byte[capacity];
  84             coder = LATIN1;
  85         } else {
  86             value = StringUTF16.newBytesFor(capacity);
  87             coder = UTF16;
  88         }
  89     }
  90 









  91     /**
  92      * Returns the length (character count).
  93      *
  94      * @return  the length of the sequence of characters currently
  95      *          represented by this object
  96      */
  97     @Override
  98     public int length() {
  99         return count;
 100     }
 101 
 102     /**
 103      * Returns the current capacity. The capacity is the amount of storage
 104      * available for newly inserted characters, beyond which an allocation
 105      * will occur.
 106      *
 107      * @return  the current capacity
 108      */
 109     public int capacity() {
 110         return value.length >> coder;


 149      * size check or synchronization.
 150      */
 151     private void expandCapacity(int minimumCapacity) {
 152         int newCapacity = (value.length >> coder) * 2 + 2;
 153         if (newCapacity - minimumCapacity < 0) {
 154             newCapacity = minimumCapacity;
 155         }
 156         if (newCapacity < 0) {
 157             if (minimumCapacity < 0) {// overflow
 158                 throw new OutOfMemoryError();
 159             }
 160             newCapacity = Integer.MAX_VALUE;
 161         }
 162         if (coder != LATIN1 && newCapacity > StringUTF16.MAX_LENGTH) {
 163             if (minimumCapacity >= StringUTF16.MAX_LENGTH) {
 164                 throw new OutOfMemoryError();
 165             }
 166             newCapacity = StringUTF16.MAX_LENGTH;
 167         }
 168         this.value = Arrays.copyOf(value, newCapacity << coder);

 169     }
 170 
 171     /**
 172      * If the coder is "isLatin1", this inflates the internal 8-bit storage
 173      * to 16-bit <hi=0, low> pair storage.
 174      */
 175     private void inflate() {
 176         if (!isLatin1()) {
 177             return;
 178         }
 179         byte[] buf = StringUTF16.newBytesFor(value.length);
 180         StringLatin1.inflateSB(value, buf, 0, count);
 181         this.value = buf;
 182         this.coder = UTF16;

 183     }
 184 
 185     /**
 186      * Attempts to reduce storage used for the character sequence.
 187      * If the buffer is larger than necessary to hold its current sequence of
 188      * characters, then it may be resized to become more space efficient.
 189      * Calling this method may, but is not required to, affect the value
 190      * returned by a subsequent call to the {@link #capacity()} method.
 191      */
 192     public void trimToSize() {
 193         int length = count << coder;
 194         if (length < value.length) {
 195             value = Arrays.copyOf(value, length);
 196         }
 197     }
 198 
 199     /**
 200      * Sets the length of the character sequence.
 201      * The sequence is changed to a new character sequence
 202      * whose length is specified by the argument. For every nonnegative


 208      *
 209      * In other words, if the {@code newLength} argument is less than
 210      * the current length, the length is changed to the specified length.
 211      * <p>
 212      * If the {@code newLength} argument is greater than or equal
 213      * to the current length, sufficient null characters
 214      * ({@code '\u005Cu0000'}) are appended so that
 215      * length becomes the {@code newLength} argument.
 216      * <p>
 217      * The {@code newLength} argument must be greater than or equal
 218      * to {@code 0}.
 219      *
 220      * @param      newLength   the new length
 221      * @throws     IndexOutOfBoundsException  if the
 222      *               {@code newLength} argument is negative.
 223      */
 224     public void setLength(int newLength) {
 225         if (newLength < 0) {
 226             throw new StringIndexOutOfBoundsException(newLength);
 227         }
 228         ensureCapacityInternal(newLength);
 229         if (count < newLength) {

 230             if (isLatin1()) {
 231                 StringLatin1.fillNull(value, count, newLength);
 232             } else {
 233                 StringUTF16.fillNull(value, count, newLength);
 234             }


 235         }
 236         count = newLength;
 237     }
 238 
 239     /**
 240      * Returns the {@code char} value in this sequence at the specified index.
 241      * The first {@code char} value is at index {@code 0}, the next at index
 242      * {@code 1}, and so on, as in array indexing.
 243      * <p>
 244      * The index argument must be greater than or equal to
 245      * {@code 0}, and less than the length of this sequence.
 246      *
 247      * <p>If the {@code char} value specified by the index is a
 248      * <a href="Character.html#unicode">surrogate</a>, the surrogate
 249      * value is returned.
 250      *
 251      * @param      index   the index of the desired {@code char} value.
 252      * @return     the {@code char} value at the specified index.
 253      * @throws     IndexOutOfBoundsException  if {@code index} is
 254      *             negative or greater than or equal to {@code length()}.


 420         }
 421     }
 422 
 423     /**
 424      * The character at the specified index is set to {@code ch}. This
 425      * sequence is altered to represent a new character sequence that is
 426      * identical to the old character sequence, except that it contains the
 427      * character {@code ch} at position {@code index}.
 428      * <p>
 429      * The index argument must be greater than or equal to
 430      * {@code 0}, and less than the length of this sequence.
 431      *
 432      * @param      index   the index of the character to modify.
 433      * @param      ch      the new character.
 434      * @throws     IndexOutOfBoundsException  if {@code index} is
 435      *             negative or greater than or equal to {@code length()}.
 436      */
 437     public void setCharAt(int index, char ch) {
 438         checkIndex(index, count);
 439         if (isLatin1() && StringLatin1.canEncode(ch)) {

 440             value[index] = (byte)ch;
 441         } else {
 442             if (isLatin1()) {
 443                 inflate();


 444             }
 445             StringUTF16.putCharSB(value, index, ch);
 446         }
 447     }
 448 
 449     /**
 450      * Appends the string representation of the {@code Object} argument.
 451      * <p>
 452      * The overall effect is exactly as if the argument were converted
 453      * to a string by the method {@link String#valueOf(Object)},
 454      * and the characters of that string were then
 455      * {@link #append(String) appended} to this character sequence.
 456      *
 457      * @param   obj   an {@code Object}.
 458      * @return  a reference to this object.
 459      */
 460     public AbstractStringBuilder append(Object obj) {
 461         return append(String.valueOf(obj));
 462     }
 463 


 809      * Removes the characters in a substring of this sequence.
 810      * The substring begins at the specified {@code start} and extends to
 811      * the character at index {@code end - 1} or to the end of the
 812      * sequence if no such character exists. If
 813      * {@code start} is equal to {@code end}, no changes are made.
 814      *
 815      * @param      start  The beginning index, inclusive.
 816      * @param      end    The ending index, exclusive.
 817      * @return     This object.
 818      * @throws     StringIndexOutOfBoundsException  if {@code start}
 819      *             is negative, greater than {@code length()}, or
 820      *             greater than {@code end}.
 821      */
 822     public AbstractStringBuilder delete(int start, int end) {
 823         if (end > count) {
 824             end = count;
 825         }
 826         checkRangeSIOOBE(start, end, count);
 827         int len = end - start;
 828         if (len > 0) {

 829             shift(end, -len);
 830             count -= len;
 831         }
 832         return this;
 833     }
 834 
 835     /**
 836      * Appends the string representation of the {@code codePoint}
 837      * argument to this sequence.
 838      *
 839      * <p> The argument is appended to the contents of this sequence.
 840      * The length of this sequence increases by
 841      * {@link Character#charCount(int) Character.charCount(codePoint)}.
 842      *
 843      * <p> The overall effect is exactly as if the argument were
 844      * converted to a {@code char} array by the method
 845      * {@link Character#toChars(int)} and the character in that array
 846      * were then {@link #append(char[]) appended} to this character
 847      * sequence.
 848      *


 860 
 861     /**
 862      * Removes the {@code char} at the specified position in this
 863      * sequence. This sequence is shortened by one {@code char}.
 864      *
 865      * <p>Note: If the character at the given index is a supplementary
 866      * character, this method does not remove the entire character. If
 867      * correct handling of supplementary characters is required,
 868      * determine the number of {@code char}s to remove by calling
 869      * {@code Character.charCount(thisSequence.codePointAt(index))},
 870      * where {@code thisSequence} is this sequence.
 871      *
 872      * @param       index  Index of {@code char} to remove
 873      * @return      This object.
 874      * @throws      StringIndexOutOfBoundsException  if the {@code index}
 875      *              is negative or greater than or equal to
 876      *              {@code length()}.
 877      */
 878     public AbstractStringBuilder deleteCharAt(int index) {
 879         checkIndex(index, count);

 880         shift(index + 1, -1);
 881         count--;
 882         return this;
 883     }
 884 
 885     /**
 886      * Replaces the characters in a substring of this sequence
 887      * with characters in the specified {@code String}. The substring
 888      * begins at the specified {@code start} and extends to the character
 889      * at index {@code end - 1} or to the end of the
 890      * sequence if no such character exists. First the
 891      * characters in the substring are removed and then the specified
 892      * {@code String} is inserted at {@code start}. (This
 893      * sequence will be lengthened to accommodate the
 894      * specified String if necessary.)
 895      *
 896      * @param      start    The beginning index, inclusive.
 897      * @param      end      The ending index, exclusive.
 898      * @param      str   String that will replace previous contents.
 899      * @return     This object.
 900      * @throws     StringIndexOutOfBoundsException  if {@code start}
 901      *             is negative, greater than {@code length()}, or
 902      *             greater than {@code end}.
 903      */
 904     public AbstractStringBuilder replace(int start, int end, String str) {
 905         if (end > count) {
 906             end = count;
 907         }
 908         checkRangeSIOOBE(start, end, count);
 909         int len = str.length();
 910         int newCount = count + len - (end - start);
 911         ensureCapacityInternal(newCount);

 912         shift(end, newCount - count);
 913         count = newCount;
 914         putStringAt(start, str);
 915         return this;
 916     }
 917 
 918     /**
 919      * Returns a new {@code String} that contains a subsequence of
 920      * characters currently contained in this character sequence. The
 921      * substring begins at the specified index and extends to the end of
 922      * this sequence.
 923      *
 924      * @param      start    The beginning index, inclusive.
 925      * @return     The new string.
 926      * @throws     StringIndexOutOfBoundsException  if {@code start} is
 927      *             less than zero, or greater than the length of this object.
 928      */
 929     public String substring(int start) {
 930         return substring(start, count);
 931     }


1448      * sequence, these are treated as single characters for the
1449      * reverse operation. Thus, the order of the high-low surrogates
1450      * is never reversed.
1451      *
1452      * Let <i>n</i> be the character length of this character sequence
1453      * (not the length in {@code char} values) just prior to
1454      * execution of the {@code reverse} method. Then the
1455      * character at index <i>k</i> in the new character sequence is
1456      * equal to the character at index <i>n-k-1</i> in the old
1457      * character sequence.
1458      *
1459      * <p>Note that the reverse operation may result in producing
1460      * surrogate pairs that were unpaired low-surrogates and
1461      * high-surrogates before the operation. For example, reversing
1462      * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
1463      * a valid surrogate pair.
1464      *
1465      * @return  a reference to this object.
1466      */
1467     public AbstractStringBuilder reverse() {
1468         byte[] val = this.value;
1469         int count = this.count;
1470         int coder = this.coder;
1471         int n = count - 1;
1472         if (COMPACT_STRINGS && coder == LATIN1) {
1473             for (int j = (n-1) >> 1; j >= 0; j--) {
1474                 int k = n - j;
1475                 byte cj = val[j];
1476                 val[j] = val[k];
1477                 val[k] = cj;
1478             }
1479         } else {
1480             checkOffset(count, val.length >> 1);
1481             boolean hasSurrogates = false;
1482             for (int j = (n-1) >> 1; j >= 0; j--) {
1483                 int k = n - j;
1484                 char cj = StringUTF16.getChar(val, j);
1485                 char ck = StringUTF16.getChar(val, k);
1486                 StringUTF16.putChar(val, j, ck);
1487                 StringUTF16.putChar(val, k, cj);
1488                 if (Character.isSurrogate(cj) ||


1558                 false);
1559     }
1560 
1561     /**
1562      * Needed by {@code String} for the contentEquals method.
1563      */
1564     final byte[] getValue() {
1565         return value;
1566     }
1567 
1568     /*
1569      * Invoker guarantees it is in UTF16 (inflate itself for asb), if two
1570      * coders are different and the dstBegin has enough space
1571      *
1572      * @param dstBegin  the char index, not offset of byte[]
1573      * @param coder     the coder of dst[]
1574      */
1575     void getBytes(byte dst[], int dstBegin, byte coder) {
1576         if (this.coder == coder) {
1577             System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
1578         } else {        // this.coder == LATIN && coder == UTF16
1579             StringLatin1.inflateSB(value, dst, dstBegin, count);
1580         }
1581     }
1582 
1583     /* for readObject() */
1584     void initBytes(char[] value, int off, int len) {
1585         if (String.COMPACT_STRINGS) {
1586             this.value = StringUTF16.compress(value, off, len);
1587             if (this.value != null) {
1588                 this.coder = LATIN1;
1589                 return;
1590             }
1591         }
1592         this.coder = UTF16;
1593         this.value = StringUTF16.toBytes(value, off, len);
1594     }
1595 
1596     final byte getCoder() {
1597         return COMPACT_STRINGS ? coder : UTF16;
1598     }




  53  * @author      Ulf Zibis
  54  * @since       1.5
  55  */
  56 abstract class AbstractStringBuilder implements Appendable, CharSequence {
  57     /**
  58      * The value is used for character storage.
  59      */
  60     byte[] value;
  61 
  62     /**
  63      * The id of the encoding used to encode the bytes in {@code value}.
  64      */
  65     byte coder;
  66 
  67     /**
  68      * The count is the number of characters used.
  69      */
  70     int count;
  71 
  72     /**
  73      * Whether value array is shared with a String.
  74      */
  75     transient boolean shared;
  76 
  77     /**
  78      * This no-arg constructor is necessary for serialization of subclasses.
  79      */
  80     AbstractStringBuilder() {
  81     }
  82 
  83     /**
  84      * Creates an AbstractStringBuilder of the specified capacity.
  85      */
  86     AbstractStringBuilder(int capacity) {
  87         if (COMPACT_STRINGS) {
  88             value = new byte[capacity];
  89             coder = LATIN1;
  90         } else {
  91             value = StringUTF16.newBytesFor(capacity);
  92             coder = UTF16;
  93         }
  94     }
  95 
  96     byte[] unshareValue() {
  97         if (shared) {
  98             // assert (count << coder) == value.length
  99             value = Arrays.copyOf(value, value.length);
 100             shared = false;
 101         }
 102         return value;
 103     }
 104 
 105     /**
 106      * Returns the length (character count).
 107      *
 108      * @return  the length of the sequence of characters currently
 109      *          represented by this object
 110      */
 111     @Override
 112     public int length() {
 113         return count;
 114     }
 115 
 116     /**
 117      * Returns the current capacity. The capacity is the amount of storage
 118      * available for newly inserted characters, beyond which an allocation
 119      * will occur.
 120      *
 121      * @return  the current capacity
 122      */
 123     public int capacity() {
 124         return value.length >> coder;


 163      * size check or synchronization.
 164      */
 165     private void expandCapacity(int minimumCapacity) {
 166         int newCapacity = (value.length >> coder) * 2 + 2;
 167         if (newCapacity - minimumCapacity < 0) {
 168             newCapacity = minimumCapacity;
 169         }
 170         if (newCapacity < 0) {
 171             if (minimumCapacity < 0) {// overflow
 172                 throw new OutOfMemoryError();
 173             }
 174             newCapacity = Integer.MAX_VALUE;
 175         }
 176         if (coder != LATIN1 && newCapacity > StringUTF16.MAX_LENGTH) {
 177             if (minimumCapacity >= StringUTF16.MAX_LENGTH) {
 178                 throw new OutOfMemoryError();
 179             }
 180             newCapacity = StringUTF16.MAX_LENGTH;
 181         }
 182         this.value = Arrays.copyOf(value, newCapacity << coder);
 183         this.shared = false;
 184     }
 185 
 186     /**
 187      * If the coder is "isLatin1", this inflates the internal 8-bit storage
 188      * to 16-bit <hi=0, low> pair storage.
 189      */
 190     private void inflate() {
 191         if (!isLatin1()) {
 192             return;
 193         }
 194         byte[] buf = StringUTF16.newBytesFor(value.length);
 195         StringLatin1.inflateSB(value, buf, 0, count);
 196         this.value = buf;
 197         this.coder = UTF16;
 198         this.shared = false;
 199     }
 200 
 201     /**
 202      * Attempts to reduce storage used for the character sequence.
 203      * If the buffer is larger than necessary to hold its current sequence of
 204      * characters, then it may be resized to become more space efficient.
 205      * Calling this method may, but is not required to, affect the value
 206      * returned by a subsequent call to the {@link #capacity()} method.
 207      */
 208     public void trimToSize() {
 209         int length = count << coder;
 210         if (length < value.length) {
 211             value = Arrays.copyOf(value, length);
 212         }
 213     }
 214 
 215     /**
 216      * Sets the length of the character sequence.
 217      * The sequence is changed to a new character sequence
 218      * whose length is specified by the argument. For every nonnegative


 224      *
 225      * In other words, if the {@code newLength} argument is less than
 226      * the current length, the length is changed to the specified length.
 227      * <p>
 228      * If the {@code newLength} argument is greater than or equal
 229      * to the current length, sufficient null characters
 230      * ({@code '\u005Cu0000'}) are appended so that
 231      * length becomes the {@code newLength} argument.
 232      * <p>
 233      * The {@code newLength} argument must be greater than or equal
 234      * to {@code 0}.
 235      *
 236      * @param      newLength   the new length
 237      * @throws     IndexOutOfBoundsException  if the
 238      *               {@code newLength} argument is negative.
 239      */
 240     public void setLength(int newLength) {
 241         if (newLength < 0) {
 242             throw new StringIndexOutOfBoundsException(newLength);
 243         }

 244         if (count < newLength) {
 245             ensureCapacityInternal(newLength);
 246             if (isLatin1()) {
 247                 StringLatin1.fillNull(value, count, newLength);
 248             } else {
 249                 StringUTF16.fillNull(value, count, newLength);
 250             }
 251         } else if (newLength < count) {
 252             unshareValue();
 253         }
 254         count = newLength;
 255     }
 256 
 257     /**
 258      * Returns the {@code char} value in this sequence at the specified index.
 259      * The first {@code char} value is at index {@code 0}, the next at index
 260      * {@code 1}, and so on, as in array indexing.
 261      * <p>
 262      * The index argument must be greater than or equal to
 263      * {@code 0}, and less than the length of this sequence.
 264      *
 265      * <p>If the {@code char} value specified by the index is a
 266      * <a href="Character.html#unicode">surrogate</a>, the surrogate
 267      * value is returned.
 268      *
 269      * @param      index   the index of the desired {@code char} value.
 270      * @return     the {@code char} value at the specified index.
 271      * @throws     IndexOutOfBoundsException  if {@code index} is
 272      *             negative or greater than or equal to {@code length()}.


 438         }
 439     }
 440 
 441     /**
 442      * The character at the specified index is set to {@code ch}. This
 443      * sequence is altered to represent a new character sequence that is
 444      * identical to the old character sequence, except that it contains the
 445      * character {@code ch} at position {@code index}.
 446      * <p>
 447      * The index argument must be greater than or equal to
 448      * {@code 0}, and less than the length of this sequence.
 449      *
 450      * @param      index   the index of the character to modify.
 451      * @param      ch      the new character.
 452      * @throws     IndexOutOfBoundsException  if {@code index} is
 453      *             negative or greater than or equal to {@code length()}.
 454      */
 455     public void setCharAt(int index, char ch) {
 456         checkIndex(index, count);
 457         if (isLatin1() && StringLatin1.canEncode(ch)) {
 458             final byte[] value = unshareValue();
 459             value[index] = (byte)ch;
 460         } else {
 461             if (isLatin1()) {
 462                 inflate();
 463             } else {
 464                 unshareValue();
 465             }
 466             StringUTF16.putCharSB(value, index, ch);
 467         }
 468     }
 469 
 470     /**
 471      * Appends the string representation of the {@code Object} argument.
 472      * <p>
 473      * The overall effect is exactly as if the argument were converted
 474      * to a string by the method {@link String#valueOf(Object)},
 475      * and the characters of that string were then
 476      * {@link #append(String) appended} to this character sequence.
 477      *
 478      * @param   obj   an {@code Object}.
 479      * @return  a reference to this object.
 480      */
 481     public AbstractStringBuilder append(Object obj) {
 482         return append(String.valueOf(obj));
 483     }
 484 


 830      * Removes the characters in a substring of this sequence.
 831      * The substring begins at the specified {@code start} and extends to
 832      * the character at index {@code end - 1} or to the end of the
 833      * sequence if no such character exists. If
 834      * {@code start} is equal to {@code end}, no changes are made.
 835      *
 836      * @param      start  The beginning index, inclusive.
 837      * @param      end    The ending index, exclusive.
 838      * @return     This object.
 839      * @throws     StringIndexOutOfBoundsException  if {@code start}
 840      *             is negative, greater than {@code length()}, or
 841      *             greater than {@code end}.
 842      */
 843     public AbstractStringBuilder delete(int start, int end) {
 844         if (end > count) {
 845             end = count;
 846         }
 847         checkRangeSIOOBE(start, end, count);
 848         int len = end - start;
 849         if (len > 0) {
 850             unshareValue();
 851             shift(end, -len);
 852             count -= len;
 853         }
 854         return this;
 855     }
 856 
 857     /**
 858      * Appends the string representation of the {@code codePoint}
 859      * argument to this sequence.
 860      *
 861      * <p> The argument is appended to the contents of this sequence.
 862      * The length of this sequence increases by
 863      * {@link Character#charCount(int) Character.charCount(codePoint)}.
 864      *
 865      * <p> The overall effect is exactly as if the argument were
 866      * converted to a {@code char} array by the method
 867      * {@link Character#toChars(int)} and the character in that array
 868      * were then {@link #append(char[]) appended} to this character
 869      * sequence.
 870      *


 882 
 883     /**
 884      * Removes the {@code char} at the specified position in this
 885      * sequence. This sequence is shortened by one {@code char}.
 886      *
 887      * <p>Note: If the character at the given index is a supplementary
 888      * character, this method does not remove the entire character. If
 889      * correct handling of supplementary characters is required,
 890      * determine the number of {@code char}s to remove by calling
 891      * {@code Character.charCount(thisSequence.codePointAt(index))},
 892      * where {@code thisSequence} is this sequence.
 893      *
 894      * @param       index  Index of {@code char} to remove
 895      * @return      This object.
 896      * @throws      StringIndexOutOfBoundsException  if the {@code index}
 897      *              is negative or greater than or equal to
 898      *              {@code length()}.
 899      */
 900     public AbstractStringBuilder deleteCharAt(int index) {
 901         checkIndex(index, count);
 902         unshareValue();
 903         shift(index + 1, -1);
 904         count--;
 905         return this;
 906     }
 907 
 908     /**
 909      * Replaces the characters in a substring of this sequence
 910      * with characters in the specified {@code String}. The substring
 911      * begins at the specified {@code start} and extends to the character
 912      * at index {@code end - 1} or to the end of the
 913      * sequence if no such character exists. First the
 914      * characters in the substring are removed and then the specified
 915      * {@code String} is inserted at {@code start}. (This
 916      * sequence will be lengthened to accommodate the
 917      * specified String if necessary.)
 918      *
 919      * @param      start    The beginning index, inclusive.
 920      * @param      end      The ending index, exclusive.
 921      * @param      str   String that will replace previous contents.
 922      * @return     This object.
 923      * @throws     StringIndexOutOfBoundsException  if {@code start}
 924      *             is negative, greater than {@code length()}, or
 925      *             greater than {@code end}.
 926      */
 927     public AbstractStringBuilder replace(int start, int end, String str) {
 928         if (end > count) {
 929             end = count;
 930         }
 931         checkRangeSIOOBE(start, end, count);
 932         int len = str.length();
 933         int newCount = count + len - (end - start);
 934         ensureCapacityInternal(newCount);
 935         unshareValue();
 936         shift(end, newCount - count);
 937         count = newCount;
 938         putStringAt(start, str);
 939         return this;
 940     }
 941 
 942     /**
 943      * Returns a new {@code String} that contains a subsequence of
 944      * characters currently contained in this character sequence. The
 945      * substring begins at the specified index and extends to the end of
 946      * this sequence.
 947      *
 948      * @param      start    The beginning index, inclusive.
 949      * @return     The new string.
 950      * @throws     StringIndexOutOfBoundsException  if {@code start} is
 951      *             less than zero, or greater than the length of this object.
 952      */
 953     public String substring(int start) {
 954         return substring(start, count);
 955     }


1472      * sequence, these are treated as single characters for the
1473      * reverse operation. Thus, the order of the high-low surrogates
1474      * is never reversed.
1475      *
1476      * Let <i>n</i> be the character length of this character sequence
1477      * (not the length in {@code char} values) just prior to
1478      * execution of the {@code reverse} method. Then the
1479      * character at index <i>k</i> in the new character sequence is
1480      * equal to the character at index <i>n-k-1</i> in the old
1481      * character sequence.
1482      *
1483      * <p>Note that the reverse operation may result in producing
1484      * surrogate pairs that were unpaired low-surrogates and
1485      * high-surrogates before the operation. For example, reversing
1486      * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
1487      * a valid surrogate pair.
1488      *
1489      * @return  a reference to this object.
1490      */
1491     public AbstractStringBuilder reverse() {
1492         byte[] val = unshareValue();
1493         int count = this.count;
1494         int coder = this.coder;
1495         int n = count - 1;
1496         if (COMPACT_STRINGS && coder == LATIN1) {
1497             for (int j = (n-1) >> 1; j >= 0; j--) {
1498                 int k = n - j;
1499                 byte cj = val[j];
1500                 val[j] = val[k];
1501                 val[k] = cj;
1502             }
1503         } else {
1504             checkOffset(count, val.length >> 1);
1505             boolean hasSurrogates = false;
1506             for (int j = (n-1) >> 1; j >= 0; j--) {
1507                 int k = n - j;
1508                 char cj = StringUTF16.getChar(val, j);
1509                 char ck = StringUTF16.getChar(val, k);
1510                 StringUTF16.putChar(val, j, ck);
1511                 StringUTF16.putChar(val, k, cj);
1512                 if (Character.isSurrogate(cj) ||


1582                 false);
1583     }
1584 
1585     /**
1586      * Needed by {@code String} for the contentEquals method.
1587      */
1588     final byte[] getValue() {
1589         return value;
1590     }
1591 
1592     /*
1593      * Invoker guarantees it is in UTF16 (inflate itself for asb), if two
1594      * coders are different and the dstBegin has enough space
1595      *
1596      * @param dstBegin  the char index, not offset of byte[]
1597      * @param coder     the coder of dst[]
1598      */
1599     void getBytes(byte dst[], int dstBegin, byte coder) {
1600         if (this.coder == coder) {
1601             System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
1602         } else {        // this.coder == LATIN1 && coder == UTF16
1603             StringLatin1.inflateSB(value, dst, dstBegin, count);
1604         }
1605     }
1606 
1607     /* for readObject() */
1608     void initBytes(char[] value, int off, int len) {
1609         if (String.COMPACT_STRINGS) {
1610             this.value = StringUTF16.compress(value, off, len);
1611             if (this.value != null) {
1612                 this.coder = LATIN1;
1613                 return;
1614             }
1615         }
1616         this.coder = UTF16;
1617         this.value = StringUTF16.toBytes(value, off, len);
1618     }
1619 
1620     final byte getCoder() {
1621         return COMPACT_STRINGS ? coder : UTF16;
1622     }


< prev index next >