1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2019, BELLSOFT. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 26 package compiler.intrinsics.string.indexof; 27 28 // Basic class for indexof testing. Check all possible pattern size and index 29 // up to source string size specified via command line. Expected to run with 30 // different source size according to platform indexof implementation specifics. 31 // Run with Xcomp, because execution until compilation can take too long in case 32 // of large argument. 33 public class TestIndexOf { 34 private static final char PADDING = 'A'; 35 36 public static void main(String[] args) { 37 TestIndexOf test = new TestIndexOf(); 38 int sourceSize = Integer.parseInt(args[0]); 39 test.checkForSourceSizeUU(sourceSize); // UTF-16 source, UTF-16 pattern 40 test.checkForSourceSizeUL(sourceSize); // UTF-16 source, Latin1 pattern 41 test.checkForSourceSizeLL(sourceSize); // Latin1 source, Latin1 pattern 42 } 43 44 // check UTF-16 pattern search in UTF-16 source using specifiec source size 45 private void checkForSourceSizeUU(int sourceSize) { 46 String strUTF16 = generateSourceString(sourceSize, /* isUTF16 = */ true); 47 for (int patternSize = 1; patternSize < sourceSize; patternSize++) { 48 String uniquePatternUTF16 = generatePatternString(patternSize, 49 /* isUTF16 */ true, /* usePadding = */ false); 50 String partialMatchPatternUTF16 = generatePatternString(patternSize, 51 /* isUTF16 */ true, /* usePadding = */ true); 52 for (int index = -1; index <= sourceSize-patternSize; index++) { 53 testCase(strUTF16, uniquePatternUTF16, index); // no partial match 54 testCase(strUTF16, partialMatchPatternUTF16, index); // has partial match 55 } 56 } 57 } 58 59 // check Latin1 pattern search in UTF-16 source using specifiec source size 60 private void checkForSourceSizeUL(int sourceSize) { 61 String strUTF16 = generateSourceString(sourceSize, /* isUTF16 = */ true); 62 for (int patternSize = 1; patternSize < sourceSize; patternSize++) { 63 String uniquePatternLatin1 = generatePatternString(patternSize, 64 /* isUTF16 */ false, /* usePadding = */ false); 65 String partialMatchPatternLatin1 = generatePatternString(patternSize, 66 /* isUTF16 */ false, /* usePadding = */ true); 67 for (int index = -1; index <= sourceSize-patternSize; index++) { 68 testCase(strUTF16, uniquePatternLatin1, index); // no partial match 69 testCase(strUTF16, partialMatchPatternLatin1, index); // has partial match 70 } 71 } 72 } 73 74 // check Latin1 pattern search in Latin1 source using specifiec source size 75 private void checkForSourceSizeLL(int sourceSize) { 76 String strLatin1 = generateSourceString(sourceSize, /* isUTF16 = */ false); 77 for (int patternSize = 1; patternSize < sourceSize; patternSize++) { 78 String uniquePatternLatin1 = generatePatternString(patternSize, 79 /* isUTF16 */ false, /* usePadding = */ false); 80 String partialMatchPatternLatin1 = generatePatternString(patternSize, 81 /* isUTF16 */ false, /* usePadding = */ true); 82 for (int index = -1; index <= sourceSize-patternSize; index++) { 83 testCase(strLatin1, uniquePatternLatin1, index); // no partial match 84 testCase(strLatin1, partialMatchPatternLatin1, index); // has partial match 85 } 86 } 87 } 88 89 private void testCase(String srcTemplate, String patternString, int index) { 90 String searchString = srcTemplate; 91 if (index != -1) { 92 // case when srcTemplate and patternString length is equal, 93 // encoding is UTF16(src) and Latin1(pattern) and expected match 94 // index is 0 will trigger case of Lating1 source string. 95 searchString = srcTemplate.substring(0, index) + patternString 96 + srcTemplate.substring(index + patternString.length()); 97 } 98 int result = searchString.indexOf(patternString); 99 if (result != index) { 100 throw new AssertionError("Unexpected index: " + result 101 + " searching '" + patternString + "' in '" + searchString); 102 } 103 } 104 105 // create string with given length and Latin1/UTF16 encoding. Consists 106 // mostly of PADDING char. 107 private String generateSourceString(int length, boolean isUTF16) { 108 char[] raw = new char[length]; 109 for (int i = 0; i < length; i++) { 110 raw[i] = PADDING; 111 } 112 if (isUTF16) { 113 raw[0] = '\uCAFE'; 114 raw[length - 1] = '\uBABE'; 115 } 116 return new String(raw); 117 } 118 119 // create pattern string with given length, Latin1/UTF16 encoding and 120 // consisting mostly of PADDING chars in case of usePadding is true. 121 private String generatePatternString(int length, boolean isUTF16, boolean usePadding) { 122 char[] raw = new char[length]; 123 char baseChar = isUTF16 ? '\uABCD' : 'C'; 124 for (int i = 0; i < length - 1; i++) { 125 raw[i] = usePadding ? PADDING : (char)(baseChar % 40); 126 } 127 raw[length - 1] = isUTF16 ? '\uBEEF' : 'B'; 128 return new String(raw); 129 } 130 }