1 /* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. 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 17 package libcore.java.nio.charset; 18 19 import java.nio.ByteBuffer; 20 import java.nio.CharBuffer; 21 import java.nio.charset.CharacterCodingException; 22 import java.nio.charset.Charset; 23 import java.nio.charset.CharsetDecoder; 24 import java.nio.charset.CharsetEncoder; 25 import java.nio.charset.CodingErrorAction; 26 import junit.framework.TestCase; 27 28 /** 29 * Super class for concrete charset test suites. 30 */ 31 public abstract class OldCharset_AbstractTest extends TestCase { 32 33 static String charsetName; 34 static private Charset charset; 35 static CharsetDecoder decoder; 36 static CharsetEncoder encoder; 37 38 static final int[] codes = Charset_TestGenerator.codes; 39 40 static final char[] chars = new char[codes.length]; // Is filled with 41 // contents of codes. 42 43 static char[] testChars; 44 static byte[] testBytes; 45 theseChars(int... codes)46 static char[] theseChars (int... codes) { 47 char[] chars = new char[codes.length]; 48 for (int i = 0; i < codes.length; i++) chars[i] = (char) codes[i]; 49 return chars; 50 } 51 theseBytes(int... codes)52 static byte[] theseBytes (int... codes) { 53 byte[] bytes = new byte[codes.length]; 54 for (int i = 0; i < codes.length; i++) bytes[i] = (byte) codes[i]; 55 return bytes; 56 } 57 58 59 @Override setUp()60 protected void setUp() throws Exception { 61 charset = charset.forName(charsetName); 62 decoder = charset.newDecoder(); 63 encoder = charset.newEncoder(); 64 super.setUp(); 65 } 66 67 @Override tearDown()68 protected void tearDown() throws Exception { 69 super.tearDown(); 70 } 71 test_nameMatch()72 public void test_nameMatch () { 73 assertEquals("Name of charset must match!", charsetName, charset.name()); 74 } 75 test_dumpEncodableChars()76 public void test_dumpEncodableChars () { 77 if (testChars == null) return; 78 if (testChars.length > 0) return; 79 System.out.format("\ntest_dumpEncodableChars() for name %s => %s (class = %s)\n", 80 charsetName, charset.name(), getClass().getName()); 81 Charset_TestGenerator.Dumper out = new Charset_TestGenerator.Dumper1(16); 82 int code = 0; 83 while (code < 256) { 84 while (!encoder.canEncode((char) code)) code ++; 85 if (code < 65536) { 86 out.consume(code); 87 code += 1; 88 } 89 } 90 while (code < 65536) { 91 while (!encoder.canEncode((char) code)) code ++; 92 if (code < 65536) { 93 out.consume(code); 94 code += 20; 95 } 96 } 97 System.out.println(); 98 System.out.println("Encodable Chars dumped for Test Class " + getClass().getName()); 99 fail("Encodable Chars dumped for Test Class " + getClass().getName()); 100 } 101 test_dumpEncoded()102 public void test_dumpEncoded () throws CharacterCodingException { 103 if (testChars == null) return; 104 if (testChars.length == 0) return; 105 if (testBytes != null) return; 106 System.out.format("\ntest_dumpEncoded() for name %s => %s (class = %s)\n", 107 charsetName, charset.name(), getClass().getName()); 108 Charset_TestGenerator.Dumper out = new Charset_TestGenerator.Dumper1(); 109 CharBuffer inputCB = CharBuffer.wrap(testChars); 110 ByteBuffer outputBB; 111 encoder.onUnmappableCharacter(CodingErrorAction.REPORT); 112 outputBB = encoder.encode(inputCB); 113 outputBB.rewind(); 114 while (outputBB.hasRemaining()) { 115 out.consume(outputBB.get() & 0xff); 116 } 117 System.out.println(); 118 System.out.println("Encoded Bytes dumped for Test Class " + getClass().getName()); 119 fail("Encoded Bytes dumped for Test Class " + getClass().getName()); 120 } 121 122 decode(byte[] input, char[] expectedOutput)123 static void decode (byte[] input, char[] expectedOutput) throws CharacterCodingException { 124 ByteBuffer inputBB = ByteBuffer.wrap(input); 125 decoder.onMalformedInput(CodingErrorAction.REPORT); 126 CharBuffer outputCB = decoder.decode(inputBB); 127 outputCB.rewind(); 128 assertEqualChars(expectedOutput, outputCB); 129 } 130 test_Decode()131 public void test_Decode () throws CharacterCodingException { 132 decode(testBytes, testChars); 133 } 134 test_Encode()135 public void test_Encode () throws CharacterCodingException { 136 CharBuffer inputCB = CharBuffer.wrap(testChars); 137 ByteBuffer outputBB; 138 encoder.onUnmappableCharacter(CodingErrorAction.REPORT); 139 outputBB = encoder.encode(inputCB); 140 outputBB.rewind(); 141 // assertTrue("Encoded bytes must match!", 142 // Arrays.equals(testBytes, outputBB.array())); 143 assertEqualBytes("Encoded bytes must match!", testBytes, outputBB); 144 } 145 146 NNtest_CodecDynamicIndividuals()147 public void NNtest_CodecDynamicIndividuals () throws CharacterCodingException { 148 encoder.onUnmappableCharacter(CodingErrorAction.REPORT); 149 decoder.onMalformedInput(CodingErrorAction.REPORT); 150 151 for (int code = 32; code <= 65533; code ++) { 152 if (encoder.canEncode((char) code)) { 153 // inputCB.rewind(); 154 CharBuffer inputCB = CharBuffer.allocate(1); 155 inputCB.put((char) code); 156 inputCB.rewind(); 157 ByteBuffer intermediateBB = encoder.encode(inputCB); 158 inputCB.rewind(); 159 intermediateBB.rewind(); 160 try { 161 CharBuffer outputCB = decoder.decode(intermediateBB); 162 outputCB.rewind(); 163 assertEqualCBs("decode(encode(A)) must be identical with A = " + code, 164 inputCB, outputCB); 165 if (code == 165) { 166 outputCB.rewind(); 167 System.out.println("WOW:" + outputCB.get()); 168 } 169 } catch (CharacterCodingException e) { 170 fail("failed to decode(encode(" + code + "))"); 171 } 172 } 173 } 174 } 175 test_CodecDynamic()176 public void test_CodecDynamic () throws CharacterCodingException { 177 encoder.onUnmappableCharacter(CodingErrorAction.REPORT); 178 decoder.onMalformedInput(CodingErrorAction.REPORT); 179 CharBuffer inputCB = CharBuffer.allocate(65536); 180 for (int code = 32; code <= 65533; ++code) { 181 // icu4c seems to accept any surrogate as a sign that "more is coming", 182 // even for charsets like US-ASCII. http://b/10310751 183 if (code >= 0xd800 && code <= 0xdfff) { 184 continue; 185 } 186 if (encoder.canEncode((char) code)) { 187 inputCB.put((char) code); 188 } 189 } 190 inputCB.rewind(); 191 ByteBuffer intermediateBB = encoder.encode(inputCB); 192 inputCB.rewind(); 193 intermediateBB.rewind(); 194 CharBuffer outputCB = decoder.decode(intermediateBB); 195 outputCB.rewind(); 196 assertEqualCBs("decode(encode(A)) must be identical with A!", 197 inputCB, outputCB); 198 } 199 assertEqualCBs(String msg, CharBuffer expectedCB, CharBuffer actualCB)200 static void assertEqualCBs (String msg, CharBuffer expectedCB, CharBuffer actualCB) { 201 boolean match = true; 202 boolean lenMatch = true; 203 char expected, actual; 204 int len = actualCB.length(); 205 if (expectedCB.length() != len) { 206 lenMatch = false; 207 if (expectedCB.length() < len) len = expectedCB.length(); 208 } 209 for (int i = 0; i < len; i++) { 210 expected = expectedCB.get(); 211 actual = actualCB.get(); 212 if (actual != expected) { 213 String detail = String.format( 214 "Mismatch at index %d: %d instead of expected %d.\n", 215 i, (int) actual, (int) expected); 216 match = false; 217 fail(msg + ": " + detail); 218 } 219 // else { 220 // System.out.format("Match index %d: %d = %d\n", 221 // i, (int) actual[i], (int) expected[i]); 222 // } 223 } 224 assertTrue(msg, match); 225 assertTrue(msg + "(IN LENGTH ALSO!)", lenMatch); 226 // assertTrue(msg, Arrays.equals(actual, expected)); 227 } 228 assertEqualChars(char[] expected, CharBuffer actualCB)229 static void assertEqualChars(char[] expected, CharBuffer actualCB) { 230 assertEquals(expected.length, actualCB.length()); 231 for (int i = 0; i < actualCB.length(); ++i) { 232 char actual = actualCB.get(); 233 if (actual != expected[i]) { 234 String detail = String.format("Mismatch at index %d: %d instead of expected %d.\n", 235 i, (int) actual, (int) expected[i]); 236 fail(detail); 237 } 238 } 239 } 240 assertEqualBytes(String msg, byte[] expected, ByteBuffer actualBB)241 static void assertEqualBytes (String msg, byte[] expected, ByteBuffer actualBB) { 242 boolean match = true; 243 boolean lenMatch = true; 244 byte actual; 245 int len = actualBB.remaining(); 246 if (expected.length != len) { 247 lenMatch = false; 248 if (expected.length < len) len = expected.length; 249 } 250 for (int i = 0; i < len; i++) { 251 actual = actualBB.get(); 252 if (actual != expected[i]) { 253 String detail = String.format( 254 "Mismatch at index %d: %d instead of expected %d.\n", 255 i, actual & 0xff, expected[i] & 0xff); 256 match = false; 257 fail(msg + ": " + detail); 258 } 259 } 260 assertTrue(msg, match); 261 assertTrue(msg + "(IN LENGTH ALSO!)", lenMatch); 262 } 263 264 265 static abstract class CodesGenerator { 266 int row = 0, col = 0; 267 consume(int code)268 abstract void consume(int code); 269 isAccepted(int code)270 boolean isAccepted(int code) { 271 return Character.isLetterOrDigit(code); 272 } 273 } 274 275 } 276