1 /*
2  * Copyright (c) 2015, 2018, 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package test.java.lang.StringBuffer;
25 
26 import java.util.Arrays;
27 
28 import org.testng.annotations.Test;
29 
30 import static org.testng.Assert.assertEquals;
31 import static org.testng.Assert.assertTrue;
32 
33 /*
34  * @test
35  * @bug 8077559
36  * @summary Tests Compact String. This test is testing StringBuffer
37  *          behavior related to Compact String.
38  * @run testng/othervm -XX:+CompactStrings CompactStringBuffer
39  * @run testng/othervm -XX:-CompactStrings CompactStringBuffer
40  */
41 
42 public class CompactStringBuffer {
43 
44     /*
45      * Tests for "A"
46      */
47     @Test
testCompactStringBufferForLatinA()48     public void testCompactStringBufferForLatinA() {
49         final String ORIGIN = "A";
50         /*
51          * Because right now ASCII is the default encoding parameter for source
52          * code in JDK build environment, so we escape them. same as below.
53          */
54         check(new StringBuffer(ORIGIN).append(new char[] { '\uFF21' }),
55                 "A\uFF21");
56         check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
57                 "A\uFF21");
58         check(new StringBuffer(ORIGIN).append("\uFF21"), "A\uFF21");
59         check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
60                 "A\uFF21");
61         check(new StringBuffer(ORIGIN).delete(0, 1), "");
62         check(new StringBuffer(ORIGIN).delete(0, 0), "A");
63         check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
64         assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 0);
65         assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), -1);
66         assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
67         assertEquals(new StringBuffer(ORIGIN).insert(1, "\uD801\uDC00")
68                 .indexOf("A", 0), 0);
69         assertEquals(new StringBuffer(ORIGIN).insert(0, "\uD801\uDC00")
70                 .indexOf("A", 0), 2);
71         check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "A");
72         check(new StringBuffer(ORIGIN).insert(1, new char[] { '\uFF21' }),
73                 "A\uFF21");
74         check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
75                 "\uFF21A");
76         check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("\uFF21")),
77                 "\uFF21A");
78         check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("\uFF21")),
79                 "A\uFF21");
80         check(new StringBuffer(ORIGIN).insert(0, ""), "A");
81         check(new StringBuffer(ORIGIN).insert(0, "\uFF21"), "\uFF21A");
82         check(new StringBuffer(ORIGIN).insert(1, "\uFF21"), "A\uFF21");
83         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
84         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
85         assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
86         check(new StringBuffer(ORIGIN).replace(0, 0, "\uFF21"), "\uFF21A");
87         check(new StringBuffer(ORIGIN).replace(0, 1, "\uFF21"), "\uFF21");
88         checkSetCharAt(new StringBuffer(ORIGIN), 0, '\uFF21', "\uFF21");
89         checkSetLength(new StringBuffer(ORIGIN), 0, "");
90         checkSetLength(new StringBuffer(ORIGIN), 1, "A");
91         check(new StringBuffer(ORIGIN).substring(0), "A");
92         check(new StringBuffer(ORIGIN).substring(1), "");
93     }
94 
95     /*
96      * Tests for "\uFF21"
97      */
98     @Test
testCompactStringBufferForNonLatinA()99     public void testCompactStringBufferForNonLatinA() {
100         final String ORIGIN = "\uFF21";
101         check(new StringBuffer(ORIGIN).append(new char[] { 'A' }), "\uFF21A");
102         check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
103         check(new StringBuffer(ORIGIN).append("A"), "\uFF21A");
104         check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
105         check(new StringBuffer(ORIGIN).delete(0, 1), "");
106         check(new StringBuffer(ORIGIN).delete(0, 0), "\uFF21");
107         check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
108         assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), -1);
109         assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
110         assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
111         check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "\uFF21");
112         check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21A");
113         check(new StringBuffer(ORIGIN).insert(0, new char[] { 'A' }), "A\uFF21");
114         check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("A")),
115                 "A\uFF21");
116         check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("A")),
117                 "\uFF21A");
118         check(new StringBuffer(ORIGIN).insert(0, ""), "\uFF21");
119         check(new StringBuffer(ORIGIN).insert(0, "A"), "A\uFF21");
120         check(new StringBuffer(ORIGIN).insert(1, "A"), "\uFF21A");
121         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
122         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
123         assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
124         check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21");
125         check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "A");
126         checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "A");
127         checkSetLength(new StringBuffer(ORIGIN), 0, "");
128         checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
129         check(new StringBuffer(ORIGIN).substring(0), "\uFF21");
130         check(new StringBuffer(ORIGIN).substring(1), "");
131     }
132 
133     /*
134      * Tests for "\uFF21A"
135      */
136     @Test
testCompactStringBufferForMixedA1()137     public void testCompactStringBufferForMixedA1() {
138         final String ORIGIN = "\uFF21A";
139         check(new StringBuffer(ORIGIN).delete(0, 1), "A");
140         check(new StringBuffer(ORIGIN).delete(1, 2), "\uFF21");
141         check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uFF21");
142         check(new StringBuffer(ORIGIN).deleteCharAt(0), "A");
143         assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 1);
144         assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
145         assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
146         check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21AA");
147         check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
148                 "\uFF21\uFF21A");
149         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 1);
150         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
151         assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 2);
152         check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21A");
153         check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "AA");
154         checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "AA");
155         checkSetLength(new StringBuffer(ORIGIN), 0, "");
156         checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
157         check(new StringBuffer(ORIGIN).substring(0), "\uFF21A");
158         check(new StringBuffer(ORIGIN).substring(1), "A");
159     }
160 
161     /*
162      * Tests for "A\uFF21"
163      */
164     @Test
testCompactStringBufferForMixedA2()165     public void testCompactStringBufferForMixedA2() {
166         final String ORIGIN = "A\uFF21";
167         check(new StringBuffer(ORIGIN).replace(1, 2, "A"), "AA");
168         checkSetLength(new StringBuffer(ORIGIN), 1, "A");
169         check(new StringBuffer(ORIGIN).substring(0), "A\uFF21");
170         check(new StringBuffer(ORIGIN).substring(1), "\uFF21");
171         check(new StringBuffer(ORIGIN).substring(0, 1), "A");
172     }
173 
174     /*
175      * Tests for "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A"
176      */
177     @Test
testCompactStringBufferForDuplicatedMixedA1()178     public void testCompactStringBufferForDuplicatedMixedA1() {
179         final String ORIGIN = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
180         checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
181         assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 5);
182         assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 6);
183         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 9);
184         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 8);
185         assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 10);
186         check(new StringBuffer(ORIGIN).substring(9), "A");
187         check(new StringBuffer(ORIGIN).substring(8), "\uFF21A");
188     }
189 
190     /*
191      * Tests for "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21"
192      */
193     @Test
testCompactStringBufferForDuplicatedMixedA2()194     public void testCompactStringBufferForDuplicatedMixedA2() {
195         final String ORIGIN = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
196         checkSetLength(new StringBuffer(ORIGIN), 1, "A");
197         assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 6);
198         assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 5);
199         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 8);
200         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 9);
201         check(new StringBuffer(ORIGIN).substring(9), "\uFF21");
202         check(new StringBuffer(ORIGIN).substring(8), "A\uFF21");
203     }
204 
205     /*
206      * Tests for "\uD801\uDC00\uD801\uDC01"
207      */
208     @Test
testCompactStringForSupplementaryCodePoint()209     public void testCompactStringForSupplementaryCodePoint() {
210         final String ORIGIN = "\uD801\uDC00\uD801\uDC01";
211         check(new StringBuffer(ORIGIN).append("A"), "\uD801\uDC00\uD801\uDC01A");
212         check(new StringBuffer(ORIGIN).append("\uFF21"),
213                 "\uD801\uDC00\uD801\uDC01\uFF21");
214         check(new StringBuffer(ORIGIN).appendCodePoint('A'),
215                 "\uD801\uDC00\uD801\uDC01A");
216         check(new StringBuffer(ORIGIN).appendCodePoint('\uFF21'),
217                 "\uD801\uDC00\uD801\uDC01\uFF21");
218         assertEquals(new StringBuffer(ORIGIN).charAt(0), '\uD801');
219         assertEquals(new StringBuffer(ORIGIN).codePointAt(0),
220                 Character.codePointAt(ORIGIN, 0));
221         assertEquals(new StringBuffer(ORIGIN).codePointAt(1),
222                 Character.codePointAt(ORIGIN, 1));
223         assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
224                 Character.codePointAt(ORIGIN, 0));
225         assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
226         check(new StringBuffer(ORIGIN).delete(0, 2), "\uD801\uDC01");
227         check(new StringBuffer(ORIGIN).delete(0, 3), "\uDC01");
228         check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uD801\uD801\uDC01");
229         checkGetChars(new StringBuffer(ORIGIN), 0, 3, new char[] { '\uD801',
230                 '\uDC00', '\uD801' });
231         assertEquals(new StringBuffer(ORIGIN).indexOf("\uD801\uDC01"), 2);
232         assertEquals(new StringBuffer(ORIGIN).indexOf("\uDC01"), 3);
233         assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), -1);
234         assertEquals(new StringBuffer(ORIGIN).indexOf("A"), -1);
235         check(new StringBuffer(ORIGIN).insert(0, "\uFF21"),
236                 "\uFF21\uD801\uDC00\uD801\uDC01");
237         check(new StringBuffer(ORIGIN).insert(1, "\uFF21"),
238                 "\uD801\uFF21\uDC00\uD801\uDC01");
239         check(new StringBuffer(ORIGIN).insert(1, "A"),
240                 "\uD801A\uDC00\uD801\uDC01");
241         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uDC00\uD801"), 1);
242         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uD801"), 2);
243         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
244         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
245         assertEquals(new StringBuffer(ORIGIN).length(), 4);
246         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
247         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
248         check(new StringBuffer(ORIGIN).replace(0, 2, "A"), "A\uD801\uDC01");
249         check(new StringBuffer(ORIGIN).replace(0, 3, "A"), "A\uDC01");
250         check(new StringBuffer(ORIGIN).replace(0, 2, "\uFF21"),
251                 "\uFF21\uD801\uDC01");
252         check(new StringBuffer(ORIGIN).replace(0, 3, "\uFF21"), "\uFF21\uDC01");
253         check(new StringBuffer(ORIGIN).reverse(), "\uD801\uDC01\uD801\uDC00");
254         checkSetCharAt(new StringBuffer(ORIGIN), 1, '\uDC01',
255                 "\uD801\uDC01\uD801\uDC01");
256         checkSetCharAt(new StringBuffer(ORIGIN), 1, 'A', "\uD801A\uD801\uDC01");
257         checkSetLength(new StringBuffer(ORIGIN), 2, "\uD801\uDC00");
258         checkSetLength(new StringBuffer(ORIGIN), 3, "\uD801\uDC00\uD801");
259         check(new StringBuffer(ORIGIN).substring(1, 3), "\uDC00\uD801");
260     }
261 
262     /*
263      * Tests for "A\uD801\uDC00\uFF21"
264      */
265     @Test
testCompactStringForSupplementaryCodePointMixed1()266     public void testCompactStringForSupplementaryCodePointMixed1() {
267         final String ORIGIN = "A\uD801\uDC00\uFF21";
268         assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
269                 Character.codePointAt(ORIGIN, 1));
270         assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uD801');
271         assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
272         assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
273         assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
274         check(new StringBuffer(ORIGIN).delete(0, 1), "\uD801\uDC00\uFF21");
275         check(new StringBuffer(ORIGIN).delete(0, 1).delete(2, 3), "\uD801\uDC00");
276         check(new StringBuffer(ORIGIN).deleteCharAt(3).deleteCharAt(0),
277                 "\uD801\uDC00");
278         assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), 3);
279         assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 0);
280         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 3);
281         assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
282         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
283         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 3);
284         check(new StringBuffer(ORIGIN).replace(1, 3, "A"), "AA\uFF21");
285         check(new StringBuffer(ORIGIN).replace(1, 4, "A"), "AA");
286         check(new StringBuffer(ORIGIN).replace(1, 4, ""), "A");
287         check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uD801\uDC00A");
288         checkSetLength(new StringBuffer(ORIGIN), 1, "A");
289         check(new StringBuffer(ORIGIN).substring(0, 1), "A");
290     }
291 
292     /*
293      * Tests for "\uD801\uDC00\uFF21A"
294      */
295     @Test
testCompactStringForSupplementaryCodePointMixed2()296     public void testCompactStringForSupplementaryCodePointMixed2() {
297         final String ORIGIN = "\uD801\uDC00\uFF21A";
298         assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
299                 Character.codePointAt(ORIGIN, 2));
300         assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
301                 Character.codePointAt(ORIGIN, 0));
302         assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
303         assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
304         assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
305         check(new StringBuffer(ORIGIN).delete(0, 2), "\uFF21A");
306         check(new StringBuffer(ORIGIN).delete(0, 3), "A");
307         check(new StringBuffer(ORIGIN).deleteCharAt(0).deleteCharAt(0)
308                 .deleteCharAt(0), "A");
309         assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 3);
310         assertEquals(new StringBuffer(ORIGIN).delete(0, 3).indexOf("A"), 0);
311         assertEquals(new StringBuffer(ORIGIN).replace(0, 3, "B").indexOf("A"),
312                 1);
313         assertEquals(new StringBuffer(ORIGIN).substring(3, 4).indexOf("A"), 0);
314         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
315         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
316         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
317         check(new StringBuffer(ORIGIN).replace(0, 3, "B"), "BA");
318         check(new StringBuffer(ORIGIN).reverse(), "A\uFF21\uD801\uDC00");
319     }
320 
321     /*
322      * Tests for "\uD801A\uDC00\uFF21"
323      */
324     @Test
testCompactStringForSupplementaryCodePointMixed3()325     public void testCompactStringForSupplementaryCodePointMixed3() {
326         final String ORIGIN = "\uD801A\uDC00\uFF21";
327         assertEquals(new StringBuffer(ORIGIN).codePointAt(1), 'A');
328         assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uFF21');
329         assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
330         assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), 'A');
331         assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uDC00');
332         assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
333         assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
334         assertEquals(new StringBuffer(ORIGIN).delete(0, 1).delete(1, 3)
335                 .indexOf("A"), 0);
336         assertEquals(
337                 new StringBuffer(ORIGIN).replace(0, 1, "B").replace(2, 4, "C")
338                         .indexOf("A"), 1);
339         assertEquals(new StringBuffer(ORIGIN).substring(1, 4).substring(0, 1)
340                 .indexOf("A"), 0);
341         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
342         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
343         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
344         check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uDC00A\uD801");
345     }
346 
347     /*
348      * Tests for "A\uDC01\uFF21\uD801"
349      */
350     @Test
testCompactStringForSupplementaryCodePointMixed4()351     public void testCompactStringForSupplementaryCodePointMixed4() {
352         final String ORIGIN = "A\uDC01\uFF21\uD801";
353         assertEquals(new StringBuffer(ORIGIN).codePointAt(1), '\uDC01');
354         assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uD801');
355         assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
356         assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uDC01');
357         assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uFF21');
358         assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
359         assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
360         assertEquals(new StringBuffer(ORIGIN).delete(1, 4).indexOf("A"), 0);
361         assertEquals(new StringBuffer(ORIGIN).replace(1, 4, "B").indexOf("A"),
362                 0);
363         assertEquals(new StringBuffer(ORIGIN).substring(0, 1).indexOf("A"), 0);
364         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
365         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
366         assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
367         check(new StringBuffer(ORIGIN).reverse(), "\uD801\uFF21\uDC01A");
368     }
369 
370     @Test
testCompactStringMisc()371     public void testCompactStringMisc() {
372         String ascii = "abcdefgh";
373         String asciiMixed = "abc" + "\u4e00\u4e01\u4e02" + "fgh";
374         String bmp = "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08";
375         String bmpMixed = "\u4e00\u4e01\u4e02" + "ABC" + "\u4e06\u4e07\u4e08";
376 
377         check(new StringBuffer().append(ascii).delete(0, 20).toString(),
378               "");
379         check(new StringBuffer().append(ascii).delete(3, 20).toString(),
380               "abc");
381         check(new StringBuffer().append(ascii).delete(3, 6).toString(),
382               "abcgh");
383         check(new StringBuffer().append(ascii).deleteCharAt(0).toString(),
384               "bcdefgh");
385         check(new StringBuffer().append(ascii).deleteCharAt(3).toString(),
386               "abcefgh");
387         check(new StringBuffer().append(asciiMixed).delete(3, 6).toString(),
388               "abcfgh");
389         check(new StringBuffer().append(asciiMixed).deleteCharAt(3).toString(),
390               "abc\u4e01\u4e02fgh");
391         check(new StringBuffer().append(asciiMixed).deleteCharAt(3)
392                                                    .deleteCharAt(3)
393                                                    .deleteCharAt(3).toString(),
394               "abcfgh");
395         check(new StringBuffer().append(bmp).delete(0, 20).toString(),
396               "");
397         check(new StringBuffer().append(bmp).delete(3, 20).toString(),
398               "\u4e00\u4e01\u4e02");
399         check(new StringBuffer().append(bmp).delete(3, 6).toString(),
400               "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
401         check(new StringBuffer().append(bmp).deleteCharAt(0).toString(),
402               "\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
403         check(new StringBuffer().append(bmp).deleteCharAt(3).toString(),
404               "\u4e00\u4e01\u4e02\u4e04\u4e05\u4e06\u4e07\u4e08");
405         check(new StringBuffer().append(bmpMixed).delete(3, 6).toString(),
406               "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
407 
408         ////////////////////////////////////////////////////////////////////
409         check(new StringBuffer().append(ascii).replace(3, 6, "AB").toString(),
410               "abcABgh");
411         check(new StringBuffer().append(asciiMixed).replace(3, 6, "AB").toString(),
412               "abcABfgh");
413         check(new StringBuffer().append(bmp).replace(3, 6, "AB").toString(),
414               "\u4e00\u4e01\u4e02AB\u4e06\u4e07\u4e08");
415 
416         check(new StringBuffer().append(bmpMixed).replace(3, 6, "").toString(),
417               "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
418 
419         check(new StringBuffer().append(ascii).replace(3, 6, "\u4e01\u4e02").toString(),
420               "abc\u4e01\u4e02gh");
421 
422         ////////////////////////////////////////////////////////////////////
423         check(new StringBuffer().append(ascii).insert(3, "").toString(),
424               "abcdefgh");
425         check(new StringBuffer().append(ascii).insert(3, "AB").toString(),
426               "abcABdefgh");
427         check(new StringBuffer().append(ascii).insert(3, "\u4e01\u4e02").toString(),
428               "abc\u4e01\u4e02defgh");
429 
430         check(new StringBuffer().append(asciiMixed).insert(0, 'A').toString(),
431               "Aabc\u4e00\u4e01\u4e02fgh");
432         check(new StringBuffer().append(asciiMixed).insert(3, "A").toString(),
433               "abcA\u4e00\u4e01\u4e02fgh");
434 
435         check(new StringBuffer().append(ascii).insert(3, 1234567).toString(),
436               "abc1234567defgh");
437         check(new StringBuffer().append(bmp).insert(3, 1234567).toString(),
438               "\u4e00\u4e01\u4e021234567\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
439 
440         ////////////////////////////////////////////////////////////////////
441         check(new StringBuffer().append(ascii).append(1.23456).toString(),
442               "abcdefgh1.23456");
443         check(new StringBuffer().append(bmp).append(1.23456).toString(),
444               "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e081.23456");
445     }
446 
checkGetChars(StringBuffer sb, int srcBegin, int srcEnd, char expected[])447     private void checkGetChars(StringBuffer sb, int srcBegin, int srcEnd,
448             char expected[]) {
449         char[] dst = new char[srcEnd - srcBegin];
450         sb.getChars(srcBegin, srcEnd, dst, 0);
451         assertTrue(Arrays.equals(dst, expected));
452     }
453 
checkSetCharAt(StringBuffer sb, int index, char ch, String expected)454     private void checkSetCharAt(StringBuffer sb, int index, char ch,
455             String expected) {
456         sb.setCharAt(index, ch);
457         check(sb, expected);
458     }
459 
checkSetLength(StringBuffer sb, int newLength, String expected)460     private void checkSetLength(StringBuffer sb, int newLength, String expected) {
461         sb.setLength(newLength);
462         check(sb, expected);
463     }
464 
check(StringBuffer sb, String expected)465     private void check(StringBuffer sb, String expected) {
466         check(sb.toString(), expected);
467     }
468 
check(String str, String expected)469     private void check(String str, String expected) {
470         assertTrue(str.equals(expected), String.format(
471                 "Get (%s) but expect (%s), ", escapeNonASCIIs(str),
472                 escapeNonASCIIs(expected)));
473     }
474 
475     /*
476      * Escape non-ASCII characters since not all systems support them.
477      */
escapeNonASCIIs(String str)478     private String escapeNonASCIIs(String str) {
479         StringBuilder sb = new StringBuilder();
480         for (int i = 0; i < str.length(); i++) {
481             char c = str.charAt(i);
482             if (c > 0x7F) {
483                 sb.append("\\u").append(Integer.toHexString((int) c));
484             } else {
485                 sb.append(c);
486             }
487         }
488         return sb.toString();
489     }
490 }
491