Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
41152 views
1
/*
2
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.lang;
27
28
import jdk.internal.math.FloatingDecimal;
29
30
import java.util.Arrays;
31
import java.util.Spliterator;
32
import java.util.stream.IntStream;
33
import java.util.stream.StreamSupport;
34
import jdk.internal.util.ArraysSupport;
35
36
import static java.lang.String.COMPACT_STRINGS;
37
import static java.lang.String.UTF16;
38
import static java.lang.String.LATIN1;
39
import static java.lang.String.checkIndex;
40
import static java.lang.String.checkOffset;
41
42
/**
43
* A mutable sequence of characters.
44
* <p>
45
* Implements a modifiable string. At any point in time it contains some
46
* particular sequence of characters, but the length and content of the
47
* sequence can be changed through certain method calls.
48
*
49
* <p>Unless otherwise noted, passing a {@code null} argument to a constructor
50
* or method in this class will cause a {@link NullPointerException} to be
51
* thrown.
52
*
53
* @author Michael McCloskey
54
* @author Martin Buchholz
55
* @author Ulf Zibis
56
* @since 1.5
57
*/
58
abstract class AbstractStringBuilder implements Appendable, CharSequence {
59
/**
60
* The value is used for character storage.
61
*/
62
byte[] value;
63
64
/**
65
* The id of the encoding used to encode the bytes in {@code value}.
66
*/
67
byte coder;
68
69
/**
70
* The count is the number of characters used.
71
*/
72
int count;
73
74
private static final byte[] EMPTYVALUE = new byte[0];
75
76
/**
77
* This no-arg constructor is necessary for serialization of subclasses.
78
*/
79
AbstractStringBuilder() {
80
value = EMPTYVALUE;
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
/**
97
* Constructs an AbstractStringBuilder that contains the same characters
98
* as the specified {@code String}. The initial capacity of
99
* the string builder is {@code 16} plus the length of the
100
* {@code String} argument.
101
*
102
* @param str the string to copy.
103
*/
104
AbstractStringBuilder(String str) {
105
int length = str.length();
106
int capacity = (length < Integer.MAX_VALUE - 16)
107
? length + 16 : Integer.MAX_VALUE;
108
final byte initCoder = str.coder();
109
coder = initCoder;
110
value = (initCoder == LATIN1)
111
? new byte[capacity] : StringUTF16.newBytesFor(capacity);
112
append(str);
113
}
114
115
/**
116
* Constructs an AbstractStringBuilder that contains the same characters
117
* as the specified {@code CharSequence}. The initial capacity of
118
* the string builder is {@code 16} plus the length of the
119
* {@code CharSequence} argument.
120
*
121
* @param seq the sequence to copy.
122
*/
123
AbstractStringBuilder(CharSequence seq) {
124
int length = seq.length();
125
if (length < 0) {
126
throw new NegativeArraySizeException("Negative length: " + length);
127
}
128
int capacity = (length < Integer.MAX_VALUE - 16)
129
? length + 16 : Integer.MAX_VALUE;
130
131
final byte initCoder;
132
if (COMPACT_STRINGS) {
133
if (seq instanceof AbstractStringBuilder) {
134
initCoder = ((AbstractStringBuilder)seq).getCoder();
135
} else if (seq instanceof String) {
136
initCoder = ((String)seq).coder();
137
} else {
138
initCoder = LATIN1;
139
}
140
} else {
141
initCoder = UTF16;
142
}
143
144
coder = initCoder;
145
value = (initCoder == LATIN1)
146
? new byte[capacity] : StringUTF16.newBytesFor(capacity);
147
append(seq);
148
}
149
150
/**
151
* Compares the objects of two AbstractStringBuilder implementations lexicographically.
152
*
153
* @since 11
154
*/
155
int compareTo(AbstractStringBuilder another) {
156
if (this == another) {
157
return 0;
158
}
159
160
byte[] val1 = value;
161
byte[] val2 = another.value;
162
int count1 = this.count;
163
int count2 = another.count;
164
165
if (coder == another.coder) {
166
return isLatin1() ? StringLatin1.compareTo(val1, val2, count1, count2)
167
: StringUTF16.compareTo(val1, val2, count1, count2);
168
}
169
return isLatin1() ? StringLatin1.compareToUTF16(val1, val2, count1, count2)
170
: StringUTF16.compareToLatin1(val1, val2, count1, count2);
171
}
172
173
/**
174
* Returns the length (character count).
175
*
176
* @return the length of the sequence of characters currently
177
* represented by this object
178
*/
179
@Override
180
public int length() {
181
return count;
182
}
183
184
/**
185
* Returns the current capacity. The capacity is the number of characters
186
* that can be stored (including already written characters), beyond which
187
* an allocation will occur.
188
*
189
* @return the current capacity
190
*/
191
public int capacity() {
192
return value.length >> coder;
193
}
194
195
/**
196
* Ensures that the capacity is at least equal to the specified minimum.
197
* If the current capacity is less than the argument, then a new internal
198
* array is allocated with greater capacity. The new capacity is the
199
* larger of:
200
* <ul>
201
* <li>The {@code minimumCapacity} argument.
202
* <li>Twice the old capacity, plus {@code 2}.
203
* </ul>
204
* If the {@code minimumCapacity} argument is nonpositive, this
205
* method takes no action and simply returns.
206
* Note that subsequent operations on this object can reduce the
207
* actual capacity below that requested here.
208
*
209
* @param minimumCapacity the minimum desired capacity.
210
*/
211
public void ensureCapacity(int minimumCapacity) {
212
if (minimumCapacity > 0) {
213
ensureCapacityInternal(minimumCapacity);
214
}
215
}
216
217
/**
218
* For positive values of {@code minimumCapacity}, this method
219
* behaves like {@code ensureCapacity}, however it is never
220
* synchronized.
221
* If {@code minimumCapacity} is non positive due to numeric
222
* overflow, this method throws {@code OutOfMemoryError}.
223
*/
224
private void ensureCapacityInternal(int minimumCapacity) {
225
// overflow-conscious code
226
int oldCapacity = value.length >> coder;
227
if (minimumCapacity - oldCapacity > 0) {
228
value = Arrays.copyOf(value,
229
newCapacity(minimumCapacity) << coder);
230
}
231
}
232
233
/**
234
* The maximum size of array to allocate (unless necessary).
235
* Some VMs reserve some header words in an array.
236
* Attempts to allocate larger arrays may result in
237
* OutOfMemoryError: Requested array size exceeds VM limit
238
*/
239
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
240
241
/**
242
* Returns a capacity at least as large as the given minimum capacity.
243
* Returns the current capacity increased by the current length + 2 if
244
* that suffices.
245
* Will not return a capacity greater than
246
* {@code (MAX_ARRAY_SIZE >> coder)} unless the given minimum capacity
247
* is greater than that.
248
*
249
* @param minCapacity the desired minimum capacity
250
* @throws OutOfMemoryError if minCapacity is less than zero or
251
* greater than (Integer.MAX_VALUE >> coder)
252
*/
253
private int newCapacity(int minCapacity) {
254
int oldLength = value.length;
255
int newLength = minCapacity << coder;
256
int growth = newLength - oldLength;
257
int length = ArraysSupport.newLength(oldLength, growth, oldLength + (2 << coder));
258
if (length == Integer.MAX_VALUE) {
259
throw new OutOfMemoryError("Required length exceeds implementation limit");
260
}
261
return length >> coder;
262
}
263
264
/**
265
* If the coder is "isLatin1", this inflates the internal 8-bit storage
266
* to 16-bit <hi=0, low> pair storage.
267
*/
268
private void inflate() {
269
if (!isLatin1()) {
270
return;
271
}
272
byte[] buf = StringUTF16.newBytesFor(value.length);
273
StringLatin1.inflate(value, 0, buf, 0, count);
274
this.value = buf;
275
this.coder = UTF16;
276
}
277
278
/**
279
* Attempts to reduce storage used for the character sequence.
280
* If the buffer is larger than necessary to hold its current sequence of
281
* characters, then it may be resized to become more space efficient.
282
* Calling this method may, but is not required to, affect the value
283
* returned by a subsequent call to the {@link #capacity()} method.
284
*/
285
public void trimToSize() {
286
int length = count << coder;
287
if (length < value.length) {
288
value = Arrays.copyOf(value, length);
289
}
290
}
291
292
/**
293
* Sets the length of the character sequence.
294
* The sequence is changed to a new character sequence
295
* whose length is specified by the argument. For every nonnegative
296
* index <i>k</i> less than {@code newLength}, the character at
297
* index <i>k</i> in the new character sequence is the same as the
298
* character at index <i>k</i> in the old sequence if <i>k</i> is less
299
* than the length of the old character sequence; otherwise, it is the
300
* null character {@code '\u005Cu0000'}.
301
*
302
* In other words, if the {@code newLength} argument is less than
303
* the current length, the length is changed to the specified length.
304
* <p>
305
* If the {@code newLength} argument is greater than or equal
306
* to the current length, sufficient null characters
307
* ({@code '\u005Cu0000'}) are appended so that
308
* length becomes the {@code newLength} argument.
309
* <p>
310
* The {@code newLength} argument must be greater than or equal
311
* to {@code 0}.
312
*
313
* @param newLength the new length
314
* @throws IndexOutOfBoundsException if the
315
* {@code newLength} argument is negative.
316
*/
317
public void setLength(int newLength) {
318
if (newLength < 0) {
319
throw new StringIndexOutOfBoundsException(newLength);
320
}
321
ensureCapacityInternal(newLength);
322
if (count < newLength) {
323
if (isLatin1()) {
324
StringLatin1.fillNull(value, count, newLength);
325
} else {
326
StringUTF16.fillNull(value, count, newLength);
327
}
328
}
329
count = newLength;
330
}
331
332
/**
333
* Returns the {@code char} value in this sequence at the specified index.
334
* The first {@code char} value is at index {@code 0}, the next at index
335
* {@code 1}, and so on, as in array indexing.
336
* <p>
337
* The index argument must be greater than or equal to
338
* {@code 0}, and less than the length of this sequence.
339
*
340
* <p>If the {@code char} value specified by the index is a
341
* <a href="Character.html#unicode">surrogate</a>, the surrogate
342
* value is returned.
343
*
344
* @param index the index of the desired {@code char} value.
345
* @return the {@code char} value at the specified index.
346
* @throws IndexOutOfBoundsException if {@code index} is
347
* negative or greater than or equal to {@code length()}.
348
*/
349
@Override
350
public char charAt(int index) {
351
checkIndex(index, count);
352
if (isLatin1()) {
353
return (char)(value[index] & 0xff);
354
}
355
return StringUTF16.charAt(value, index);
356
}
357
358
/**
359
* Returns the character (Unicode code point) at the specified
360
* index. The index refers to {@code char} values
361
* (Unicode code units) and ranges from {@code 0} to
362
* {@link #length()}{@code - 1}.
363
*
364
* <p> If the {@code char} value specified at the given index
365
* is in the high-surrogate range, the following index is less
366
* than the length of this sequence, and the
367
* {@code char} value at the following index is in the
368
* low-surrogate range, then the supplementary code point
369
* corresponding to this surrogate pair is returned. Otherwise,
370
* the {@code char} value at the given index is returned.
371
*
372
* @param index the index to the {@code char} values
373
* @return the code point value of the character at the
374
* {@code index}
375
* @throws IndexOutOfBoundsException if the {@code index}
376
* argument is negative or not less than the length of this
377
* sequence.
378
*/
379
public int codePointAt(int index) {
380
int count = this.count;
381
byte[] value = this.value;
382
checkIndex(index, count);
383
if (isLatin1()) {
384
return value[index] & 0xff;
385
}
386
return StringUTF16.codePointAtSB(value, index, count);
387
}
388
389
/**
390
* Returns the character (Unicode code point) before the specified
391
* index. The index refers to {@code char} values
392
* (Unicode code units) and ranges from {@code 1} to {@link
393
* #length()}.
394
*
395
* <p> If the {@code char} value at {@code (index - 1)}
396
* is in the low-surrogate range, {@code (index - 2)} is not
397
* negative, and the {@code char} value at {@code (index -
398
* 2)} is in the high-surrogate range, then the
399
* supplementary code point value of the surrogate pair is
400
* returned. If the {@code char} value at {@code index -
401
* 1} is an unpaired low-surrogate or a high-surrogate, the
402
* surrogate value is returned.
403
*
404
* @param index the index following the code point that should be returned
405
* @return the Unicode code point value before the given index.
406
* @throws IndexOutOfBoundsException if the {@code index}
407
* argument is less than 1 or greater than the length
408
* of this sequence.
409
*/
410
public int codePointBefore(int index) {
411
int i = index - 1;
412
if (i < 0 || i >= count) {
413
throw new StringIndexOutOfBoundsException(index);
414
}
415
if (isLatin1()) {
416
return value[i] & 0xff;
417
}
418
return StringUTF16.codePointBeforeSB(value, index);
419
}
420
421
/**
422
* Returns the number of Unicode code points in the specified text
423
* range of this sequence. The text range begins at the specified
424
* {@code beginIndex} and extends to the {@code char} at
425
* index {@code endIndex - 1}. Thus the length (in
426
* {@code char}s) of the text range is
427
* {@code endIndex-beginIndex}. Unpaired surrogates within
428
* this sequence count as one code point each.
429
*
430
* @param beginIndex the index to the first {@code char} of
431
* the text range.
432
* @param endIndex the index after the last {@code char} of
433
* the text range.
434
* @return the number of Unicode code points in the specified text
435
* range
436
* @throws IndexOutOfBoundsException if the
437
* {@code beginIndex} is negative, or {@code endIndex}
438
* is larger than the length of this sequence, or
439
* {@code beginIndex} is larger than {@code endIndex}.
440
*/
441
public int codePointCount(int beginIndex, int endIndex) {
442
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
443
throw new IndexOutOfBoundsException();
444
}
445
if (isLatin1()) {
446
return endIndex - beginIndex;
447
}
448
return StringUTF16.codePointCountSB(value, beginIndex, endIndex);
449
}
450
451
/**
452
* Returns the index within this sequence that is offset from the
453
* given {@code index} by {@code codePointOffset} code
454
* points. Unpaired surrogates within the text range given by
455
* {@code index} and {@code codePointOffset} count as
456
* one code point each.
457
*
458
* @param index the index to be offset
459
* @param codePointOffset the offset in code points
460
* @return the index within this sequence
461
* @throws IndexOutOfBoundsException if {@code index}
462
* is negative or larger then the length of this sequence,
463
* or if {@code codePointOffset} is positive and the subsequence
464
* starting with {@code index} has fewer than
465
* {@code codePointOffset} code points,
466
* or if {@code codePointOffset} is negative and the subsequence
467
* before {@code index} has fewer than the absolute value of
468
* {@code codePointOffset} code points.
469
*/
470
public int offsetByCodePoints(int index, int codePointOffset) {
471
if (index < 0 || index > count) {
472
throw new IndexOutOfBoundsException();
473
}
474
return Character.offsetByCodePoints(this,
475
index, codePointOffset);
476
}
477
478
/**
479
* Characters are copied from this sequence into the
480
* destination character array {@code dst}. The first character to
481
* be copied is at index {@code srcBegin}; the last character to
482
* be copied is at index {@code srcEnd-1}. The total number of
483
* characters to be copied is {@code srcEnd-srcBegin}. The
484
* characters are copied into the subarray of {@code dst} starting
485
* at index {@code dstBegin} and ending at index:
486
* <pre>{@code
487
* dstbegin + (srcEnd-srcBegin) - 1
488
* }</pre>
489
*
490
* @param srcBegin start copying at this offset.
491
* @param srcEnd stop copying at this offset.
492
* @param dst the array to copy the data into.
493
* @param dstBegin offset into {@code dst}.
494
* @throws IndexOutOfBoundsException if any of the following is true:
495
* <ul>
496
* <li>{@code srcBegin} is negative
497
* <li>{@code dstBegin} is negative
498
* <li>the {@code srcBegin} argument is greater than
499
* the {@code srcEnd} argument.
500
* <li>{@code srcEnd} is greater than
501
* {@code this.length()}.
502
* <li>{@code dstBegin+srcEnd-srcBegin} is greater than
503
* {@code dst.length}
504
* </ul>
505
*/
506
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
507
{
508
checkRangeSIOOBE(srcBegin, srcEnd, count); // compatible to old version
509
int n = srcEnd - srcBegin;
510
checkRange(dstBegin, dstBegin + n, dst.length);
511
if (isLatin1()) {
512
StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin);
513
} else {
514
StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin);
515
}
516
}
517
518
/**
519
* The character at the specified index is set to {@code ch}. This
520
* sequence is altered to represent a new character sequence that is
521
* identical to the old character sequence, except that it contains the
522
* character {@code ch} at position {@code index}.
523
* <p>
524
* The index argument must be greater than or equal to
525
* {@code 0}, and less than the length of this sequence.
526
*
527
* @param index the index of the character to modify.
528
* @param ch the new character.
529
* @throws IndexOutOfBoundsException if {@code index} is
530
* negative or greater than or equal to {@code length()}.
531
*/
532
public void setCharAt(int index, char ch) {
533
checkIndex(index, count);
534
if (isLatin1() && StringLatin1.canEncode(ch)) {
535
value[index] = (byte)ch;
536
} else {
537
if (isLatin1()) {
538
inflate();
539
}
540
StringUTF16.putCharSB(value, index, ch);
541
}
542
}
543
544
/**
545
* Appends the string representation of the {@code Object} argument.
546
* <p>
547
* The overall effect is exactly as if the argument were converted
548
* to a string by the method {@link String#valueOf(Object)},
549
* and the characters of that string were then
550
* {@link #append(String) appended} to this character sequence.
551
*
552
* @param obj an {@code Object}.
553
* @return a reference to this object.
554
*/
555
public AbstractStringBuilder append(Object obj) {
556
return append(String.valueOf(obj));
557
}
558
559
/**
560
* Appends the specified string to this character sequence.
561
* <p>
562
* The characters of the {@code String} argument are appended, in
563
* order, increasing the length of this sequence by the length of the
564
* argument. If {@code str} is {@code null}, then the four
565
* characters {@code "null"} are appended.
566
* <p>
567
* Let <i>n</i> be the length of this character sequence just prior to
568
* execution of the {@code append} method. Then the character at
569
* index <i>k</i> in the new character sequence is equal to the character
570
* at index <i>k</i> in the old character sequence, if <i>k</i> is less
571
* than <i>n</i>; otherwise, it is equal to the character at index
572
* <i>k-n</i> in the argument {@code str}.
573
*
574
* @param str a string.
575
* @return a reference to this object.
576
*/
577
public AbstractStringBuilder append(String str) {
578
if (str == null) {
579
return appendNull();
580
}
581
int len = str.length();
582
ensureCapacityInternal(count + len);
583
putStringAt(count, str);
584
count += len;
585
return this;
586
}
587
588
/**
589
* Appends the specified {@code StringBuffer} to this sequence.
590
*
591
* @param sb the {@code StringBuffer} to append.
592
* @return a reference to this object.
593
*/
594
public AbstractStringBuilder append(StringBuffer sb) {
595
return this.append((AbstractStringBuilder)sb);
596
}
597
598
/**
599
* @since 1.8
600
*/
601
AbstractStringBuilder append(AbstractStringBuilder asb) {
602
if (asb == null) {
603
return appendNull();
604
}
605
int len = asb.length();
606
ensureCapacityInternal(count + len);
607
if (getCoder() != asb.getCoder()) {
608
inflate();
609
}
610
asb.getBytes(value, count, coder);
611
count += len;
612
return this;
613
}
614
615
// Documentation in subclasses because of synchro difference
616
@Override
617
public AbstractStringBuilder append(CharSequence s) {
618
if (s == null) {
619
return appendNull();
620
}
621
if (s instanceof String) {
622
return this.append((String)s);
623
}
624
if (s instanceof AbstractStringBuilder) {
625
return this.append((AbstractStringBuilder)s);
626
}
627
return this.append(s, 0, s.length());
628
}
629
630
private AbstractStringBuilder appendNull() {
631
ensureCapacityInternal(count + 4);
632
int count = this.count;
633
byte[] val = this.value;
634
if (isLatin1()) {
635
val[count++] = 'n';
636
val[count++] = 'u';
637
val[count++] = 'l';
638
val[count++] = 'l';
639
} else {
640
count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
641
}
642
this.count = count;
643
return this;
644
}
645
646
/**
647
* Appends a subsequence of the specified {@code CharSequence} to this
648
* sequence.
649
* <p>
650
* Characters of the argument {@code s}, starting at
651
* index {@code start}, are appended, in order, to the contents of
652
* this sequence up to the (exclusive) index {@code end}. The length
653
* of this sequence is increased by the value of {@code end - start}.
654
* <p>
655
* Let <i>n</i> be the length of this character sequence just prior to
656
* execution of the {@code append} method. Then the character at
657
* index <i>k</i> in this character sequence becomes equal to the
658
* character at index <i>k</i> in this sequence, if <i>k</i> is less than
659
* <i>n</i>; otherwise, it is equal to the character at index
660
* <i>k+start-n</i> in the argument {@code s}.
661
* <p>
662
* If {@code s} is {@code null}, then this method appends
663
* characters as if the s parameter was a sequence containing the four
664
* characters {@code "null"}.
665
*
666
* @param s the sequence to append.
667
* @param start the starting index of the subsequence to be appended.
668
* @param end the end index of the subsequence to be appended.
669
* @return a reference to this object.
670
* @throws IndexOutOfBoundsException if
671
* {@code start} is negative, or
672
* {@code start} is greater than {@code end} or
673
* {@code end} is greater than {@code s.length()}
674
*/
675
@Override
676
public AbstractStringBuilder append(CharSequence s, int start, int end) {
677
if (s == null) {
678
s = "null";
679
}
680
checkRange(start, end, s.length());
681
int len = end - start;
682
ensureCapacityInternal(count + len);
683
if (s instanceof String) {
684
appendChars((String)s, start, end);
685
} else {
686
appendChars(s, start, end);
687
}
688
return this;
689
}
690
691
692
/**
693
* Appends the string representation of the {@code char} array
694
* argument to this sequence.
695
* <p>
696
* The characters of the array argument are appended, in order, to
697
* the contents of this sequence. The length of this sequence
698
* increases by the length of the argument.
699
* <p>
700
* The overall effect is exactly as if the argument were converted
701
* to a string by the method {@link String#valueOf(char[])},
702
* and the characters of that string were then
703
* {@link #append(String) appended} to this character sequence.
704
*
705
* @param str the characters to be appended.
706
* @return a reference to this object.
707
*/
708
public AbstractStringBuilder append(char[] str) {
709
int len = str.length;
710
ensureCapacityInternal(count + len);
711
appendChars(str, 0, len);
712
return this;
713
}
714
715
/**
716
* Appends the string representation of a subarray of the
717
* {@code char} array argument to this sequence.
718
* <p>
719
* Characters of the {@code char} array {@code str}, starting at
720
* index {@code offset}, are appended, in order, to the contents
721
* of this sequence. The length of this sequence increases
722
* by the value of {@code len}.
723
* <p>
724
* The overall effect is exactly as if the arguments were converted
725
* to a string by the method {@link String#valueOf(char[],int,int)},
726
* and the characters of that string were then
727
* {@link #append(String) appended} to this character sequence.
728
*
729
* @param str the characters to be appended.
730
* @param offset the index of the first {@code char} to append.
731
* @param len the number of {@code char}s to append.
732
* @return a reference to this object.
733
* @throws IndexOutOfBoundsException
734
* if {@code offset < 0} or {@code len < 0}
735
* or {@code offset+len > str.length}
736
*/
737
public AbstractStringBuilder append(char[] str, int offset, int len) {
738
int end = offset + len;
739
checkRange(offset, end, str.length);
740
ensureCapacityInternal(count + len);
741
appendChars(str, offset, end);
742
return this;
743
}
744
745
/**
746
* Appends the string representation of the {@code boolean}
747
* argument to the sequence.
748
* <p>
749
* The overall effect is exactly as if the argument were converted
750
* to a string by the method {@link String#valueOf(boolean)},
751
* and the characters of that string were then
752
* {@link #append(String) appended} to this character sequence.
753
*
754
* @param b a {@code boolean}.
755
* @return a reference to this object.
756
*/
757
public AbstractStringBuilder append(boolean b) {
758
ensureCapacityInternal(count + (b ? 4 : 5));
759
int count = this.count;
760
byte[] val = this.value;
761
if (isLatin1()) {
762
if (b) {
763
val[count++] = 't';
764
val[count++] = 'r';
765
val[count++] = 'u';
766
val[count++] = 'e';
767
} else {
768
val[count++] = 'f';
769
val[count++] = 'a';
770
val[count++] = 'l';
771
val[count++] = 's';
772
val[count++] = 'e';
773
}
774
} else {
775
if (b) {
776
count = StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e');
777
} else {
778
count = StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e');
779
}
780
}
781
this.count = count;
782
return this;
783
}
784
785
/**
786
* Appends the string representation of the {@code char}
787
* argument to this sequence.
788
* <p>
789
* The argument is appended to the contents of this sequence.
790
* The length of this sequence increases by {@code 1}.
791
* <p>
792
* The overall effect is exactly as if the argument were converted
793
* to a string by the method {@link String#valueOf(char)},
794
* and the character in that string were then
795
* {@link #append(String) appended} to this character sequence.
796
*
797
* @param c a {@code char}.
798
* @return a reference to this object.
799
*/
800
@Override
801
public AbstractStringBuilder append(char c) {
802
ensureCapacityInternal(count + 1);
803
if (isLatin1() && StringLatin1.canEncode(c)) {
804
value[count++] = (byte)c;
805
} else {
806
if (isLatin1()) {
807
inflate();
808
}
809
StringUTF16.putCharSB(value, count++, c);
810
}
811
return this;
812
}
813
814
/**
815
* Appends the string representation of the {@code int}
816
* argument to this sequence.
817
* <p>
818
* The overall effect is exactly as if the argument were converted
819
* to a string by the method {@link String#valueOf(int)},
820
* and the characters of that string were then
821
* {@link #append(String) appended} to this character sequence.
822
*
823
* @param i an {@code int}.
824
* @return a reference to this object.
825
*/
826
public AbstractStringBuilder append(int i) {
827
int count = this.count;
828
int spaceNeeded = count + Integer.stringSize(i);
829
ensureCapacityInternal(spaceNeeded);
830
if (isLatin1()) {
831
Integer.getChars(i, spaceNeeded, value);
832
} else {
833
StringUTF16.getChars(i, count, spaceNeeded, value);
834
}
835
this.count = spaceNeeded;
836
return this;
837
}
838
839
/**
840
* Appends the string representation of the {@code long}
841
* argument to this sequence.
842
* <p>
843
* The overall effect is exactly as if the argument were converted
844
* to a string by the method {@link String#valueOf(long)},
845
* and the characters of that string were then
846
* {@link #append(String) appended} to this character sequence.
847
*
848
* @param l a {@code long}.
849
* @return a reference to this object.
850
*/
851
public AbstractStringBuilder append(long l) {
852
int count = this.count;
853
int spaceNeeded = count + Long.stringSize(l);
854
ensureCapacityInternal(spaceNeeded);
855
if (isLatin1()) {
856
Long.getChars(l, spaceNeeded, value);
857
} else {
858
StringUTF16.getChars(l, count, spaceNeeded, value);
859
}
860
this.count = spaceNeeded;
861
return this;
862
}
863
864
/**
865
* Appends the string representation of the {@code float}
866
* argument to this sequence.
867
* <p>
868
* The overall effect is exactly as if the argument were converted
869
* to a string by the method {@link String#valueOf(float)},
870
* and the characters of that string were then
871
* {@link #append(String) appended} to this character sequence.
872
*
873
* @param f a {@code float}.
874
* @return a reference to this object.
875
*/
876
public AbstractStringBuilder append(float f) {
877
FloatingDecimal.appendTo(f,this);
878
return this;
879
}
880
881
/**
882
* Appends the string representation of the {@code double}
883
* argument to this sequence.
884
* <p>
885
* The overall effect is exactly as if the argument were converted
886
* to a string by the method {@link String#valueOf(double)},
887
* and the characters of that string were then
888
* {@link #append(String) appended} to this character sequence.
889
*
890
* @param d a {@code double}.
891
* @return a reference to this object.
892
*/
893
public AbstractStringBuilder append(double d) {
894
FloatingDecimal.appendTo(d,this);
895
return this;
896
}
897
898
/**
899
* Removes the characters in a substring of this sequence.
900
* The substring begins at the specified {@code start} and extends to
901
* the character at index {@code end - 1} or to the end of the
902
* sequence if no such character exists. If
903
* {@code start} is equal to {@code end}, no changes are made.
904
*
905
* @param start The beginning index, inclusive.
906
* @param end The ending index, exclusive.
907
* @return This object.
908
* @throws StringIndexOutOfBoundsException if {@code start}
909
* is negative, greater than {@code length()}, or
910
* greater than {@code end}.
911
*/
912
public AbstractStringBuilder delete(int start, int end) {
913
int count = this.count;
914
if (end > count) {
915
end = count;
916
}
917
checkRangeSIOOBE(start, end, count);
918
int len = end - start;
919
if (len > 0) {
920
shift(end, -len);
921
this.count = count - len;
922
}
923
return this;
924
}
925
926
/**
927
* Appends the string representation of the {@code codePoint}
928
* argument to this sequence.
929
*
930
* <p> The argument is appended to the contents of this sequence.
931
* The length of this sequence increases by
932
* {@link Character#charCount(int) Character.charCount(codePoint)}.
933
*
934
* <p> The overall effect is exactly as if the argument were
935
* converted to a {@code char} array by the method
936
* {@link Character#toChars(int)} and the character in that array
937
* were then {@link #append(char[]) appended} to this character
938
* sequence.
939
*
940
* @param codePoint a Unicode code point
941
* @return a reference to this object.
942
* @throws IllegalArgumentException if the specified
943
* {@code codePoint} isn't a valid Unicode code point
944
*/
945
public AbstractStringBuilder appendCodePoint(int codePoint) {
946
if (Character.isBmpCodePoint(codePoint)) {
947
return append((char)codePoint);
948
}
949
return append(Character.toChars(codePoint));
950
}
951
952
/**
953
* Removes the {@code char} at the specified position in this
954
* sequence. This sequence is shortened by one {@code char}.
955
*
956
* <p>Note: If the character at the given index is a supplementary
957
* character, this method does not remove the entire character. If
958
* correct handling of supplementary characters is required,
959
* determine the number of {@code char}s to remove by calling
960
* {@code Character.charCount(thisSequence.codePointAt(index))},
961
* where {@code thisSequence} is this sequence.
962
*
963
* @param index Index of {@code char} to remove
964
* @return This object.
965
* @throws StringIndexOutOfBoundsException if the {@code index}
966
* is negative or greater than or equal to
967
* {@code length()}.
968
*/
969
public AbstractStringBuilder deleteCharAt(int index) {
970
checkIndex(index, count);
971
shift(index + 1, -1);
972
count--;
973
return this;
974
}
975
976
/**
977
* Replaces the characters in a substring of this sequence
978
* with characters in the specified {@code String}. The substring
979
* begins at the specified {@code start} and extends to the character
980
* at index {@code end - 1} or to the end of the
981
* sequence if no such character exists. First the
982
* characters in the substring are removed and then the specified
983
* {@code String} is inserted at {@code start}. (This
984
* sequence will be lengthened to accommodate the
985
* specified String if necessary.)
986
*
987
* @param start The beginning index, inclusive.
988
* @param end The ending index, exclusive.
989
* @param str String that will replace previous contents.
990
* @return This object.
991
* @throws StringIndexOutOfBoundsException if {@code start}
992
* is negative, greater than {@code length()}, or
993
* greater than {@code end}.
994
*/
995
public AbstractStringBuilder replace(int start, int end, String str) {
996
int count = this.count;
997
if (end > count) {
998
end = count;
999
}
1000
checkRangeSIOOBE(start, end, count);
1001
int len = str.length();
1002
int newCount = count + len - (end - start);
1003
ensureCapacityInternal(newCount);
1004
shift(end, newCount - count);
1005
this.count = newCount;
1006
putStringAt(start, str);
1007
return this;
1008
}
1009
1010
/**
1011
* Returns a new {@code String} that contains a subsequence of
1012
* characters currently contained in this character sequence. The
1013
* substring begins at the specified index and extends to the end of
1014
* this sequence.
1015
*
1016
* @param start The beginning index, inclusive.
1017
* @return The new string.
1018
* @throws StringIndexOutOfBoundsException if {@code start} is
1019
* less than zero, or greater than the length of this object.
1020
*/
1021
public String substring(int start) {
1022
return substring(start, count);
1023
}
1024
1025
/**
1026
* Returns a new character sequence that is a subsequence of this sequence.
1027
*
1028
* <p> An invocation of this method of the form
1029
*
1030
* <pre>{@code
1031
* sb.subSequence(begin, end)}</pre>
1032
*
1033
* behaves in exactly the same way as the invocation
1034
*
1035
* <pre>{@code
1036
* sb.substring(begin, end)}</pre>
1037
*
1038
* This method is provided so that this class can
1039
* implement the {@link CharSequence} interface.
1040
*
1041
* @param start the start index, inclusive.
1042
* @param end the end index, exclusive.
1043
* @return the specified subsequence.
1044
*
1045
* @throws IndexOutOfBoundsException
1046
* if {@code start} or {@code end} are negative,
1047
* if {@code end} is greater than {@code length()},
1048
* or if {@code start} is greater than {@code end}
1049
*/
1050
@Override
1051
public CharSequence subSequence(int start, int end) {
1052
return substring(start, end);
1053
}
1054
1055
/**
1056
* Returns a new {@code String} that contains a subsequence of
1057
* characters currently contained in this sequence. The
1058
* substring begins at the specified {@code start} and
1059
* extends to the character at index {@code end - 1}.
1060
*
1061
* @param start The beginning index, inclusive.
1062
* @param end The ending index, exclusive.
1063
* @return The new string.
1064
* @throws StringIndexOutOfBoundsException if {@code start}
1065
* or {@code end} are negative or greater than
1066
* {@code length()}, or {@code start} is
1067
* greater than {@code end}.
1068
*/
1069
public String substring(int start, int end) {
1070
checkRangeSIOOBE(start, end, count);
1071
if (isLatin1()) {
1072
return StringLatin1.newString(value, start, end - start);
1073
}
1074
return StringUTF16.newString(value, start, end - start);
1075
}
1076
1077
private void shift(int offset, int n) {
1078
System.arraycopy(value, offset << coder,
1079
value, (offset + n) << coder, (count - offset) << coder);
1080
}
1081
1082
/**
1083
* Inserts the string representation of a subarray of the {@code str}
1084
* array argument into this sequence. The subarray begins at the
1085
* specified {@code offset} and extends {@code len} {@code char}s.
1086
* The characters of the subarray are inserted into this sequence at
1087
* the position indicated by {@code index}. The length of this
1088
* sequence increases by {@code len} {@code char}s.
1089
*
1090
* @param index position at which to insert subarray.
1091
* @param str A {@code char} array.
1092
* @param offset the index of the first {@code char} in subarray to
1093
* be inserted.
1094
* @param len the number of {@code char}s in the subarray to
1095
* be inserted.
1096
* @return This object
1097
* @throws StringIndexOutOfBoundsException if {@code index}
1098
* is negative or greater than {@code length()}, or
1099
* {@code offset} or {@code len} are negative, or
1100
* {@code (offset+len)} is greater than
1101
* {@code str.length}.
1102
*/
1103
public AbstractStringBuilder insert(int index, char[] str, int offset,
1104
int len)
1105
{
1106
checkOffset(index, count);
1107
checkRangeSIOOBE(offset, offset + len, str.length);
1108
ensureCapacityInternal(count + len);
1109
shift(index, len);
1110
count += len;
1111
putCharsAt(index, str, offset, offset + len);
1112
return this;
1113
}
1114
1115
/**
1116
* Inserts the string representation of the {@code Object}
1117
* argument into this character sequence.
1118
* <p>
1119
* The overall effect is exactly as if the second argument were
1120
* converted to a string by the method {@link String#valueOf(Object)},
1121
* and the characters of that string were then
1122
* {@link #insert(int,String) inserted} into this character
1123
* sequence at the indicated offset.
1124
* <p>
1125
* The {@code offset} argument must be greater than or equal to
1126
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1127
* of this sequence.
1128
*
1129
* @param offset the offset.
1130
* @param obj an {@code Object}.
1131
* @return a reference to this object.
1132
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1133
*/
1134
public AbstractStringBuilder insert(int offset, Object obj) {
1135
return insert(offset, String.valueOf(obj));
1136
}
1137
1138
/**
1139
* Inserts the string into this character sequence.
1140
* <p>
1141
* The characters of the {@code String} argument are inserted, in
1142
* order, into this sequence at the indicated offset, moving up any
1143
* characters originally above that position and increasing the length
1144
* of this sequence by the length of the argument. If
1145
* {@code str} is {@code null}, then the four characters
1146
* {@code "null"} are inserted into this sequence.
1147
* <p>
1148
* The character at index <i>k</i> in the new character sequence is
1149
* equal to:
1150
* <ul>
1151
* <li>the character at index <i>k</i> in the old character sequence, if
1152
* <i>k</i> is less than {@code offset}
1153
* <li>the character at index <i>k</i>{@code -offset} in the
1154
* argument {@code str}, if <i>k</i> is not less than
1155
* {@code offset} but is less than {@code offset+str.length()}
1156
* <li>the character at index <i>k</i>{@code -str.length()} in the
1157
* old character sequence, if <i>k</i> is not less than
1158
* {@code offset+str.length()}
1159
* </ul><p>
1160
* The {@code offset} argument must be greater than or equal to
1161
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1162
* of this sequence.
1163
*
1164
* @param offset the offset.
1165
* @param str a string.
1166
* @return a reference to this object.
1167
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1168
*/
1169
public AbstractStringBuilder insert(int offset, String str) {
1170
checkOffset(offset, count);
1171
if (str == null) {
1172
str = "null";
1173
}
1174
int len = str.length();
1175
ensureCapacityInternal(count + len);
1176
shift(offset, len);
1177
count += len;
1178
putStringAt(offset, str);
1179
return this;
1180
}
1181
1182
/**
1183
* Inserts the string representation of the {@code char} array
1184
* argument into this sequence.
1185
* <p>
1186
* The characters of the array argument are inserted into the
1187
* contents of this sequence at the position indicated by
1188
* {@code offset}. The length of this sequence increases by
1189
* the length of the argument.
1190
* <p>
1191
* The overall effect is exactly as if the second argument were
1192
* converted to a string by the method {@link String#valueOf(char[])},
1193
* and the characters of that string were then
1194
* {@link #insert(int,String) inserted} into this character
1195
* sequence at the indicated offset.
1196
* <p>
1197
* The {@code offset} argument must be greater than or equal to
1198
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1199
* of this sequence.
1200
*
1201
* @param offset the offset.
1202
* @param str a character array.
1203
* @return a reference to this object.
1204
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1205
*/
1206
public AbstractStringBuilder insert(int offset, char[] str) {
1207
checkOffset(offset, count);
1208
int len = str.length;
1209
ensureCapacityInternal(count + len);
1210
shift(offset, len);
1211
count += len;
1212
putCharsAt(offset, str, 0, len);
1213
return this;
1214
}
1215
1216
/**
1217
* Inserts the specified {@code CharSequence} into this sequence.
1218
* <p>
1219
* The characters of the {@code CharSequence} argument are inserted,
1220
* in order, into this sequence at the indicated offset, moving up
1221
* any characters originally above that position and increasing the length
1222
* of this sequence by the length of the argument s.
1223
* <p>
1224
* The result of this method is exactly the same as if it were an
1225
* invocation of this object's
1226
* {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
1227
* method.
1228
*
1229
* <p>If {@code s} is {@code null}, then the four characters
1230
* {@code "null"} are inserted into this sequence.
1231
*
1232
* @param dstOffset the offset.
1233
* @param s the sequence to be inserted
1234
* @return a reference to this object.
1235
* @throws IndexOutOfBoundsException if the offset is invalid.
1236
*/
1237
public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
1238
if (s == null) {
1239
s = "null";
1240
}
1241
return this.insert(dstOffset, s, 0, s.length());
1242
}
1243
1244
/**
1245
* Inserts a subsequence of the specified {@code CharSequence} into
1246
* this sequence.
1247
* <p>
1248
* The subsequence of the argument {@code s} specified by
1249
* {@code start} and {@code end} are inserted,
1250
* in order, into this sequence at the specified destination offset, moving
1251
* up any characters originally above that position. The length of this
1252
* sequence is increased by {@code end - start}.
1253
* <p>
1254
* The character at index <i>k</i> in this sequence becomes equal to:
1255
* <ul>
1256
* <li>the character at index <i>k</i> in this sequence, if
1257
* <i>k</i> is less than {@code dstOffset}
1258
* <li>the character at index <i>k</i>{@code +start-dstOffset} in
1259
* the argument {@code s}, if <i>k</i> is greater than or equal to
1260
* {@code dstOffset} but is less than {@code dstOffset+end-start}
1261
* <li>the character at index <i>k</i>{@code -(end-start)} in this
1262
* sequence, if <i>k</i> is greater than or equal to
1263
* {@code dstOffset+end-start}
1264
* </ul><p>
1265
* The {@code dstOffset} argument must be greater than or equal to
1266
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1267
* of this sequence.
1268
* <p>The start argument must be nonnegative, and not greater than
1269
* {@code end}.
1270
* <p>The end argument must be greater than or equal to
1271
* {@code start}, and less than or equal to the length of s.
1272
*
1273
* <p>If {@code s} is {@code null}, then this method inserts
1274
* characters as if the s parameter was a sequence containing the four
1275
* characters {@code "null"}.
1276
*
1277
* @param dstOffset the offset in this sequence.
1278
* @param s the sequence to be inserted.
1279
* @param start the starting index of the subsequence to be inserted.
1280
* @param end the end index of the subsequence to be inserted.
1281
* @return a reference to this object.
1282
* @throws IndexOutOfBoundsException if {@code dstOffset}
1283
* is negative or greater than {@code this.length()}, or
1284
* {@code start} or {@code end} are negative, or
1285
* {@code start} is greater than {@code end} or
1286
* {@code end} is greater than {@code s.length()}
1287
*/
1288
public AbstractStringBuilder insert(int dstOffset, CharSequence s,
1289
int start, int end)
1290
{
1291
if (s == null) {
1292
s = "null";
1293
}
1294
checkOffset(dstOffset, count);
1295
checkRange(start, end, s.length());
1296
int len = end - start;
1297
ensureCapacityInternal(count + len);
1298
shift(dstOffset, len);
1299
count += len;
1300
if (s instanceof String) {
1301
putStringAt(dstOffset, (String) s, start, end);
1302
} else {
1303
putCharsAt(dstOffset, s, start, end);
1304
}
1305
return this;
1306
}
1307
1308
/**
1309
* Inserts the string representation of the {@code boolean}
1310
* argument into this sequence.
1311
* <p>
1312
* The overall effect is exactly as if the second argument were
1313
* converted to a string by the method {@link String#valueOf(boolean)},
1314
* and the characters of that string were then
1315
* {@link #insert(int,String) inserted} into this character
1316
* sequence at the indicated offset.
1317
* <p>
1318
* The {@code offset} argument must be greater than or equal to
1319
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1320
* of this sequence.
1321
*
1322
* @param offset the offset.
1323
* @param b a {@code boolean}.
1324
* @return a reference to this object.
1325
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1326
*/
1327
public AbstractStringBuilder insert(int offset, boolean b) {
1328
return insert(offset, String.valueOf(b));
1329
}
1330
1331
/**
1332
* Inserts the string representation of the {@code char}
1333
* argument into this sequence.
1334
* <p>
1335
* The overall effect is exactly as if the second argument were
1336
* converted to a string by the method {@link String#valueOf(char)},
1337
* and the character in that string were then
1338
* {@link #insert(int,String) inserted} into this character
1339
* sequence at the indicated offset.
1340
* <p>
1341
* The {@code offset} argument must be greater than or equal to
1342
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1343
* of this sequence.
1344
*
1345
* @param offset the offset.
1346
* @param c a {@code char}.
1347
* @return a reference to this object.
1348
* @throws IndexOutOfBoundsException if the offset is invalid.
1349
*/
1350
public AbstractStringBuilder insert(int offset, char c) {
1351
checkOffset(offset, count);
1352
ensureCapacityInternal(count + 1);
1353
shift(offset, 1);
1354
count += 1;
1355
if (isLatin1() && StringLatin1.canEncode(c)) {
1356
value[offset] = (byte)c;
1357
} else {
1358
if (isLatin1()) {
1359
inflate();
1360
}
1361
StringUTF16.putCharSB(value, offset, c);
1362
}
1363
return this;
1364
}
1365
1366
/**
1367
* Inserts the string representation of the second {@code int}
1368
* argument into this sequence.
1369
* <p>
1370
* The overall effect is exactly as if the second argument were
1371
* converted to a string by the method {@link String#valueOf(int)},
1372
* and the characters of that string were then
1373
* {@link #insert(int,String) inserted} into this character
1374
* sequence at the indicated offset.
1375
* <p>
1376
* The {@code offset} argument must be greater than or equal to
1377
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1378
* of this sequence.
1379
*
1380
* @param offset the offset.
1381
* @param i an {@code int}.
1382
* @return a reference to this object.
1383
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1384
*/
1385
public AbstractStringBuilder insert(int offset, int i) {
1386
return insert(offset, String.valueOf(i));
1387
}
1388
1389
/**
1390
* Inserts the string representation of the {@code long}
1391
* argument into this sequence.
1392
* <p>
1393
* The overall effect is exactly as if the second argument were
1394
* converted to a string by the method {@link String#valueOf(long)},
1395
* and the characters of that string were then
1396
* {@link #insert(int,String) inserted} into this character
1397
* sequence at the indicated offset.
1398
* <p>
1399
* The {@code offset} argument must be greater than or equal to
1400
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1401
* of this sequence.
1402
*
1403
* @param offset the offset.
1404
* @param l a {@code long}.
1405
* @return a reference to this object.
1406
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1407
*/
1408
public AbstractStringBuilder insert(int offset, long l) {
1409
return insert(offset, String.valueOf(l));
1410
}
1411
1412
/**
1413
* Inserts the string representation of the {@code float}
1414
* argument into this sequence.
1415
* <p>
1416
* The overall effect is exactly as if the second argument were
1417
* converted to a string by the method {@link String#valueOf(float)},
1418
* and the characters of that string were then
1419
* {@link #insert(int,String) inserted} into this character
1420
* sequence at the indicated offset.
1421
* <p>
1422
* The {@code offset} argument must be greater than or equal to
1423
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1424
* of this sequence.
1425
*
1426
* @param offset the offset.
1427
* @param f a {@code float}.
1428
* @return a reference to this object.
1429
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1430
*/
1431
public AbstractStringBuilder insert(int offset, float f) {
1432
return insert(offset, String.valueOf(f));
1433
}
1434
1435
/**
1436
* Inserts the string representation of the {@code double}
1437
* argument into this sequence.
1438
* <p>
1439
* The overall effect is exactly as if the second argument were
1440
* converted to a string by the method {@link String#valueOf(double)},
1441
* and the characters of that string were then
1442
* {@link #insert(int,String) inserted} into this character
1443
* sequence at the indicated offset.
1444
* <p>
1445
* The {@code offset} argument must be greater than or equal to
1446
* {@code 0}, and less than or equal to the {@linkplain #length() length}
1447
* of this sequence.
1448
*
1449
* @param offset the offset.
1450
* @param d a {@code double}.
1451
* @return a reference to this object.
1452
* @throws StringIndexOutOfBoundsException if the offset is invalid.
1453
*/
1454
public AbstractStringBuilder insert(int offset, double d) {
1455
return insert(offset, String.valueOf(d));
1456
}
1457
1458
/**
1459
* Returns the index within this string of the first occurrence of the
1460
* specified substring.
1461
*
1462
* <p>The returned index is the smallest value {@code k} for which:
1463
* <pre>{@code
1464
* this.toString().startsWith(str, k)
1465
* }</pre>
1466
* If no such value of {@code k} exists, then {@code -1} is returned.
1467
*
1468
* @param str the substring to search for.
1469
* @return the index of the first occurrence of the specified substring,
1470
* or {@code -1} if there is no such occurrence.
1471
*/
1472
public int indexOf(String str) {
1473
return indexOf(str, 0);
1474
}
1475
1476
/**
1477
* Returns the index within this string of the first occurrence of the
1478
* specified substring, starting at the specified index.
1479
*
1480
* <p>The returned index is the smallest value {@code k} for which:
1481
* <pre>{@code
1482
* k >= Math.min(fromIndex, this.length()) &&
1483
* this.toString().startsWith(str, k)
1484
* }</pre>
1485
* If no such value of {@code k} exists, then {@code -1} is returned.
1486
*
1487
* @param str the substring to search for.
1488
* @param fromIndex the index from which to start the search.
1489
* @return the index of the first occurrence of the specified substring,
1490
* starting at the specified index,
1491
* or {@code -1} if there is no such occurrence.
1492
*/
1493
public int indexOf(String str, int fromIndex) {
1494
return String.indexOf(value, coder, count, str, fromIndex);
1495
}
1496
1497
/**
1498
* Returns the index within this string of the last occurrence of the
1499
* specified substring. The last occurrence of the empty string "" is
1500
* considered to occur at the index value {@code this.length()}.
1501
*
1502
* <p>The returned index is the largest value {@code k} for which:
1503
* <pre>{@code
1504
* this.toString().startsWith(str, k)
1505
* }</pre>
1506
* If no such value of {@code k} exists, then {@code -1} is returned.
1507
*
1508
* @param str the substring to search for.
1509
* @return the index of the last occurrence of the specified substring,
1510
* or {@code -1} if there is no such occurrence.
1511
*/
1512
public int lastIndexOf(String str) {
1513
return lastIndexOf(str, count);
1514
}
1515
1516
/**
1517
* Returns the index within this string of the last occurrence of the
1518
* specified substring, searching backward starting at the specified index.
1519
*
1520
* <p>The returned index is the largest value {@code k} for which:
1521
* <pre>{@code
1522
* k <= Math.min(fromIndex, this.length()) &&
1523
* this.toString().startsWith(str, k)
1524
* }</pre>
1525
* If no such value of {@code k} exists, then {@code -1} is returned.
1526
*
1527
* @param str the substring to search for.
1528
* @param fromIndex the index to start the search from.
1529
* @return the index of the last occurrence of the specified substring,
1530
* searching backward from the specified index,
1531
* or {@code -1} if there is no such occurrence.
1532
*/
1533
public int lastIndexOf(String str, int fromIndex) {
1534
return String.lastIndexOf(value, coder, count, str, fromIndex);
1535
}
1536
1537
/**
1538
* Causes this character sequence to be replaced by the reverse of
1539
* the sequence. If there are any surrogate pairs included in the
1540
* sequence, these are treated as single characters for the
1541
* reverse operation. Thus, the order of the high-low surrogates
1542
* is never reversed.
1543
*
1544
* Let <i>n</i> be the character length of this character sequence
1545
* (not the length in {@code char} values) just prior to
1546
* execution of the {@code reverse} method. Then the
1547
* character at index <i>k</i> in the new character sequence is
1548
* equal to the character at index <i>n-k-1</i> in the old
1549
* character sequence.
1550
*
1551
* <p>Note that the reverse operation may result in producing
1552
* surrogate pairs that were unpaired low-surrogates and
1553
* high-surrogates before the operation. For example, reversing
1554
* "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
1555
* a valid surrogate pair.
1556
*
1557
* @return a reference to this object.
1558
*/
1559
public AbstractStringBuilder reverse() {
1560
byte[] val = this.value;
1561
int count = this.count;
1562
int n = count - 1;
1563
if (isLatin1()) {
1564
for (int j = (n-1) >> 1; j >= 0; j--) {
1565
int k = n - j;
1566
byte cj = val[j];
1567
val[j] = val[k];
1568
val[k] = cj;
1569
}
1570
} else {
1571
StringUTF16.reverse(val, count);
1572
}
1573
return this;
1574
}
1575
1576
/**
1577
* Returns a string representing the data in this sequence.
1578
* A new {@code String} object is allocated and initialized to
1579
* contain the character sequence currently represented by this
1580
* object. This {@code String} is then returned. Subsequent
1581
* changes to this sequence do not affect the contents of the
1582
* {@code String}.
1583
*
1584
* @return a string representation of this sequence of characters.
1585
*/
1586
@Override
1587
public abstract String toString();
1588
1589
/**
1590
* {@inheritDoc}
1591
* @since 9
1592
*/
1593
@Override
1594
public IntStream chars() {
1595
// Reuse String-based spliterator. This requires a supplier to
1596
// capture the value and count when the terminal operation is executed
1597
return StreamSupport.intStream(
1598
() -> {
1599
// The combined set of field reads are not atomic and thread
1600
// safe but bounds checks will ensure no unsafe reads from
1601
// the byte array
1602
byte[] val = this.value;
1603
int count = this.count;
1604
byte coder = this.coder;
1605
return coder == LATIN1
1606
? new StringLatin1.CharsSpliterator(val, 0, count, 0)
1607
: new StringUTF16.CharsSpliterator(val, 0, count, 0);
1608
},
1609
Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
1610
false);
1611
}
1612
1613
/**
1614
* {@inheritDoc}
1615
* @since 9
1616
*/
1617
@Override
1618
public IntStream codePoints() {
1619
// Reuse String-based spliterator. This requires a supplier to
1620
// capture the value and count when the terminal operation is executed
1621
return StreamSupport.intStream(
1622
() -> {
1623
// The combined set of field reads are not atomic and thread
1624
// safe but bounds checks will ensure no unsafe reads from
1625
// the byte array
1626
byte[] val = this.value;
1627
int count = this.count;
1628
byte coder = this.coder;
1629
return coder == LATIN1
1630
? new StringLatin1.CharsSpliterator(val, 0, count, 0)
1631
: new StringUTF16.CodePointsSpliterator(val, 0, count, 0);
1632
},
1633
Spliterator.ORDERED,
1634
false);
1635
}
1636
1637
/**
1638
* Needed by {@code String} for the contentEquals method.
1639
*/
1640
final byte[] getValue() {
1641
return value;
1642
}
1643
1644
/*
1645
* Invoker guarantees it is in UTF16 (inflate itself for asb), if two
1646
* coders are different and the dstBegin has enough space
1647
*
1648
* @param dstBegin the char index, not offset of byte[]
1649
* @param coder the coder of dst[]
1650
*/
1651
void getBytes(byte[] dst, int dstBegin, byte coder) {
1652
if (this.coder == coder) {
1653
System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
1654
} else { // this.coder == LATIN && coder == UTF16
1655
StringLatin1.inflate(value, 0, dst, dstBegin, count);
1656
}
1657
}
1658
1659
/* for readObject() */
1660
void initBytes(char[] value, int off, int len) {
1661
if (String.COMPACT_STRINGS) {
1662
this.value = StringUTF16.compress(value, off, len);
1663
if (this.value != null) {
1664
this.coder = LATIN1;
1665
return;
1666
}
1667
}
1668
this.coder = UTF16;
1669
this.value = StringUTF16.toBytes(value, off, len);
1670
}
1671
1672
final byte getCoder() {
1673
return COMPACT_STRINGS ? coder : UTF16;
1674
}
1675
1676
final boolean isLatin1() {
1677
return COMPACT_STRINGS && coder == LATIN1;
1678
}
1679
1680
private final void putCharsAt(int index, char[] s, int off, int end) {
1681
if (isLatin1()) {
1682
byte[] val = this.value;
1683
for (int i = off, j = index; i < end; i++) {
1684
char c = s[i];
1685
if (StringLatin1.canEncode(c)) {
1686
val[j++] = (byte)c;
1687
} else {
1688
inflate();
1689
StringUTF16.putCharsSB(this.value, j, s, i, end);
1690
return;
1691
}
1692
}
1693
} else {
1694
StringUTF16.putCharsSB(this.value, index, s, off, end);
1695
}
1696
}
1697
1698
private final void putCharsAt(int index, CharSequence s, int off, int end) {
1699
if (isLatin1()) {
1700
byte[] val = this.value;
1701
for (int i = off, j = index; i < end; i++) {
1702
char c = s.charAt(i);
1703
if (StringLatin1.canEncode(c)) {
1704
val[j++] = (byte)c;
1705
} else {
1706
inflate();
1707
StringUTF16.putCharsSB(this.value, j, s, i, end);
1708
return;
1709
}
1710
}
1711
} else {
1712
StringUTF16.putCharsSB(this.value, index, s, off, end);
1713
}
1714
}
1715
1716
private void putStringAt(int index, String str, int off, int end) {
1717
if (getCoder() != str.coder()) {
1718
inflate();
1719
}
1720
str.getBytes(value, off, index, coder, end - off);
1721
}
1722
1723
private void putStringAt(int index, String str) {
1724
putStringAt(index, str, 0, str.length());
1725
}
1726
1727
private final void appendChars(char[] s, int off, int end) {
1728
int count = this.count;
1729
if (isLatin1()) {
1730
byte[] val = this.value;
1731
for (int i = off, j = count; i < end; i++) {
1732
char c = s[i];
1733
if (StringLatin1.canEncode(c)) {
1734
val[j++] = (byte)c;
1735
} else {
1736
this.count = count = j;
1737
inflate();
1738
StringUTF16.putCharsSB(this.value, j, s, i, end);
1739
this.count = count + end - i;
1740
return;
1741
}
1742
}
1743
} else {
1744
StringUTF16.putCharsSB(this.value, count, s, off, end);
1745
}
1746
this.count = count + end - off;
1747
}
1748
1749
private final void appendChars(String s, int off, int end) {
1750
if (isLatin1()) {
1751
if (s.isLatin1()) {
1752
System.arraycopy(s.value(), off, this.value, this.count, end - off);
1753
} else {
1754
// We might need to inflate, but do it as late as possible since
1755
// the range of characters we're copying might all be latin1
1756
byte[] val = this.value;
1757
for (int i = off, j = count; i < end; i++) {
1758
char c = s.charAt(i);
1759
if (StringLatin1.canEncode(c)) {
1760
val[j++] = (byte) c;
1761
} else {
1762
count = j;
1763
inflate();
1764
System.arraycopy(s.value(), i << UTF16, this.value, j << UTF16, (end - i) << UTF16);
1765
count += end - i;
1766
return;
1767
}
1768
}
1769
}
1770
} else if (s.isLatin1()) {
1771
StringUTF16.putCharsSB(this.value, this.count, s, off, end);
1772
} else { // both UTF16
1773
System.arraycopy(s.value(), off << UTF16, this.value, this.count << UTF16, (end - off) << UTF16);
1774
}
1775
count += end - off;
1776
}
1777
1778
private final void appendChars(CharSequence s, int off, int end) {
1779
if (isLatin1()) {
1780
byte[] val = this.value;
1781
for (int i = off, j = count; i < end; i++) {
1782
char c = s.charAt(i);
1783
if (StringLatin1.canEncode(c)) {
1784
val[j++] = (byte)c;
1785
} else {
1786
count = j;
1787
inflate();
1788
StringUTF16.putCharsSB(this.value, j, s, i, end);
1789
count += end - i;
1790
return;
1791
}
1792
}
1793
} else {
1794
StringUTF16.putCharsSB(this.value, count, s, off, end);
1795
}
1796
count += end - off;
1797
}
1798
1799
/* IndexOutOfBoundsException, if out of bounds */
1800
private static void checkRange(int start, int end, int len) {
1801
if (start < 0 || start > end || end > len) {
1802
throw new IndexOutOfBoundsException(
1803
"start " + start + ", end " + end + ", length " + len);
1804
}
1805
}
1806
1807
/* StringIndexOutOfBoundsException, if out of bounds */
1808
private static void checkRangeSIOOBE(int start, int end, int len) {
1809
if (start < 0 || start > end || end > len) {
1810
throw new StringIndexOutOfBoundsException(
1811
"start " + start + ", end " + end + ", length " + len);
1812
}
1813
}
1814
}
1815
1816