TestStringCoding.java revision 8729:0242fce0f717
1/* 2 * Copyright (c) 2000, 2012, 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/* @test 25 @bug 6636323 6636319 7040220 7096080 7183053 26 @summary Test if StringCoding and NIO result have the same de/encoding result 27 * @run main/othervm/timeout=2000 TestStringCoding 28 */ 29 30import java.util.*; 31import java.nio.*; 32import java.nio.charset.*; 33 34public class TestStringCoding { 35 public static void main(String[] args) throws Throwable { 36 37 for (Boolean hasSM: new boolean[] { false, true }) { 38 if (hasSM) 39 System.setSecurityManager(new PermissiveSecurityManger()); 40 for (Charset cs: Charset.availableCharsets().values()) { 41 if ("ISO-2022-CN".equals(cs.name()) || 42 "x-COMPOUND_TEXT".equals(cs.name()) || 43 "x-JISAutoDetect".equals(cs.name())) 44 continue; 45 System.out.printf("Testing(sm=%b) " + cs.name() + "....", hasSM); 46 // full bmp first 47 char[] bmpCA = new char[0x10000]; 48 for (int i = 0; i < 0x10000; i++) { 49 bmpCA[i] = (char)i; 50 } 51 byte[] sbBA = new byte[0x100]; 52 for (int i = 0; i < 0x100; i++) { 53 sbBA[i] = (byte)i; 54 } 55 test(cs, bmpCA, sbBA); 56 // "randomed" sizes 57 Random rnd = new Random(); 58 for (int i = 0; i < 10; i++) { 59 int clen = rnd.nextInt(0x10000); 60 int blen = rnd.nextInt(0x100); 61 //System.out.printf(" blen=%d, clen=%d%n", blen, clen); 62 test(cs, Arrays.copyOf(bmpCA, clen), Arrays.copyOf(sbBA, blen)); 63 //add a pair of surrogates 64 int pos = clen / 2; 65 if ((pos + 1) < blen) { 66 bmpCA[pos] = '\uD800'; 67 bmpCA[pos+1] = '\uDC00'; 68 } 69 test(cs, Arrays.copyOf(bmpCA, clen), Arrays.copyOf(sbBA, blen)); 70 } 71 72 testMixed(cs); 73 System.out.println("done!"); 74 } 75 } 76 } 77 78 static void testMixed(Charset cs) throws Throwable { 79 CharsetDecoder dec = cs.newDecoder() 80 .onMalformedInput(CodingErrorAction.REPLACE) 81 .onUnmappableCharacter(CodingErrorAction.REPLACE); 82 CharsetEncoder enc = cs.newEncoder() 83 .onMalformedInput(CodingErrorAction.REPLACE) 84 .onUnmappableCharacter(CodingErrorAction.REPLACE); 85 List<Integer> cps = new ArrayList<>(0x10000); 86 int off = 0; 87 int cp = 0; 88 while (cp < 0x10000) { 89 if (enc.canEncode((char)cp)) { 90 cps.add(cp); 91 } 92 cp++; 93 } 94 Collections.shuffle(cps); 95 char[] bmpCA = new char[cps.size()]; 96 for (int i = 0; i < cps.size(); i++) 97 bmpCA[i] = (char)(int)cps.get(i); 98 String bmpStr = new String(bmpCA); 99 //getBytes(csn); 100 byte[] bmpBA = bmpStr.getBytes(cs.name()); 101 ByteBuffer bf = enc.reset().encode(CharBuffer.wrap(bmpCA)); 102 byte[] baNIO = new byte[bf.limit()]; 103 bf.get(baNIO, 0, baNIO.length); 104 if (!Arrays.equals(bmpBA, baNIO)) { 105 throw new RuntimeException("getBytes(csn) failed -> " + cs.name()); 106 } 107 108 //getBytes(cs); 109 bmpBA = bmpStr.getBytes(cs); 110 if (!Arrays.equals(bmpBA, baNIO)) 111 throw new RuntimeException("getBytes(cs) failed -> " + cs.name()); 112 113 //new String(csn); 114 String strSC = new String(bmpBA, cs.name()); 115 String strNIO = dec.reset().decode(ByteBuffer.wrap(bmpBA)).toString(); 116 if(!strNIO.equals(strSC)) { 117 throw new RuntimeException("new String(csn) failed -> " + cs.name()); 118 } 119 120 //new String(cs); 121 strSC = new String(bmpBA, cs); 122 if (!strNIO.equals(strSC)) 123 throw new RuntimeException("new String(cs) failed -> " + cs.name()); 124 125 } 126 127 static void test(Charset cs, char[] bmpCA, byte[] sbBA) throws Throwable { 128 String bmpStr = new String(bmpCA); 129 CharsetDecoder dec = cs.newDecoder() 130 .onMalformedInput(CodingErrorAction.REPLACE) 131 .onUnmappableCharacter(CodingErrorAction.REPLACE); 132 CharsetEncoder enc = cs.newEncoder() 133 .onMalformedInput(CodingErrorAction.REPLACE) 134 .onUnmappableCharacter(CodingErrorAction.REPLACE); 135 136 //getBytes(csn); 137 byte[] baSC = bmpStr.getBytes(cs.name()); 138 ByteBuffer bf = enc.reset().encode(CharBuffer.wrap(bmpCA)); 139 byte[] baNIO = new byte[bf.limit()]; 140 bf.get(baNIO, 0, baNIO.length); 141 if (!Arrays.equals(baSC, baNIO)) 142 throw new RuntimeException("getBytes(csn) failed -> " + cs.name()); 143 144 //getBytes(cs); 145 baSC = bmpStr.getBytes(cs); 146 if (!Arrays.equals(baSC, baNIO)) 147 throw new RuntimeException("getBytes(cs) failed -> " + cs.name()); 148 149 //new String(csn); 150 String strSC = new String(sbBA, cs.name()); 151 String strNIO = dec.reset().decode(ByteBuffer.wrap(sbBA)).toString(); 152 153 if(!strNIO.equals(strSC)) 154 throw new RuntimeException("new String(csn) failed -> " + cs.name()); 155 156 //new String(cs); 157 strSC = new String(sbBA, cs); 158 if (!strNIO.equals(strSC)) 159 throw new RuntimeException("new String(cs) failed -> " + cs.name()); 160 161 //encode unmappable surrogates 162 if (enc instanceof sun.nio.cs.ArrayEncoder && 163 cs.contains(Charset.forName("ASCII"))) { 164 if (cs.name().equals("UTF-8") || // utf8 handles surrogates 165 cs.name().equals("CESU-8")) // utf8 handles surrogates 166 return; 167 enc.replaceWith(new byte[] { (byte)'A'}); 168 sun.nio.cs.ArrayEncoder cae = (sun.nio.cs.ArrayEncoder)enc; 169 170 String str = "ab\uD800\uDC00\uD800\uDC00cd"; 171 byte[] ba = new byte[str.length() - 2]; 172 int n = cae.encode(str.toCharArray(), 0, str.length(), ba); 173 if (n != 6 || !"abAAcd".equals(new String(ba, cs.name()))) 174 throw new RuntimeException("encode1(surrogates) failed -> " 175 + cs.name()); 176 177 ba = new byte[str.length()]; 178 n = cae.encode(str.toCharArray(), 0, str.length(), ba); 179 if (n != 6 || !"abAAcd".equals(new String(ba, 0, n, 180 cs.name()))) 181 throw new RuntimeException("encode2(surrogates) failed -> " 182 + cs.name()); 183 str = "ab\uD800B\uDC00Bcd"; 184 ba = new byte[str.length()]; 185 n = cae.encode(str.toCharArray(), 0, str.length(), ba); 186 if (n != 8 || !"abABABcd".equals(new String(ba, 0, n, 187 cs.name()))) 188 throw new RuntimeException("encode3(surrogates) failed -> " 189 + cs.name()); 190 /* sun.nio.cs.ArrayDeEncoder works on the assumption that the 191 invoker (StringCoder) allocates enough output buf, utf8 192 and double-byte coder does not check the output buffer limit. 193 ba = new byte[str.length() - 1]; 194 n = cae.encode(str.toCharArray(), 0, str.length(), ba); 195 if (n != 7 || !"abABABc".equals(new String(ba, 0, n, cs.name()))) { 196 throw new RuntimeException("encode4(surrogates) failed -> " 197 + cs.name()); 198 } 199 */ 200 } 201 202 } 203 204 static class PermissiveSecurityManger extends SecurityManager { 205 @Override public void checkPermission(java.security.Permission p) {} 206 } 207} 208