blob: df0a3ddf48853a1e993553e57f64f235a4da763f [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import junit.framework.Assert;
Jeff Hao848f70a2014-01-15 13:49:50 -080018import java.lang.reflect.Method;
jeffhao5d1ac922011-09-29 17:41:15 -070019
20/**
21 * more string tests
22 */
23public class Main {
Jeff Hao848f70a2014-01-15 13:49:50 -080024 public static void main(String args[]) throws Exception {
jeffhao5d1ac922011-09-29 17:41:15 -070025 String test = "0123456789";
26 String test1 = new String("0123456789"); // different object
27 String test2 = new String("0123456780"); // different value
28 String offset = new String("xxx0123456789yyy");
29 String sub = offset.substring(3, 13);
30 Object blah = new Object();
31
32 Assert.assertTrue(test.equals(test));
33 Assert.assertTrue(test.equals(test1));
34 Assert.assertFalse(test.equals(test2));
35
36 Assert.assertEquals(test.compareTo(test1), 0);
37 Assert.assertTrue(test1.compareTo(test2) > 0);
38 Assert.assertTrue(test2.compareTo(test1) < 0);
39
Alexei Zavjalov4554bfd2014-02-26 17:28:35 +070040 Assert.assertEquals("".compareTo(""), 0);
41 Assert.assertTrue(test.compareTo("") > 0);
42 Assert.assertTrue("".compareTo(test) < 0);
43
jeffhao5d1ac922011-09-29 17:41:15 -070044 /* compare string with a nonzero offset, in left/right side */
45 Assert.assertEquals(test.compareTo(sub), 0);
46 Assert.assertEquals(sub.compareTo(test), 0);
47 Assert.assertTrue(test.equals(sub));
48 Assert.assertTrue(sub.equals(test));
49 /* same base, one is a substring */
50 Assert.assertFalse(offset.equals(sub));
51 Assert.assertFalse(sub.equals(offset));
52 /* wrong class */
53 Assert.assertFalse(test.equals(blah));
54
55 /* null ptr - throw */
56 try {
57 test.compareTo(null);
58 Assert.fail("didn't get expected npe");
59 } catch (NullPointerException npe) {
60 System.out.println("Got expected npe");
61 }
62 /* null ptr - ok */
63 Assert.assertFalse(test.equals(null));
64
65 test = test.substring(1);
66 Assert.assertTrue(test.equals("123456789"));
67 Assert.assertFalse(test.equals(test1));
68
69 test = test.substring(1);
70 Assert.assertTrue(test.equals("23456789"));
71
72 test = test.substring(1);
73 Assert.assertTrue(test.equals("3456789"));
74
75 test = test.substring(1);
76 Assert.assertTrue(test.equals("456789"));
77
78 test = test.substring(3,5);
79 Assert.assertTrue(test.equals("78"));
80
81 test = "this/is/a/path";
82 String[] strings = test.split("/");
83 Assert.assertEquals(4, strings.length);
84
85 Assert.assertEquals("this is a path", test.replaceAll("/", " "));
86 Assert.assertEquals("this is a path", test.replace("/", " "));
Jeff Hao848f70a2014-01-15 13:49:50 -080087
Andreas Gampe166aaee2016-07-18 08:27:23 -070088 Class<?> Strings = Class.forName("com.android.org.bouncycastle.util.Strings");
Jeff Hao848f70a2014-01-15 13:49:50 -080089 Method fromUTF8ByteArray = Strings.getDeclaredMethod("fromUTF8ByteArray", byte[].class);
90 String result = (String) fromUTF8ByteArray.invoke(null, new byte[] {'O', 'K'});
91 System.out.println(result);
Vladimir Marko9c9883b2016-10-17 14:45:29 +010092
93 testCompareToAndEquals();
94 testIndexOf();
Vladimir Marko16850ae2016-12-09 14:01:02 +000095
96 String s0_0 = "\u0000";
97 String s0_1 = new String(s0_0);
98 String s0_2 = new String(new char[] { '\u0000' });
99 String s0_3 = s0_0 + "";
100 System.out.println(
101 " " + $noinline$equals(s0_0, s0_0) +
102 " " + $noinline$equals(s0_0, s0_1) +
103 " " + $noinline$equals(s0_0, s0_2) +
104 " " + $noinline$equals(s0_0, s0_3));
105 System.out.println(
106 " " + $noinline$equals(s0_1, s0_0) +
107 " " + $noinline$equals(s0_1, s0_1) +
108 " " + $noinline$equals(s0_1, s0_2) +
109 " " + $noinline$equals(s0_1, s0_3));
110 System.out.println(
111 " " + $noinline$equals(s0_2, s0_0) +
112 " " + $noinline$equals(s0_2, s0_1) +
113 " " + $noinline$equals(s0_2, s0_2) +
114 " " + $noinline$equals(s0_2, s0_3));
115 System.out.println(
116 " " + $noinline$equals(s0_3, s0_0) +
117 " " + $noinline$equals(s0_3, s0_1) +
118 " " + $noinline$equals(s0_3, s0_2) +
119 " " + $noinline$equals(s0_3, s0_3));
jeffhao5d1ac922011-09-29 17:41:15 -0700120 }
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100121
122 public static void testCompareToAndEquals() {
123 String[] strings = {
124 // Special: empty string.
125 "",
126 // Category 0, ASCII strings:
127 // "0123456789abcdef".substring(0, index + 1)
128 "0",
129 "01",
130 "012",
131 "0123",
132 "01234",
133 "012345",
134 "0123456",
135 "01234567",
136 "012345678",
137 "0123456789",
138 "0123456789a",
139 "0123456789ab",
140 "0123456789abc",
141 "0123456789abcd",
142 "0123456789abcde",
143 "0123456789abcdef",
144 // Category 1, ASCII strings:
145 // "0123456789abcdef".substring(0, index) + "x"
146 "x",
147 "0x",
148 "01x",
149 "012x",
150 "0123x",
151 "01234x",
152 "012345x",
153 "0123456x",
154 "01234567x",
155 "012345678x",
156 "0123456789x",
157 "0123456789ax",
158 "0123456789abx",
159 "0123456789abcx",
160 "0123456789abcdx",
161 "0123456789abcdex",
162 // Category 2, ASCII strings,
163 // "0123456789abcdef".substring(0, index) + "x" +
164 // "0123456789abcdef".substring(index + 1)
165 "x123456789abcdef",
166 "0x23456789abcdef",
167 "01x3456789abcdef",
168 "012x456789abcdef",
169 "0123x56789abcdef",
170 "01234x6789abcdef",
171 "012345x789abcdef",
172 "0123456x89abcdef",
173 "01234567x9abcdef",
174 "012345678xabcdef",
175 "0123456789xbcdef",
176 "0123456789axcdef",
177 "0123456789abxdef",
178 "0123456789abcxef",
179 "0123456789abcdxf",
180 "0123456789abcdex",
181 // Category 3, ASCII strings:
182 // "z" + "0123456789abcdef".substring(1, index + 1)
183 "z",
184 "z1",
185 "z12",
186 "z123",
187 "z1234",
188 "z12345",
189 "z123456",
190 "z1234567",
191 "z12345678",
192 "z123456789",
193 "z123456789a",
194 "z123456789ab",
195 "z123456789abc",
196 "z123456789abcd",
197 "z123456789abcde",
198 "z123456789abcdef",
199 // Category 4, non-ASCII strings:
200 // "0123456789abcdef".substring(0, index) + "\u0440"
201 "\u0440",
202 "0\u0440",
203 "01\u0440",
204 "012\u0440",
205 "0123\u0440",
206 "01234\u0440",
207 "012345\u0440",
208 "0123456\u0440",
209 "01234567\u0440",
210 "012345678\u0440",
211 "0123456789\u0440",
212 "0123456789a\u0440",
213 "0123456789ab\u0440",
214 "0123456789abc\u0440",
215 "0123456789abcd\u0440",
216 "0123456789abcde\u0440",
217 // Category 5, non-ASCII strings:
218 // "0123456789abcdef".substring(0, index) + "\u0440" +
219 // "0123456789abcdef".substring(index + 1)
220 "\u0440123456789abcdef",
221 "0\u044023456789abcdef",
222 "01\u04403456789abcdef",
223 "012\u0440456789abcdef",
224 "0123\u044056789abcdef",
225 "01234\u04406789abcdef",
226 "012345\u0440789abcdef",
227 "0123456\u044089abcdef",
228 "01234567\u04409abcdef",
229 "012345678\u0440abcdef",
230 "0123456789\u0440bcdef",
231 "0123456789a\u0440cdef",
232 "0123456789ab\u0440def",
233 "0123456789abc\u0440ef",
234 "0123456789abcd\u0440f",
235 "0123456789abcde\u0440",
236 // Category 6, ASCII strings:
237 // "\u0443" + "0123456789abcdef".substring(1, index + 1)
238 "\u0443",
239 "\u04431",
240 "\u044312",
241 "\u0443123",
242 "\u04431234",
243 "\u044312345",
244 "\u0443123456",
245 "\u04431234567",
246 "\u044312345678",
247 "\u0443123456789",
248 "\u0443123456789a",
249 "\u0443123456789ab",
250 "\u0443123456789abc",
251 "\u0443123456789abcd",
252 "\u0443123456789abcde",
253 "\u0443123456789abcdef",
254 // Category 7, non-ASCII strings:
255 // "0123456789abcdef".substring(0, index) + "\u0482"
256 "\u0482",
257 "0\u0482",
258 "01\u0482",
259 "012\u0482",
260 "0123\u0482",
261 "01234\u0482",
262 "012345\u0482",
263 "0123456\u0482",
264 "01234567\u0482",
265 "012345678\u0482",
266 "0123456789\u0482",
267 "0123456789a\u0482",
268 "0123456789ab\u0482",
269 "0123456789abc\u0482",
270 "0123456789abcd\u0482",
271 "0123456789abcde\u0482",
272 // Category 8, non-ASCII strings:
273 // "0123456789abcdef".substring(0, index) + "\u0482" +
274 // "0123456789abcdef".substring(index + 1)
275 "\u0482123456789abcdef",
276 "0\u048223456789abcdef",
277 "01\u04823456789abcdef",
278 "012\u0482456789abcdef",
279 "0123\u048256789abcdef",
280 "01234\u04826789abcdef",
281 "012345\u0482789abcdef",
282 "0123456\u048289abcdef",
283 "01234567\u04829abcdef",
284 "012345678\u0482abcdef",
285 "0123456789\u0482bcdef",
286 "0123456789a\u0482cdef",
287 "0123456789ab\u0482def",
288 "0123456789abc\u0482ef",
289 "0123456789abcd\u0482f",
290 "0123456789abcde\u0482",
291 // Category 9, ASCII strings:
292 // "\u0489" + "0123456789abcdef".substring(1, index + 1)
293 "\u0489",
294 "\u04891",
295 "\u048912",
296 "\u0489123",
297 "\u04891234",
298 "\u048912345",
299 "\u0489123456",
300 "\u04891234567",
301 "\u048912345678",
302 "\u0489123456789",
303 "\u0489123456789a",
304 "\u0489123456789ab",
305 "\u0489123456789abc",
306 "\u0489123456789abcd",
307 "\u0489123456789abcde",
308 "\u0489123456789abcdef",
309 };
310 int length = strings.length;
311 Assert.assertEquals(1 + 16 * 10, length);
312 for (int i = 0; i != length; ++i) {
313 String lhs = strings[i];
314 for (int j = 0; j != length; ++j) {
315 String rhs = strings[j];
316 int result = $noinline$compareTo(lhs, rhs);
317 final int expected;
318 if (i == 0 || j == 0 || i == j) {
319 // One of the strings is empty or the strings are the same.
320 expected = lhs.length() - rhs.length();
321 } else {
322 int i_category = (i - 1) / 16;
323 int i_index = (i - 1) % 16;
324 int j_category = (j - 1) / 16;
325 int j_index = (j - 1) % 16;
326 int min_ij_index = (i_index < j_index) ? i_index : j_index;
327 if (i_category == j_category) {
328 switch (i_category) {
329 case 0: case 3: case 6: case 9:
330 // Differs in length.
331 expected = lhs.length() - rhs.length();
332 break;
333 case 1: case 2: case 4: case 5: case 7: case 8:
334 // Differs in charAt(min_ij_index).
335 expected = lhs.charAt(min_ij_index) - rhs.charAt(min_ij_index);
336 break;
337 default: throw new Error("Unexpected category.");
338 }
339 } else if (i_category == 3 || i_category == 6 || i_category == 9 ||
340 j_category == 3 || j_category == 6 || j_category == 9) {
341 // In these categories, charAt(0) differs from other categories' strings.
342 expected = lhs.charAt(0) - rhs.charAt(0);
343 } else if (// Category 0 string is a prefix to any longer string in
344 // remaining categories.
345 (i_category == 0 && i_index < j_index) ||
346 (j_category == 0 && j_index < i_index) ||
347 // Category 2 string is a prefix to category 3 string at the same
348 // index. Similar for categories 4 and 5 and also 7 and 8.
349 // This includes matching last strings of these pairs of categories.
350 (i_index == j_index &&
351 ((i_category == 1 && j_category == 2) ||
352 (i_category == 2 && j_category == 1) ||
353 (i_category == 4 && j_category == 5) ||
354 (i_category == 5 && j_category == 4) ||
355 (i_category == 7 && j_category == 8) ||
356 (i_category == 8 && j_category == 7)))) {
357 // Differs in length.
358 expected = lhs.length() - rhs.length();
359 } else {
360 // The remaining cases differ in charAt(min_ij_index), the characters
361 // before that are "0123456789abcdef".substring(0, min_ij_index).
362 for (int k = 0; k < min_ij_index; ++k) {
363 Assert.assertEquals("0123456789abcdef".charAt(k), lhs.charAt(k));
364 Assert.assertEquals("0123456789abcdef".charAt(k), rhs.charAt(k));
365 }
366 expected = lhs.charAt(min_ij_index) - rhs.charAt(min_ij_index);
367 Assert.assertFalse(expected == 0);
368 }
369 }
370 if (expected != result) {
371 throw new Error(
372 "Mismatch at i=" + i + ", j=" + j + ", expected=" + expected +
373 ", result=" + result);
374 }
375 boolean equalsExpected =
376 (i == j) ||
377 // Last string in categories 1 and 2.
378 (i == 32 && j == 48) || (i == 48 && j == 32) ||
379 // Last string in categories 4 and 5.
380 (i == 80 && j == 96) || (i == 96 && j == 80) ||
381 // Last string in categories 7 and 8.
382 (i == 128 && j == 144) || (i == 144 && j == 128);
383 Assert.assertEquals(equalsExpected, $noinline$equals(lhs, rhs));
384 }
385 }
386
387 try {
388 $noinline$compareTo("", null);
389 Assert.fail();
390 } catch (NullPointerException expected) {
391 }
392 try {
393 $noinline$compareTo(null, "");
394 Assert.fail();
395 } catch (NullPointerException expected) {
396 }
397
398 Assert.assertFalse($noinline$equals("", null));
399 try {
400 $noinline$equals(null, "");
401 Assert.fail();
402 } catch (NullPointerException expected) {
403 }
404 }
405
406 public static void testIndexOf() {
407 String[] prefixes = {
408 "",
409 "0",
410 "01",
411 "012",
412 "0123",
413 "01234",
414 "012345",
415 "0123456",
416 "01234567",
417 "012345678",
418 "0123456789",
419 "0123456789a",
420 "0123456789ab",
421 "0123456789abc",
422 "0123456789abcd",
423 "0123456789abcdef",
424 };
425 String[] cores = {
426 "",
427 "x",
428 "xx",
429 "xxx",
430 "xxxx",
431 "xxxxx",
432 "xxxxxx",
433 "xxxxxxx",
434 "xxxxxxxx",
435 "xzx",
436 "xxzx",
437 "xxxzx",
438 "xxxxzx",
439 "xxxxxzx",
440 "xxxxxxzx",
441 "xxxxxxxzx",
442 "xxxxxxxxzx",
443 "\u0440",
444 "\u0440\u0440",
445 "\u0440\u0440\u0440",
446 "\u0440\u0440\u0440\u0440",
447 "\u0440\u0440\u0440\u0440\u0440",
448 "\u0440\u0440\u0440\u0440\u0440\u0440",
449 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440",
450 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440\u0440",
451 "\u0440z\u0440",
452 "\u0440\u0440z\u0440",
453 "\u0440\u0440\u0440z\u0440",
454 "\u0440\u0440\u0440\u0440z\u0440",
455 "\u0440\u0440\u0440\u0440\u0440z\u0440",
456 "\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
457 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
458 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100459 "\u0000",
460 "\u0000\u0000",
461 "\u0000\u0000\u0000",
462 "\u0000\u0000\u0000\u0000",
463 "\u0000\u0000\u0000\u0000\u0000",
464 "\u0000\u0000\u0000\u0000\u0000\u0000",
465 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
466 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
467 "\u0000z\u0000",
468 "\u0000\u0000z\u0000",
469 "\u0000\u0000\u0000z\u0000",
470 "\u0000\u0000\u0000\u0000z\u0000",
471 "\u0000\u0000\u0000\u0000\u0000z\u0000",
472 "\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
473 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
474 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100475 };
476 String[] suffixes = {
477 "",
478 "y",
479 "yy",
480 "yyy",
481 "yyyy",
482 "yyyyy",
483 "yyyyyy",
484 "yyyyyyy",
485 "yyyyyyyy",
486 "\u0441",
487 "y\u0441",
488 "yy\u0441",
489 "yyy\u0441",
490 "yyyy\u0441",
491 "yyyyy\u0441",
492 "yyyyyy\u0441",
493 "yyyyyyy\u0441",
494 "yyyyyyyy\u0441",
495 };
496 for (String p : prefixes) {
497 for (String c : cores) {
498 for (String s : suffixes) {
499 String full = p + c + s;
500 int expX = (c.isEmpty() || c.charAt(0) != 'x') ? -1 : p.length();
501 int exp0440 = (c.isEmpty() || c.charAt(0) != '\u0440') ? -1 : p.length();
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100502 int exp0000 = (c.isEmpty() || c.charAt(0) != '\u0000') ? -1 : p.length();
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100503 Assert.assertEquals(expX, $noinline$indexOf(full, 'x'));
504 Assert.assertEquals(exp0440, $noinline$indexOf(full, '\u0440'));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100505 Assert.assertEquals(exp0000, $noinline$indexOf(full, '\u0000'));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100506 Assert.assertEquals(expX, $noinline$indexOf(full, 'x', -1));
507 Assert.assertEquals(exp0440, $noinline$indexOf(full, '\u0440', -1));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100508 Assert.assertEquals(exp0000, $noinline$indexOf(full, '\u0000', -1));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100509 Assert.assertEquals(-1, $noinline$indexOf(full, 'x', full.length() + 1));
510 Assert.assertEquals(-1, $noinline$indexOf(full, '\u0440', full.length() + 1));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100511 Assert.assertEquals(-1, $noinline$indexOf(full, '\u0000', full.length() + 1));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100512 for (int from = 0; from != full.length(); ++from) {
513 final int eX;
514 final int e0440;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100515 final int e0000;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100516 if (from <= p.length()) {
517 eX = expX;
518 e0440 = exp0440;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100519 e0000 = exp0000;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100520 } else if (from >= p.length() + c.length()) {
521 eX = -1;
522 e0440 = -1;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100523 e0000 = -1;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100524 } else if (full.charAt(from) == 'z') {
525 eX = (full.charAt(from + 1) != 'x') ? -1 : from + 1;
526 e0440 = (full.charAt(from + 1) != '\u0440') ? -1 : from + 1;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100527 e0000 = (full.charAt(from + 1) != '\u0000') ? -1 : from + 1;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100528 } else {
529 eX = (full.charAt(from) != 'x') ? -1 : from;
530 e0440 = (full.charAt(from) != '\u0440') ? -1 : from;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100531 e0000 = (full.charAt(from) != '\u0000') ? -1 : from;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100532 }
533 Assert.assertEquals(eX, $noinline$indexOf(full, 'x', from));
534 Assert.assertEquals(e0440, $noinline$indexOf(full, '\u0440', from));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100535 Assert.assertEquals(e0000, $noinline$indexOf(full, '\u0000', from));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100536 }
537 }
538 }
539 }
540 }
541
542 public static int $noinline$compareTo(String lhs, String rhs) {
543 if (doThrow) { throw new Error(); }
544 return lhs.compareTo(rhs);
545 }
546
547 public static boolean $noinline$equals(String lhs, String rhs) {
548 if (doThrow) { throw new Error(); }
549 return lhs.equals(rhs);
550 }
551
552 public static int $noinline$indexOf(String lhs, int ch) {
553 if (doThrow) { throw new Error(); }
554 return lhs.indexOf(ch);
555 }
556
557 public static int $noinline$indexOf(String lhs, int ch, int fromIndex) {
558 if (doThrow) { throw new Error(); }
559 return lhs.indexOf(ch, fromIndex);
560 }
561
562 public static boolean doThrow = false;
jeffhao5d1ac922011-09-29 17:41:15 -0700563}