blob: 4bff4cfcd61fe83213db90bfc7f39ffa34370006 [file] [log] [blame]
sherman4645e6c2009-03-23 09:19:23 -07001/*
lanaf3d11f62013-12-26 12:04:16 -08002 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
sherman4645e6c2009-03-23 09:19:23 -07003 * 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
serb9adafbe2013-11-12 20:24:25 +04007 * published by the Free Software Foundation.
sherman4645e6c2009-03-23 09:19:23 -07008 *
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 *
ohair2283b9d2010-05-25 15:58:33 -070019 * 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.
sherman4645e6c2009-03-23 09:19:23 -070022 */
23
24/* @test
shermand1e22412015-05-21 15:42:30 -070025 @bug 6636323 6636319 7040220 7096080 7183053 8080248
sherman4645e6c2009-03-23 09:19:23 -070026 @summary Test if StringCoding and NIO result have the same de/encoding result
alanb902fc682010-06-23 20:19:29 +010027 * @run main/othervm/timeout=2000 TestStringCoding
sherman4645e6c2009-03-23 09:19:23 -070028 */
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 }
sherman3192c442012-07-17 19:57:31 -070071
72 testMixed(cs);
sherman4645e6c2009-03-23 09:19:23 -070073 System.out.println("done!");
74 }
75 }
76 }
77
sherman3192c442012-07-17 19:57:31 -070078 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
sherman4645e6c2009-03-23 09:19:23 -0700127 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();
sherman3192c442012-07-17 19:57:31 -0700152
sherman4645e6c2009-03-23 09:19:23 -0700153 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"))) {
sherman876b6be2011-11-07 13:46:02 -0800164 if (cs.name().equals("UTF-8") || // utf8 handles surrogates
sherman3192c442012-07-17 19:57:31 -0700165 cs.name().equals("CESU-8")) // utf8 handles surrogates
sherman85e6ff52011-05-02 11:42:52 -0700166 return;
sherman4645e6c2009-03-23 09:19:23 -0700167 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());
sherman3192c442012-07-17 19:57:31 -0700190 /* 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.
sherman4645e6c2009-03-23 09:19:23 -0700193 ba = new byte[str.length() - 1];
194 n = cae.encode(str.toCharArray(), 0, str.length(), ba);
sherman3192c442012-07-17 19:57:31 -0700195 if (n != 7 || !"abABABc".equals(new String(ba, 0, n, cs.name()))) {
sherman4645e6c2009-03-23 09:19:23 -0700196 throw new RuntimeException("encode4(surrogates) failed -> "
197 + cs.name());
sherman3192c442012-07-17 19:57:31 -0700198 }
199 */
sherman4645e6c2009-03-23 09:19:23 -0700200 }
201
shermand1e22412015-05-21 15:42:30 -0700202 //encode mappable surrogates for hkscs
203 if (cs.name().equals("Big5-HKSCS") || cs.name().equals("x-MS950-HKSCS")) {
204 String str = "ab\uD840\uDD0Ccd";
205 byte[] expected = new byte[] {(byte)'a', (byte)'b',
206 (byte)0x88, (byte)0x45, (byte)'c', (byte)'d' };
207 if (!Arrays.equals(str.getBytes(cs.name()), expected) ||
208 !Arrays.equals(str.getBytes(cs), expected)) {
209 throw new RuntimeException("encode(surrogates) failed -> "
210 + cs.name());
211 }
212 }
sherman4645e6c2009-03-23 09:19:23 -0700213 }
214
215 static class PermissiveSecurityManger extends SecurityManager {
216 @Override public void checkPermission(java.security.Permission p) {}
217 }
218}