1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.text;
18
19 import java.io.IOException;
20 import java.io.Reader;
21 import java.io.Serializable;
22 import java.io.Writer;
23 import java.nio.CharBuffer;
24 import java.util.Arrays;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Objects;
28
29 import org.apache.commons.lang3.ArrayUtils;
30 import org.apache.commons.lang3.StringUtils;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 @Deprecated
74 public class StrBuilder implements CharSequence, Appendable, Serializable, Builder<String> {
75
76
77
78
79 final class StrBuilderReader extends Reader {
80
81
82 private int pos;
83
84
85 private int mark;
86
87
88
89
90 StrBuilderReader() {
91 }
92
93
94 @Override
95 public void close() {
96
97 }
98
99
100 @Override
101 public void mark(final int readAheadLimit) {
102 mark = pos;
103 }
104
105
106 @Override
107 public boolean markSupported() {
108 return true;
109 }
110
111
112 @Override
113 public int read() {
114 if (!ready()) {
115 return -1;
116 }
117 return StrBuilder.this.charAt(pos++);
118 }
119
120
121 @Override
122 public int read(final char[] b, final int off, int len) {
123 if (off < 0 || len < 0 || off > b.length
124 || off + len > b.length || off + len < 0) {
125 throw new IndexOutOfBoundsException();
126 }
127 if (len == 0) {
128 return 0;
129 }
130 if (pos >= StrBuilder.this.size()) {
131 return -1;
132 }
133 if (pos + len > size()) {
134 len = StrBuilder.this.size() - pos;
135 }
136 StrBuilder.this.getChars(pos, pos + len, b, off);
137 pos += len;
138 return len;
139 }
140
141
142 @Override
143 public boolean ready() {
144 return pos < StrBuilder.this.size();
145 }
146
147
148 @Override
149 public void reset() {
150 pos = mark;
151 }
152
153
154 @Override
155 public long skip(long n) {
156 if (pos + n > StrBuilder.this.size()) {
157 n = StrBuilder.this.size() - pos;
158 }
159 if (n < 0) {
160 return 0;
161 }
162 pos = Math.addExact(pos, Math.toIntExact(n));
163 return n;
164 }
165 }
166
167
168
169
170 final class StrBuilderTokenizer extends StrTokenizer {
171
172
173
174
175 StrBuilderTokenizer() {
176 }
177
178
179 @Override
180 public String getContent() {
181 final String str = super.getContent();
182 if (str == null) {
183 return StrBuilder.this.toString();
184 }
185 return str;
186 }
187
188
189 @Override
190 protected List<String> tokenize(final char[] chars, final int offset, final int count) {
191 if (chars == null) {
192 return super.tokenize(
193 StrBuilder.this.buffer, 0, StrBuilder.this.size());
194 }
195 return super.tokenize(chars, offset, count);
196 }
197 }
198
199
200
201
202 final class StrBuilderWriter extends Writer {
203
204
205
206
207 StrBuilderWriter() {
208 }
209
210
211 @Override
212 public void close() {
213
214 }
215
216
217 @Override
218 public void flush() {
219
220 }
221
222
223 @Override
224 public void write(final char[] cbuf) {
225 StrBuilder.this.append(cbuf);
226 }
227
228
229 @Override
230 public void write(final char[] cbuf, final int off, final int len) {
231 StrBuilder.this.append(cbuf, off, len);
232 }
233
234
235 @Override
236 public void write(final int c) {
237 StrBuilder.this.append((char) c);
238 }
239
240
241 @Override
242 public void write(final String str) {
243 StrBuilder.this.append(str);
244 }
245
246
247 @Override
248 public void write(final String str, final int off, final int len) {
249 StrBuilder.this.append(str, off, len);
250 }
251 }
252
253
254
255
256 static final int CAPACITY = 32;
257
258
259
260
261
262
263 private static final long serialVersionUID = 7628716375283629643L;
264
265
266 char[] buffer;
267
268
269 private int size;
270
271
272 private String newLine;
273
274
275 private String nullText;
276
277
278
279
280 public StrBuilder() {
281 this(CAPACITY);
282 }
283
284
285
286
287
288
289 public StrBuilder(int initialCapacity) {
290 if (initialCapacity <= 0) {
291 initialCapacity = CAPACITY;
292 }
293 buffer = new char[initialCapacity];
294 }
295
296
297
298
299
300
301
302 public StrBuilder(final String str) {
303 if (str == null) {
304 buffer = new char[CAPACITY];
305 } else {
306 buffer = new char[str.length() + CAPACITY];
307 append(str);
308 }
309 }
310
311
312
313
314
315
316
317 public StrBuilder append(final boolean value) {
318 if (value) {
319 ensureCapacity(size + 4);
320 buffer[size++] = 't';
321 buffer[size++] = 'r';
322 buffer[size++] = 'u';
323 buffer[size++] = 'e';
324 } else {
325 ensureCapacity(size + 5);
326 buffer[size++] = 'f';
327 buffer[size++] = 'a';
328 buffer[size++] = 'l';
329 buffer[size++] = 's';
330 buffer[size++] = 'e';
331 }
332 return this;
333 }
334
335
336
337
338
339
340
341 @Override
342 public StrBuilder append(final char ch) {
343 final int len = length();
344 ensureCapacity(len + 1);
345 buffer[size++] = ch;
346 return this;
347 }
348
349
350
351
352
353
354
355
356 public StrBuilder append(final char[] chars) {
357 if (chars == null) {
358 return appendNull();
359 }
360 final int strLen = chars.length;
361 if (strLen > 0) {
362 final int len = length();
363 ensureCapacity(len + strLen);
364 System.arraycopy(chars, 0, buffer, len, strLen);
365 size += strLen;
366 }
367 return this;
368 }
369
370
371
372
373
374
375
376
377
378
379 public StrBuilder append(final char[] chars, final int startIndex, final int length) {
380 if (chars == null) {
381 return appendNull();
382 }
383 if (startIndex < 0 || startIndex > chars.length) {
384 throw new StringIndexOutOfBoundsException("Invalid startIndex: " + length);
385 }
386 if (length < 0 || startIndex + length > chars.length) {
387 throw new StringIndexOutOfBoundsException("Invalid length: " + length);
388 }
389 if (length > 0) {
390 final int len = length();
391 ensureCapacity(len + length);
392 System.arraycopy(chars, startIndex, buffer, len, length);
393 size += length;
394 }
395 return this;
396 }
397
398
399
400
401
402
403
404
405 public StrBuilder append(final CharBuffer buf) {
406 if (buf == null) {
407 return appendNull();
408 }
409 if (buf.hasArray()) {
410 final int length = buf.remaining();
411 final int len = length();
412 ensureCapacity(len + length);
413 System.arraycopy(buf.array(), buf.arrayOffset() + buf.position(), buffer, len, length);
414 size += length;
415 } else {
416 append(buf.toString());
417 }
418 return this;
419 }
420
421
422
423
424
425
426
427
428
429
430 public StrBuilder append(final CharBuffer buf, final int startIndex, final int length) {
431 if (buf == null) {
432 return appendNull();
433 }
434 if (buf.hasArray()) {
435 final int totalLength = buf.remaining();
436 if (startIndex < 0 || startIndex > totalLength) {
437 throw new StringIndexOutOfBoundsException("startIndex must be valid");
438 }
439 if (length < 0 || startIndex + length > totalLength) {
440 throw new StringIndexOutOfBoundsException("length must be valid");
441 }
442 final int len = length();
443 ensureCapacity(len + length);
444 System.arraycopy(buf.array(), buf.arrayOffset() + buf.position() + startIndex, buffer, len, length);
445 size += length;
446 } else {
447 append(buf.toString(), startIndex, length);
448 }
449 return this;
450 }
451
452
453
454
455
456
457
458
459 @Override
460 public StrBuilder append(final CharSequence seq) {
461 if (seq == null) {
462 return appendNull();
463 }
464 if (seq instanceof StrBuilder) {
465 return append((StrBuilder) seq);
466 }
467 if (seq instanceof StringBuilder) {
468 return append((StringBuilder) seq);
469 }
470 if (seq instanceof StringBuffer) {
471 return append((StringBuffer) seq);
472 }
473 if (seq instanceof CharBuffer) {
474 return append((CharBuffer) seq);
475 }
476 return append(seq.toString());
477 }
478
479
480
481
482
483
484
485
486
487
488 @Override
489 public StrBuilder append(final CharSequence seq, final int startIndex, final int length) {
490 if (seq == null) {
491 return appendNull();
492 }
493 return append(seq.toString(), startIndex, length);
494 }
495
496
497
498
499
500
501
502 public StrBuilder append(final double value) {
503 return append(String.valueOf(value));
504 }
505
506
507
508
509
510
511
512 public StrBuilder append(final float value) {
513 return append(String.valueOf(value));
514 }
515
516
517
518
519
520
521
522 public StrBuilder append(final int value) {
523 return append(String.valueOf(value));
524 }
525
526
527
528
529
530
531
532 public StrBuilder append(final long value) {
533 return append(String.valueOf(value));
534 }
535
536
537
538
539
540
541
542
543 public StrBuilder append(final Object obj) {
544 if (obj == null) {
545 return appendNull();
546 }
547 if (obj instanceof CharSequence) {
548 return append((CharSequence) obj);
549 }
550 return append(obj.toString());
551 }
552
553
554
555
556
557
558
559
560 public StrBuilder append(final StrBuilder str) {
561 if (str == null) {
562 return appendNull();
563 }
564 final int strLen = str.length();
565 if (strLen > 0) {
566 final int len = length();
567 ensureCapacity(len + strLen);
568 System.arraycopy(str.buffer, 0, buffer, len, strLen);
569 size += strLen;
570 }
571 return this;
572 }
573
574
575
576
577
578
579
580
581
582
583 public StrBuilder append(final StrBuilder str, final int startIndex, final int length) {
584 if (str == null) {
585 return appendNull();
586 }
587 if (startIndex < 0 || startIndex > str.length()) {
588 throw new StringIndexOutOfBoundsException("startIndex must be valid");
589 }
590 if (length < 0 || startIndex + length > str.length()) {
591 throw new StringIndexOutOfBoundsException("length must be valid");
592 }
593 if (length > 0) {
594 final int len = length();
595 ensureCapacity(len + length);
596 str.getChars(startIndex, startIndex + length, buffer, len);
597 size += length;
598 }
599 return this;
600 }
601
602
603
604
605
606
607
608
609 public StrBuilder append(final String str) {
610 if (str == null) {
611 return appendNull();
612 }
613 final int strLen = str.length();
614 if (strLen > 0) {
615 final int len = length();
616 ensureCapacity(len + strLen);
617 str.getChars(0, strLen, buffer, len);
618 size += strLen;
619 }
620 return this;
621 }
622
623
624
625
626
627
628
629
630
631
632 public StrBuilder append(final String str, final int startIndex, final int length) {
633 if (str == null) {
634 return appendNull();
635 }
636 if (startIndex < 0 || startIndex > str.length()) {
637 throw new StringIndexOutOfBoundsException("startIndex must be valid");
638 }
639 if (length < 0 || startIndex + length > str.length()) {
640 throw new StringIndexOutOfBoundsException("length must be valid");
641 }
642 if (length > 0) {
643 final int len = length();
644 ensureCapacity(len + length);
645 str.getChars(startIndex, startIndex + length, buffer, len);
646 size += length;
647 }
648 return this;
649 }
650
651
652
653
654
655
656
657
658
659 public StrBuilder append(final String format, final Object... objs) {
660 return append(String.format(format, objs));
661 }
662
663
664
665
666
667
668
669
670 public StrBuilder append(final StringBuffer str) {
671 if (str == null) {
672 return appendNull();
673 }
674 final int strLen = str.length();
675 if (strLen > 0) {
676 final int len = length();
677 ensureCapacity(len + strLen);
678 str.getChars(0, strLen, buffer, len);
679 size += strLen;
680 }
681 return this;
682 }
683
684
685
686
687
688
689
690
691
692
693 public StrBuilder append(final StringBuffer str, final int startIndex, final int length) {
694 if (str == null) {
695 return appendNull();
696 }
697 if (startIndex < 0 || startIndex > str.length()) {
698 throw new StringIndexOutOfBoundsException("startIndex must be valid");
699 }
700 if (length < 0 || startIndex + length > str.length()) {
701 throw new StringIndexOutOfBoundsException("length must be valid");
702 }
703 if (length > 0) {
704 final int len = length();
705 ensureCapacity(len + length);
706 str.getChars(startIndex, startIndex + length, buffer, len);
707 size += length;
708 }
709 return this;
710 }
711
712
713
714
715
716
717
718
719 public StrBuilder append(final StringBuilder str) {
720 if (str == null) {
721 return appendNull();
722 }
723 final int strLen = str.length();
724 if (strLen > 0) {
725 final int len = length();
726 ensureCapacity(len + strLen);
727 str.getChars(0, strLen, buffer, len);
728 size += strLen;
729 }
730 return this;
731 }
732
733
734
735
736
737
738
739
740
741
742 public StrBuilder append(final StringBuilder str, final int startIndex, final int length) {
743 if (str == null) {
744 return appendNull();
745 }
746 if (startIndex < 0 || startIndex > str.length()) {
747 throw new StringIndexOutOfBoundsException("startIndex must be valid");
748 }
749 if (length < 0 || startIndex + length > str.length()) {
750 throw new StringIndexOutOfBoundsException("length must be valid");
751 }
752 if (length > 0) {
753 final int len = length();
754 ensureCapacity(len + length);
755 str.getChars(startIndex, startIndex + length, buffer, len);
756 size += length;
757 }
758 return this;
759 }
760
761
762
763
764
765
766
767
768
769 public StrBuilder appendAll(final Iterable<?> iterable) {
770 if (iterable != null) {
771 iterable.forEach(this::append);
772 }
773 return this;
774 }
775
776
777
778
779
780
781
782
783
784 public StrBuilder appendAll(final Iterator<?> it) {
785 if (it != null) {
786 while (it.hasNext()) {
787 append(it.next());
788 }
789 }
790 return this;
791 }
792
793
794
795
796
797
798
799
800
801
802 public <T> StrBuilder appendAll(@SuppressWarnings("unchecked") final T... array) {
803
804
805
806
807
808
809 if (array != null && array.length > 0) {
810 for (final Object element : array) {
811 append(element);
812 }
813 }
814 return this;
815 }
816
817
818
819
820
821
822
823
824
825
826
827 public StrBuilder appendFixedWidthPadLeft(final int value, final int width, final char padChar) {
828 return appendFixedWidthPadLeft(String.valueOf(value), width, padChar);
829 }
830
831
832
833
834
835
836
837
838
839
840
841
842 public StrBuilder appendFixedWidthPadLeft(final Object obj, final int width, final char padChar) {
843 if (width > 0) {
844 ensureCapacity(size + width);
845 String str = obj == null ? getNullText() : obj.toString();
846 if (str == null) {
847 str = StringUtils.EMPTY;
848 }
849 final int strLen = str.length();
850 if (strLen >= width) {
851 str.getChars(strLen - width, strLen, buffer, size);
852 } else {
853 final int padLen = width - strLen;
854 for (int i = 0; i < padLen; i++) {
855 buffer[size + i] = padChar;
856 }
857 str.getChars(0, strLen, buffer, size + padLen);
858 }
859 size += width;
860 }
861 return this;
862 }
863
864
865
866
867
868
869
870
871
872
873
874 public StrBuilder appendFixedWidthPadRight(final int value, final int width, final char padChar) {
875 return appendFixedWidthPadRight(String.valueOf(value), width, padChar);
876 }
877
878
879
880
881
882
883
884
885
886
887
888
889 public StrBuilder appendFixedWidthPadRight(final Object obj, final int width, final char padChar) {
890 if (width > 0) {
891 ensureCapacity(size + width);
892 String str = obj == null ? getNullText() : obj.toString();
893 if (str == null) {
894 str = StringUtils.EMPTY;
895 }
896 final int strLen = str.length();
897 if (strLen >= width) {
898 str.getChars(0, width, buffer, size);
899 } else {
900 final int padLen = width - strLen;
901 str.getChars(0, strLen, buffer, size);
902 for (int i = 0; i < padLen; i++) {
903 buffer[size + strLen + i] = padChar;
904 }
905 }
906 size += width;
907 }
908 return this;
909 }
910
911
912
913
914
915
916
917 public StrBuilder appendln(final boolean value) {
918 return append(value).appendNewLine();
919 }
920
921
922
923
924
925
926
927 public StrBuilder appendln(final char ch) {
928 return append(ch).appendNewLine();
929 }
930
931
932
933
934
935
936
937
938 public StrBuilder appendln(final char[] chars) {
939 return append(chars).appendNewLine();
940 }
941
942
943
944
945
946
947
948
949
950
951 public StrBuilder appendln(final char[] chars, final int startIndex, final int length) {
952 return append(chars, startIndex, length).appendNewLine();
953 }
954
955
956
957
958
959
960
961 public StrBuilder appendln(final double value) {
962 return append(value).appendNewLine();
963 }
964
965
966
967
968
969
970
971 public StrBuilder appendln(final float value) {
972 return append(value).appendNewLine();
973 }
974
975
976
977
978
979
980
981 public StrBuilder appendln(final int value) {
982 return append(value).appendNewLine();
983 }
984
985
986
987
988
989
990
991 public StrBuilder appendln(final long value) {
992 return append(value).appendNewLine();
993 }
994
995
996
997
998
999
1000
1001
1002 public StrBuilder appendln(final Object obj) {
1003 return append(obj).appendNewLine();
1004 }
1005
1006
1007
1008
1009
1010
1011
1012
1013 public StrBuilder appendln(final StrBuilder str) {
1014 return append(str).appendNewLine();
1015 }
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026 public StrBuilder appendln(final StrBuilder str, final int startIndex, final int length) {
1027 return append(str, startIndex, length).appendNewLine();
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 public StrBuilder appendln(final String str) {
1038 return append(str).appendNewLine();
1039 }
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050 public StrBuilder appendln(final String str, final int startIndex, final int length) {
1051 return append(str, startIndex, length).appendNewLine();
1052 }
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062 public StrBuilder appendln(final String format, final Object... objs) {
1063 return append(format, objs).appendNewLine();
1064 }
1065
1066
1067
1068
1069
1070
1071
1072
1073 public StrBuilder appendln(final StringBuffer str) {
1074 return append(str).appendNewLine();
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 public StrBuilder appendln(final StringBuffer str, final int startIndex, final int length) {
1087 return append(str, startIndex, length).appendNewLine();
1088 }
1089
1090
1091
1092
1093
1094
1095
1096
1097 public StrBuilder appendln(final StringBuilder str) {
1098 return append(str).appendNewLine();
1099 }
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110 public StrBuilder appendln(final StringBuilder str, final int startIndex, final int length) {
1111 return append(str, startIndex, length).appendNewLine();
1112 }
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123 public StrBuilder appendNewLine() {
1124 if (newLine == null) {
1125 append(System.lineSeparator());
1126 return this;
1127 }
1128 return append(newLine);
1129 }
1130
1131
1132
1133
1134
1135
1136 public StrBuilder appendNull() {
1137 if (nullText == null) {
1138 return this;
1139 }
1140 return append(nullText);
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150 public StrBuilder appendPadding(final int length, final char padChar) {
1151 if (length >= 0) {
1152 ensureCapacity(size + length);
1153 for (int i = 0; i < length; i++) {
1154 buffer[size++] = padChar;
1155 }
1156 }
1157 return this;
1158 }
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181 public StrBuilder appendSeparator(final char separator) {
1182 if (isNotEmpty()) {
1183 append(separator);
1184 }
1185 return this;
1186 }
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 public StrBuilder appendSeparator(final char standard, final char defaultIfEmpty) {
1199 if (isNotEmpty()) {
1200 append(standard);
1201 } else {
1202 append(defaultIfEmpty);
1203 }
1204 return this;
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229 public StrBuilder appendSeparator(final char separator, final int loopIndex) {
1230 if (loopIndex > 0) {
1231 append(separator);
1232 }
1233 return this;
1234 }
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258 public StrBuilder appendSeparator(final String separator) {
1259 return appendSeparator(separator, null);
1260 }
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285 public StrBuilder appendSeparator(final String separator, final int loopIndex) {
1286 if (separator != null && loopIndex > 0) {
1287 append(separator);
1288 }
1289 return this;
1290 }
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320 public StrBuilder appendSeparator(final String standard, final String defaultIfEmpty) {
1321 final String str = isEmpty() ? defaultIfEmpty : standard;
1322 if (str != null) {
1323 append(str);
1324 }
1325 return this;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340 public void appendTo(final Appendable appendable) throws IOException {
1341 if (appendable instanceof Writer) {
1342 ((Writer) appendable).write(buffer, 0, size);
1343 } else if (appendable instanceof StringBuilder) {
1344 ((StringBuilder) appendable).append(buffer, 0, size);
1345 } else if (appendable instanceof StringBuffer) {
1346 ((StringBuffer) appendable).append(buffer, 0, size);
1347 } else if (appendable instanceof CharBuffer) {
1348 ((CharBuffer) appendable).put(buffer, 0, size);
1349 } else {
1350 appendable.append(this);
1351 }
1352 }
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364 public StrBuilder appendWithSeparators(final Iterable<?> iterable, final String separator) {
1365 if (iterable != null) {
1366 appendWithSeparators(iterable.iterator(), separator);
1367 }
1368 return this;
1369 }
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381 public StrBuilder appendWithSeparators(final Iterator<?> iterator, final String separator) {
1382 if (iterator != null) {
1383 final String sep = Objects.toString(separator, StringUtils.EMPTY);
1384 while (iterator.hasNext()) {
1385 append(iterator.next());
1386 if (iterator.hasNext()) {
1387 append(sep);
1388 }
1389 }
1390 }
1391 return this;
1392 }
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404 public StrBuilder appendWithSeparators(final Object[] array, final String separator) {
1405 if (array != null && array.length > 0) {
1406 final String sep = Objects.toString(separator, StringUtils.EMPTY);
1407 append(array[0]);
1408 for (int i = 1; i < array.length; i++) {
1409 append(sep);
1410 append(array[i]);
1411 }
1412 }
1413 return this;
1414 }
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439 public Reader asReader() {
1440 return new StrBuilderReader();
1441 }
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480 public StrTokenizer asTokenizer() {
1481 return new StrBuilderTokenizer();
1482 }
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508 public Writer asWriter() {
1509 return new StrBuilderWriter();
1510 }
1511
1512
1513
1514
1515
1516
1517
1518
1519 @Deprecated
1520 @Override
1521 public String build() {
1522 return toString();
1523 }
1524
1525
1526
1527
1528
1529
1530 public int capacity() {
1531 return buffer.length;
1532 }
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543 @Override
1544 public char charAt(final int index) {
1545 if (index < 0 || index >= length()) {
1546 throw new StringIndexOutOfBoundsException(index);
1547 }
1548 return buffer[index];
1549 }
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564 public StrBuilder clear() {
1565 size = 0;
1566 return this;
1567 }
1568
1569
1570
1571
1572
1573
1574
1575 public boolean contains(final char ch) {
1576 final char[] thisBuf = buffer;
1577 for (int i = 0; i < this.size; i++) {
1578 if (thisBuf[i] == ch) {
1579 return true;
1580 }
1581 }
1582 return false;
1583 }
1584
1585
1586
1587
1588
1589
1590
1591 public boolean contains(final String str) {
1592 return indexOf(str, 0) >= 0;
1593 }
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607 public boolean contains(final StrMatcher matcher) {
1608 return indexOf(matcher, 0) >= 0;
1609 }
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620 public StrBuilder delete(final int startIndex, int endIndex) {
1621 endIndex = validateRange(startIndex, endIndex);
1622 final int len = endIndex - startIndex;
1623 if (len > 0) {
1624 deleteImpl(startIndex, endIndex, len);
1625 }
1626 return this;
1627 }
1628
1629
1630
1631
1632
1633
1634
1635 public StrBuilder deleteAll(final char ch) {
1636 for (int i = 0; i < size; i++) {
1637 if (buffer[i] == ch) {
1638 final int start = i;
1639 while (++i < size) {
1640 if (buffer[i] != ch) {
1641 break;
1642 }
1643 }
1644 final int len = i - start;
1645 deleteImpl(start, i, len);
1646 i -= len;
1647 }
1648 }
1649 return this;
1650 }
1651
1652
1653
1654
1655
1656
1657
1658 public StrBuilder deleteAll(final String str) {
1659 final int len = str == null ? 0 : str.length();
1660 if (len > 0) {
1661 int index = indexOf(str, 0);
1662 while (index >= 0) {
1663 deleteImpl(index, index + len, len);
1664 index = indexOf(str, index);
1665 }
1666 }
1667 return this;
1668 }
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681 public StrBuilder deleteAll(final StrMatcher matcher) {
1682 return replace(matcher, null, 0, size, -1);
1683 }
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694 public StrBuilder deleteCharAt(final int index) {
1695 if (index < 0 || index >= size) {
1696 throw new StringIndexOutOfBoundsException(index);
1697 }
1698 deleteImpl(index, index + 1, 1);
1699 return this;
1700 }
1701
1702
1703
1704
1705
1706
1707
1708 public StrBuilder deleteFirst(final char ch) {
1709 for (int i = 0; i < size; i++) {
1710 if (buffer[i] == ch) {
1711 deleteImpl(i, i + 1, 1);
1712 break;
1713 }
1714 }
1715 return this;
1716 }
1717
1718
1719
1720
1721
1722
1723
1724 public StrBuilder deleteFirst(final String str) {
1725 final int len = str == null ? 0 : str.length();
1726 if (len > 0) {
1727 final int index = indexOf(str, 0);
1728 if (index >= 0) {
1729 deleteImpl(index, index + len, len);
1730 }
1731 }
1732 return this;
1733 }
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746 public StrBuilder deleteFirst(final StrMatcher matcher) {
1747 return replace(matcher, null, 0, size, 1);
1748 }
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758 private void deleteImpl(final int startIndex, final int endIndex, final int len) {
1759 System.arraycopy(buffer, endIndex, buffer, startIndex, size - endIndex);
1760 size -= len;
1761 }
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772 public boolean endsWith(final String str) {
1773 if (str == null) {
1774 return false;
1775 }
1776 final int len = str.length();
1777 if (len == 0) {
1778 return true;
1779 }
1780 if (len > size) {
1781 return false;
1782 }
1783 int pos = size - len;
1784 for (int i = 0; i < len; i++, pos++) {
1785 if (buffer[pos] != str.charAt(i)) {
1786 return false;
1787 }
1788 }
1789 return true;
1790 }
1791
1792
1793
1794
1795
1796
1797
1798 public StrBuilder ensureCapacity(final int capacity) {
1799 if (capacity > buffer.length) {
1800 final char[] old = buffer;
1801 buffer = new char[capacity * 2];
1802 System.arraycopy(old, 0, buffer, 0, size);
1803 }
1804 return this;
1805 }
1806
1807
1808
1809
1810
1811
1812
1813
1814 @Override
1815 public boolean equals(final Object obj) {
1816 return obj instanceof StrBuilder
1817 && equals((StrBuilder) obj);
1818 }
1819
1820
1821
1822
1823
1824
1825
1826
1827 public boolean equals(final StrBuilder other) {
1828 if (this == other) {
1829 return true;
1830 }
1831 if (other == null) {
1832 return false;
1833 }
1834 if (this.size != other.size) {
1835 return false;
1836 }
1837 final char[] thisBuf = this.buffer;
1838 final char[] otherBuf = other.buffer;
1839 for (int i = size - 1; i >= 0; i--) {
1840 if (thisBuf[i] != otherBuf[i]) {
1841 return false;
1842 }
1843 }
1844 return true;
1845 }
1846
1847
1848
1849
1850
1851
1852
1853
1854 public boolean equalsIgnoreCase(final StrBuilder other) {
1855 if (this == other) {
1856 return true;
1857 }
1858 if (this.size != other.size) {
1859 return false;
1860 }
1861 final char[] thisBuf = this.buffer;
1862 final char[] otherBuf = other.buffer;
1863 for (int i = size - 1; i >= 0; i--) {
1864 final char c1 = thisBuf[i];
1865 final char c2 = otherBuf[i];
1866 if (c1 != c2 && Character.toUpperCase(c1) != Character.toUpperCase(c2)) {
1867 return false;
1868 }
1869 }
1870 return true;
1871 }
1872
1873
1874
1875
1876
1877
1878
1879
1880 @Override
1881 public String get() {
1882 return toString();
1883 }
1884
1885
1886
1887
1888
1889
1890
1891 public char[] getChars(char[] destination) {
1892 final int len = length();
1893 if (destination == null || destination.length < len) {
1894 destination = new char[len];
1895 }
1896 System.arraycopy(buffer, 0, destination, 0, len);
1897 return destination;
1898 }
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910 public void getChars(final int startIndex,
1911 final int endIndex,
1912 final char[] destination,
1913 final int destinationIndex) {
1914 if (startIndex < 0) {
1915 throw new StringIndexOutOfBoundsException(startIndex);
1916 }
1917 if (endIndex < 0 || endIndex > length()) {
1918 throw new StringIndexOutOfBoundsException(endIndex);
1919 }
1920 if (startIndex > endIndex) {
1921 throw new StringIndexOutOfBoundsException("end < start");
1922 }
1923 System.arraycopy(buffer, startIndex, destination, destinationIndex, endIndex - startIndex);
1924 }
1925
1926
1927
1928
1929
1930
1931 public String getNewLineText() {
1932 return newLine;
1933 }
1934
1935
1936
1937
1938
1939
1940 public String getNullText() {
1941 return nullText;
1942 }
1943
1944
1945
1946
1947
1948
1949 @Override
1950 public int hashCode() {
1951 final char[] buf = buffer;
1952 int hash = 0;
1953 for (int i = size - 1; i >= 0; i--) {
1954 hash = 31 * hash + buf[i];
1955 }
1956 return hash;
1957 }
1958
1959
1960
1961
1962
1963
1964
1965 public int indexOf(final char ch) {
1966 return indexOf(ch, 0);
1967 }
1968
1969
1970
1971
1972
1973
1974
1975
1976 public int indexOf(final char ch, int startIndex) {
1977 startIndex = Math.max(startIndex, 0);
1978 if (startIndex >= size) {
1979 return -1;
1980 }
1981 final char[] thisBuf = buffer;
1982 for (int i = startIndex; i < size; i++) {
1983 if (thisBuf[i] == ch) {
1984 return i;
1985 }
1986 }
1987 return -1;
1988 }
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999 public int indexOf(final String str) {
2000 return indexOf(str, 0);
2001 }
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014 public int indexOf(final String str, int startIndex) {
2015 startIndex = Math.max(startIndex, 0);
2016 if (str == null || startIndex >= size) {
2017 return -1;
2018 }
2019 final int strLen = str.length();
2020 if (strLen == 1) {
2021 return indexOf(str.charAt(0), startIndex);
2022 }
2023 if (strLen == 0) {
2024 return startIndex;
2025 }
2026 if (strLen > size) {
2027 return -1;
2028 }
2029 final char[] thisBuf = buffer;
2030 final int len = size - strLen + 1;
2031 outer:
2032 for (int i = startIndex; i < len; i++) {
2033 for (int j = 0; j < strLen; j++) {
2034 if (str.charAt(j) != thisBuf[i + j]) {
2035 continue outer;
2036 }
2037 }
2038 return i;
2039 }
2040 return -1;
2041 }
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054 public int indexOf(final StrMatcher matcher) {
2055 return indexOf(matcher, 0);
2056 }
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071 public int indexOf(final StrMatcher matcher, int startIndex) {
2072 startIndex = Math.max(startIndex, 0);
2073 if (matcher == null || startIndex >= size) {
2074 return -1;
2075 }
2076 final int len = size;
2077 final char[] buf = buffer;
2078 for (int i = startIndex; i < len; i++) {
2079 if (matcher.isMatch(buf, i, startIndex, len) > 0) {
2080 return i;
2081 }
2082 }
2083 return -1;
2084 }
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094 public StrBuilder insert(int index, final boolean value) {
2095 validateIndex(index);
2096 if (value) {
2097 ensureCapacity(size + 4);
2098 System.arraycopy(buffer, index, buffer, index + 4, size - index);
2099 buffer[index++] = 't';
2100 buffer[index++] = 'r';
2101 buffer[index++] = 'u';
2102 buffer[index] = 'e';
2103 size += 4;
2104 } else {
2105 ensureCapacity(size + 5);
2106 System.arraycopy(buffer, index, buffer, index + 5, size - index);
2107 buffer[index++] = 'f';
2108 buffer[index++] = 'a';
2109 buffer[index++] = 'l';
2110 buffer[index++] = 's';
2111 buffer[index] = 'e';
2112 size += 5;
2113 }
2114 return this;
2115 }
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125 public StrBuilder insert(final int index, final char value) {
2126 validateIndex(index);
2127 ensureCapacity(size + 1);
2128 System.arraycopy(buffer, index, buffer, index + 1, size - index);
2129 buffer[index] = value;
2130 size++;
2131 return this;
2132 }
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143 public StrBuilder insert(final int index, final char[] chars) {
2144 validateIndex(index);
2145 if (chars == null) {
2146 return insert(index, nullText);
2147 }
2148 final int len = chars.length;
2149 if (len > 0) {
2150 ensureCapacity(size + len);
2151 System.arraycopy(buffer, index, buffer, index + len, size - index);
2152 System.arraycopy(chars, 0, buffer, index, len);
2153 size += len;
2154 }
2155 return this;
2156 }
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169 public StrBuilder insert(final int index, final char[] chars, final int offset, final int length) {
2170 validateIndex(index);
2171 if (chars == null) {
2172 return insert(index, nullText);
2173 }
2174 if (offset < 0 || offset > chars.length) {
2175 throw new StringIndexOutOfBoundsException("Invalid offset: " + offset);
2176 }
2177 if (length < 0 || offset + length > chars.length) {
2178 throw new StringIndexOutOfBoundsException("Invalid length: " + length);
2179 }
2180 if (length > 0) {
2181 ensureCapacity(size + length);
2182 System.arraycopy(buffer, index, buffer, index + length, size - index);
2183 System.arraycopy(chars, offset, buffer, index, length);
2184 size += length;
2185 }
2186 return this;
2187 }
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197 public StrBuilder insert(final int index, final double value) {
2198 return insert(index, String.valueOf(value));
2199 }
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209 public StrBuilder insert(final int index, final float value) {
2210 return insert(index, String.valueOf(value));
2211 }
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221 public StrBuilder insert(final int index, final int value) {
2222 return insert(index, String.valueOf(value));
2223 }
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233 public StrBuilder insert(final int index, final long value) {
2234 return insert(index, String.valueOf(value));
2235 }
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246 public StrBuilder insert(final int index, final Object obj) {
2247 if (obj == null) {
2248 return insert(index, nullText);
2249 }
2250 return insert(index, obj.toString());
2251 }
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262 public StrBuilder insert(final int index, String str) {
2263 validateIndex(index);
2264 if (str == null) {
2265 str = nullText;
2266 }
2267 if (str != null) {
2268 final int strLen = str.length();
2269 if (strLen > 0) {
2270 final int newSize = size + strLen;
2271 ensureCapacity(newSize);
2272 System.arraycopy(buffer, index, buffer, index + strLen, size - index);
2273 size = newSize;
2274 str.getChars(0, strLen, buffer, index);
2275 }
2276 }
2277 return this;
2278 }
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289 public boolean isEmpty() {
2290 return size == 0;
2291 }
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303 public boolean isNotEmpty() {
2304 return size > 0;
2305 }
2306
2307
2308
2309
2310
2311
2312
2313 public int lastIndexOf(final char ch) {
2314 return lastIndexOf(ch, size - 1);
2315 }
2316
2317
2318
2319
2320
2321
2322
2323
2324 public int lastIndexOf(final char ch, int startIndex) {
2325 startIndex = startIndex >= size ? size - 1 : startIndex;
2326 if (startIndex < 0) {
2327 return -1;
2328 }
2329 for (int i = startIndex; i >= 0; i--) {
2330 if (buffer[i] == ch) {
2331 return i;
2332 }
2333 }
2334 return -1;
2335 }
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346 public int lastIndexOf(final String str) {
2347 return lastIndexOf(str, size - 1);
2348 }
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361 public int lastIndexOf(final String str, int startIndex) {
2362 startIndex = startIndex >= size ? size - 1 : startIndex;
2363 if (str == null || startIndex < 0) {
2364 return -1;
2365 }
2366 final int strLen = str.length();
2367 if (strLen > 0 && strLen <= size) {
2368 if (strLen == 1) {
2369 return lastIndexOf(str.charAt(0), startIndex);
2370 }
2371
2372 outer:
2373 for (int i = startIndex - strLen + 1; i >= 0; i--) {
2374 for (int j = 0; j < strLen; j++) {
2375 if (str.charAt(j) != buffer[i + j]) {
2376 continue outer;
2377 }
2378 }
2379 return i;
2380 }
2381
2382 } else if (strLen == 0) {
2383 return startIndex;
2384 }
2385 return -1;
2386 }
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399 public int lastIndexOf(final StrMatcher matcher) {
2400 return lastIndexOf(matcher, size);
2401 }
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416 public int lastIndexOf(final StrMatcher matcher, int startIndex) {
2417 startIndex = startIndex >= size ? size - 1 : startIndex;
2418 if (matcher == null || startIndex < 0) {
2419 return -1;
2420 }
2421 final char[] buf = buffer;
2422 final int endIndex = startIndex + 1;
2423 for (int i = startIndex; i >= 0; i--) {
2424 if (matcher.isMatch(buf, i, 0, endIndex) > 0) {
2425 return i;
2426 }
2427 }
2428 return -1;
2429 }
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444 public String leftString(final int length) {
2445 if (length <= 0) {
2446 return StringUtils.EMPTY;
2447 }
2448 if (length >= size) {
2449 return new String(buffer, 0, size);
2450 }
2451 return new String(buffer, 0, length);
2452 }
2453
2454
2455
2456
2457
2458
2459 @Override
2460 public int length() {
2461 return size;
2462 }
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481 public String midString(int index, final int length) {
2482 if (index < 0) {
2483 index = 0;
2484 }
2485 if (length <= 0 || index >= size) {
2486 return StringUtils.EMPTY;
2487 }
2488 if (size <= index + length) {
2489 return new String(buffer, index, size - index);
2490 }
2491 return new String(buffer, index, length);
2492 }
2493
2494
2495
2496
2497
2498
2499 public StrBuilder minimizeCapacity() {
2500 if (buffer.length > length()) {
2501 final char[] old = buffer;
2502 buffer = new char[length()];
2503 System.arraycopy(old, 0, buffer, 0, size);
2504 }
2505 return this;
2506 }
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518 public int readFrom(final Readable readable) throws IOException {
2519 final int oldSize = size;
2520 if (readable instanceof Reader) {
2521 final Reader r = (Reader) readable;
2522 ensureCapacity(size + 1);
2523 int read;
2524 while ((read = r.read(buffer, size, buffer.length - size)) != -1) {
2525 size += read;
2526 ensureCapacity(size + 1);
2527 }
2528 } else if (readable instanceof CharBuffer) {
2529 final CharBuffer cb = (CharBuffer) readable;
2530 final int remaining = cb.remaining();
2531 ensureCapacity(size + remaining);
2532 cb.get(buffer, size, remaining);
2533 size += remaining;
2534 } else {
2535 while (true) {
2536 ensureCapacity(size + 1);
2537 final CharBuffer buf = CharBuffer.wrap(buffer, size, buffer.length - size);
2538 final int read = readable.read(buf);
2539 if (read == -1) {
2540 break;
2541 }
2542 size += read;
2543 }
2544 }
2545 return size - oldSize;
2546 }
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559 public StrBuilder replace(final int startIndex, int endIndex, final String replaceStr) {
2560 endIndex = validateRange(startIndex, endIndex);
2561 final int insertLen = replaceStr == null ? 0 : replaceStr.length();
2562 replaceImpl(startIndex, endIndex, endIndex - startIndex, replaceStr, insertLen);
2563 return this;
2564 }
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583 public StrBuilder replace(
2584 final StrMatcher matcher, final String replaceStr,
2585 final int startIndex, int endIndex, final int replaceCount) {
2586 endIndex = validateRange(startIndex, endIndex);
2587 return replaceImpl(matcher, replaceStr, startIndex, endIndex, replaceCount);
2588 }
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598 public StrBuilder replaceAll(final char search, final char replace) {
2599 if (search != replace) {
2600 for (int i = 0; i < size; i++) {
2601 if (buffer[i] == search) {
2602 buffer[i] = replace;
2603 }
2604 }
2605 }
2606 return this;
2607 }
2608
2609
2610
2611
2612
2613
2614
2615
2616 public StrBuilder replaceAll(final String searchStr, final String replaceStr) {
2617 final int searchLen = searchStr == null ? 0 : searchStr.length();
2618 if (searchLen > 0) {
2619 final int replaceLen = replaceStr == null ? 0 : replaceStr.length();
2620 int index = indexOf(searchStr, 0);
2621 while (index >= 0) {
2622 replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
2623 index = indexOf(searchStr, index + replaceLen);
2624 }
2625 }
2626 return this;
2627 }
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641 public StrBuilder replaceAll(final StrMatcher matcher, final String replaceStr) {
2642 return replace(matcher, replaceStr, 0, size, -1);
2643 }
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653 public StrBuilder replaceFirst(final char search, final char replace) {
2654 if (search != replace) {
2655 for (int i = 0; i < size; i++) {
2656 if (buffer[i] == search) {
2657 buffer[i] = replace;
2658 break;
2659 }
2660 }
2661 }
2662 return this;
2663 }
2664
2665
2666
2667
2668
2669
2670
2671
2672 public StrBuilder replaceFirst(final String searchStr, final String replaceStr) {
2673 final int searchLen = searchStr == null ? 0 : searchStr.length();
2674 if (searchLen > 0) {
2675 final int index = indexOf(searchStr, 0);
2676 if (index >= 0) {
2677 final int replaceLen = replaceStr == null ? 0 : replaceStr.length();
2678 replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
2679 }
2680 }
2681 return this;
2682 }
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696 public StrBuilder replaceFirst(final StrMatcher matcher, final String replaceStr) {
2697 return replace(matcher, replaceStr, 0, size, 1);
2698 }
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710 private void replaceImpl(final int startIndex,
2711 final int endIndex,
2712 final int removeLen,
2713 final String insertStr,
2714 final int insertLen) {
2715 final int newSize = size - removeLen + insertLen;
2716 if (insertLen != removeLen) {
2717 ensureCapacity(newSize);
2718 System.arraycopy(buffer, endIndex, buffer, startIndex + insertLen, size - endIndex);
2719 size = newSize;
2720 }
2721 if (insertLen > 0) {
2722 insertStr.getChars(0, insertLen, buffer, startIndex);
2723 }
2724 }
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742 private StrBuilder replaceImpl(
2743 final StrMatcher matcher, final String replaceStr,
2744 final int from, int to, int replaceCount) {
2745 if (matcher == null || size == 0) {
2746 return this;
2747 }
2748 final int replaceLen = replaceStr == null ? 0 : replaceStr.length();
2749 for (int i = from; i < to && replaceCount != 0; i++) {
2750 final char[] buf = buffer;
2751 final int removeLen = matcher.isMatch(buf, i, from, to);
2752 if (removeLen > 0) {
2753 replaceImpl(i, i + removeLen, removeLen, replaceStr, replaceLen);
2754 to = to - removeLen + replaceLen;
2755 i = i + replaceLen - 1;
2756 if (replaceCount > 0) {
2757 replaceCount--;
2758 }
2759 }
2760 }
2761 return this;
2762 }
2763
2764
2765
2766
2767
2768
2769 public StrBuilder reverse() {
2770 if (size == 0) {
2771 return this;
2772 }
2773
2774 final int half = size / 2;
2775 final char[] buf = buffer;
2776 for (int leftIdx = 0, rightIdx = size - 1; leftIdx < half; leftIdx++, rightIdx--) {
2777 final char swap = buf[leftIdx];
2778 buf[leftIdx] = buf[rightIdx];
2779 buf[rightIdx] = swap;
2780 }
2781 return this;
2782 }
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797 public String rightString(final int length) {
2798 if (length <= 0) {
2799 return StringUtils.EMPTY;
2800 }
2801 if (length >= size) {
2802 return new String(buffer, 0, size);
2803 }
2804 return new String(buffer, size - length, length);
2805 }
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817 public StrBuilder setCharAt(final int index, final char ch) {
2818 if (index < 0 || index >= length()) {
2819 throw new StringIndexOutOfBoundsException(index);
2820 }
2821 buffer[index] = ch;
2822 return this;
2823 }
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833 public StrBuilder setLength(final int length) {
2834 if (length < 0) {
2835 throw new StringIndexOutOfBoundsException(length);
2836 }
2837 if (length < size) {
2838 size = length;
2839 } else if (length > size) {
2840 ensureCapacity(length);
2841 final int oldEnd = size;
2842 size = length;
2843 for (int i = oldEnd; i < length; i++) {
2844 buffer[i] = '\0';
2845 }
2846 }
2847 return this;
2848 }
2849
2850
2851
2852
2853
2854
2855
2856 public StrBuilder setNewLineText(final String newLine) {
2857 this.newLine = newLine;
2858 return this;
2859 }
2860
2861
2862
2863
2864
2865
2866
2867 public StrBuilder setNullText(String nullText) {
2868 if (nullText != null && nullText.isEmpty()) {
2869 nullText = null;
2870 }
2871 this.nullText = nullText;
2872 return this;
2873 }
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884 public int size() {
2885 return size;
2886 }
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897 public boolean startsWith(final String str) {
2898 if (str == null) {
2899 return false;
2900 }
2901 final int len = str.length();
2902 if (len == 0) {
2903 return true;
2904 }
2905 if (len > size) {
2906 return false;
2907 }
2908 for (int i = 0; i < len; i++) {
2909 if (buffer[i] != str.charAt(i)) {
2910 return false;
2911 }
2912 }
2913 return true;
2914 }
2915
2916
2917
2918
2919 @Override
2920 public CharSequence subSequence(final int startIndex, final int endIndex) {
2921 if (startIndex < 0) {
2922 throw new StringIndexOutOfBoundsException(startIndex);
2923 }
2924 if (endIndex > size) {
2925 throw new StringIndexOutOfBoundsException(endIndex);
2926 }
2927 if (startIndex > endIndex) {
2928 throw new StringIndexOutOfBoundsException(endIndex - startIndex);
2929 }
2930 return substring(startIndex, endIndex);
2931 }
2932
2933
2934
2935
2936
2937
2938
2939
2940 public String substring(final int start) {
2941 return substring(start, size);
2942 }
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957 public String substring(final int startIndex, int endIndex) {
2958 endIndex = validateRange(startIndex, endIndex);
2959 return new String(buffer, startIndex, endIndex - startIndex);
2960 }
2961
2962
2963
2964
2965
2966
2967 public char[] toCharArray() {
2968 return size == 0 ? ArrayUtils.EMPTY_CHAR_ARRAY : Arrays.copyOf(buffer, size);
2969 }
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981 public char[] toCharArray(final int startIndex, int endIndex) {
2982 endIndex = validateRange(startIndex, endIndex);
2983 final int len = endIndex - startIndex;
2984 if (len == 0) {
2985 return ArrayUtils.EMPTY_CHAR_ARRAY;
2986 }
2987 final char[] chars = new char[len];
2988 System.arraycopy(buffer, startIndex, chars, 0, len);
2989 return chars;
2990 }
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002 @Override
3003 public String toString() {
3004 return new String(buffer, 0, size);
3005 }
3006
3007
3008
3009
3010
3011
3012
3013 public StringBuffer toStringBuffer() {
3014 return new StringBuffer(size).append(buffer, 0, size);
3015 }
3016
3017
3018
3019
3020
3021
3022
3023 public StringBuilder toStringBuilder() {
3024 return new StringBuilder(size).append(buffer, 0, size);
3025 }
3026
3027
3028
3029
3030
3031
3032
3033 public StrBuilder trim() {
3034 if (size == 0) {
3035 return this;
3036 }
3037 int len = size;
3038 final char[] buf = buffer;
3039 int pos = 0;
3040 while (pos < len && buf[pos] <= ' ') {
3041 pos++;
3042 }
3043 while (pos < len && buf[len - 1] <= ' ') {
3044 len--;
3045 }
3046 if (len < size) {
3047 delete(len, size);
3048 }
3049 if (pos > 0) {
3050 delete(0, pos);
3051 }
3052 return this;
3053 }
3054
3055
3056
3057
3058
3059
3060
3061 protected void validateIndex(final int index) {
3062 if (index < 0 || index > size) {
3063 throw new StringIndexOutOfBoundsException(index);
3064 }
3065 }
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076 protected int validateRange(final int startIndex, int endIndex) {
3077 if (startIndex < 0) {
3078 throw new StringIndexOutOfBoundsException(startIndex);
3079 }
3080 if (endIndex > size) {
3081 endIndex = size;
3082 }
3083 if (startIndex > endIndex) {
3084 throw new StringIndexOutOfBoundsException("end < start");
3085 }
3086 return endIndex;
3087 }
3088
3089 }