1 /* 2 * Copyright (c) 2008, 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 4403848 6348426 6407730 26 @summary Check correctness of the UTF-16 converter in all its flavors 27 */ 28 29 import java.io.IOException; 30 import java.nio.BufferOverflowException; 31 import java.nio.*; 32 import java.nio.charset.*; 33 34 public class TestUTF_16 { 35 testDecode(String charset, String expected, byte[] input)36 private static void testDecode(String charset, 37 String expected, 38 byte[] input) 39 throws Exception 40 { 41 String out = new String(input, charset); 42 if (!out.equals(expected)) { 43 failureReport (out, expected); 44 throw new Exception("UTF_16 Decoding test failed " + charset); 45 } 46 } 47 testEncode(String charset, String input, byte[] expected)48 private static void testEncode(String charset, 49 String input, 50 byte[] expected) 51 throws Exception 52 { 53 byte[] testBytes = input.getBytes(charset); 54 for (int i = 0; i< expected.length; i++) 55 if (testBytes[i] != expected[i]) 56 throw new Exception("UTF_16 Encoding test failed " + charset); 57 58 } 59 warn(String s)60 private static void warn(String s) { 61 System.err.println("FAILED Test 4403848 UTF-16" + 62 s) ; 63 } 64 failureReport(String testStr, String expected)65 private static void failureReport(String testStr, 66 String expected) { 67 68 System.err.println ("Expected Characters:"); 69 for (int i = 0; i < expected.length() ; i++) { 70 warn("expected char[" + i + "] : " + 71 Integer.toHexString((int)expected.charAt(i)) + 72 "obtained char[" + i + "] : " + 73 Integer.toHexString((int)testStr.charAt(i))); 74 } 75 } 76 77 /* 78 private static void checkResult(char[] expected, 79 String testStr, 80 String testName) 81 throws Exception 82 { 83 if (testStr.length() != expected.length) 84 failureReport(testStr, expected); 85 86 for (int i = 0; i < testStr.length(); i++) { 87 if (testStr.charAt(i) != expected[i]) { 88 failureReport(testStr, expected); 89 throw new Exception ("REGTEST TestUTF16 failed: " 90 + testName); 91 } 92 } 93 System.err.println ("Test " + testName + " PASSED"); 94 return; 95 } 96 */ 97 test()98 private static void test() throws Exception { 99 100 // Tests: Check decoding of UTF-16. 101 // Ensures correct endian polarity 102 // of the decoders and appropriate 103 // interpretation of BOM bytes where 104 // they are required. 105 106 // Test 1: BigEndian UTF-16 Decoding 107 108 testDecode("UTF_16BE", "\u0092\u0093", 109 new byte[] { (byte) 0x00, (byte) 0x92, 110 (byte) 0x00, (byte) 0x93 }); 111 112 // Test 1a: BigEndian UTF-16 Decoding. BOM bytes provided. 113 testDecode("UTF_16BE", "\ufeff\u0092\u0093", 114 new byte[] { (byte) 0xfe, (byte) 0xff, 115 (byte) 0x00, (byte) 0x92, 116 (byte) 0x00, (byte) 0x93 }); 117 118 testDecode("UTF_16LE", "\u9200\u9300", 119 new byte[] { (byte) 0x00, (byte) 0x92, 120 (byte) 0x00, (byte) 0x93 }); 121 122 // Test 2a: LittleEndian UTF-16 Decoding, BOM bytes provided. 123 testDecode("UTF_16LE", "\ufeff\u9200\u9300", 124 new byte[] { (byte) 0xff, (byte) 0xfe, 125 (byte) 0x00, (byte) 0x92, 126 (byte) 0x00, (byte) 0x93 }); 127 128 // Test 3: UTF-16 (with mandatory byte order mark) Decoding 129 130 testDecode("UTF-16", "\u9200\u9300", 131 new byte[] { (byte) 0xfe, (byte) 0xff, 132 (byte) 0x92, (byte) 0x00, 133 (byte) 0x93, (byte) 0x00 }); 134 135 136 // Test 3a: UTF-16 BOM omitted. This should decode OK. 137 testDecode("UTF-16", "\u9200\u9300", 138 new byte[] { (byte) 0x92, (byte) 0x00, 139 (byte) 0x93, (byte) 0x00 }); 140 141 142 // Test 4: encoding using UTF-16 143 // BOM must be emitted when encoding and must be BigEndian. 144 145 testEncode("UTF-16", "\u0123", 146 new byte[] { (byte) 0xfe, (byte) 0xff, 147 (byte) 0x01, (byte) 0x23 }); 148 149 // Test 5: 150 if (CoderResult.OVERFLOW != 151 Charset.forName("UTF_16") 152 .newDecoder() 153 .decode((ByteBuffer.allocate(4) 154 .put(new byte[] 155 {(byte)0xd8,(byte)0x00, 156 (byte)0xdc,(byte)0x01}) 157 .flip()), 158 CharBuffer.allocate(1), 159 true)) { 160 throw new Exception ("REGTEST TestUTF16 Overflow test failed"); 161 } 162 163 // Test 6: decoding using UTF_16LE_BOM/UnicodeLittle 164 // UnicodeLittle should accept non-BOM byte sequence 165 166 testDecode("UnicodeLittle", "Arial", 167 new byte[] { 'A', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0}); 168 169 System.err.println ("\nPASSED UTF-16 encoder test"); 170 171 // Reversed BOM in middle of stream Negative test. 172 173 /* 174 boolean caughtException = false; 175 try { 176 String out = new String(new byte[] {(byte)0x00, 177 (byte)0x92, 178 (byte)0xff, 179 (byte)0xfe}, 180 "UTF-16"); 181 } catch (IOException e) { caughtException = true; } 182 183 if (caughtException == false) 184 throw new Exception ("Incorrectly parsed BOM in middle of input"); 185 */ 186 187 // Fixed included with bug 4403848 fixes buffer sizing 188 // issue due to non provision of additional 2 bytes 189 // headroom for initial BOM bytes for UTF-16 encoding. 190 System.err.println ("OVERALL PASS OF UTF-16 Test"); 191 } 192 main(String[] args)193 public static void main (String[] args) throws Exception { 194 test(); 195 } 196 } 197