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 /**
25  * @test
26  * @bug      4114080 8186803
27  * @summary  Make sure the euro converters, which are derived from
28  * existing converters, only differ from their parents at the expected
29  * code point.
30  * @modules jdk.charsets
31  */
32 
33 import java.text.*;
34 import java.util.*;
35 import java.io.*;
36 
37 /* Author: Alan Liu
38  * 7/14/98
39  */
40 public class EuroConverter {
main(String args[])41     public static void main(String args[]) throws Exception {
42         boolean pass = true;
43         char[] map = new char[256]; // map for the encoding
44         byte[] bytes = new byte[1]; // scratch
45         char[] chars = new char[1]; // scratch
46         for (int i=0; i<DATA.length; ) {
47             String euroEnc = DATA[i++];
48             String parentEnc = DATA[i++];
49             System.out.println("Checking encoder " + euroEnc + " against " + parentEnc);
50             String currentEnc = parentEnc;
51 
52             try {
53                 // Fill map with parent values
54                 for (int j=-128; j<128; ++j) {
55                     bytes[0] = (byte)j;
56                     char parentValue = new String(bytes, parentEnc).charAt(0);
57                     // NOTE: 0x25 doesn't round trip on the EBCDIC code pages,
58                     // so we don't check that code point in the sanity check.
59                     if (j != 0x0025) {
60                         chars[0] = parentValue;
61                         int parentRoundTrip = new String(chars).getBytes(parentEnc)[0];
62                         // This is a sanity check -- we aren't really testing the parent
63                         // encoder here.
64                         if (parentRoundTrip != j) {
65                             pass = false;
66                             System.out.println("Error: Encoder " + parentEnc +
67                                            " fails round-trip: " + j +
68                                            " -> \\u" + Integer.toHexString(parentValue) +
69                                            " -> " + parentRoundTrip);
70                         }
71                     }
72                     map[(j+0x100)&0xFF] = parentValue;
73                 }
74 
75                 // Modify map with new expected values.  Each pair has code point, parent value, euro value.
76                 // Terminated by null.
77                 while (DATA[i] != null) {
78                     int codePoint = Integer.valueOf(DATA[i++], 16).intValue();
79                     char expectedParentValue = DATA[i++].charAt(0);
80                     char expectedEuroValue = DATA[i++].charAt(0);
81                     // This is a sanity check -- we aren't really testing the parent
82                     // encoder here.
83                     if (map[codePoint] != expectedParentValue) {
84                         pass = false;
85                         System.out.println("Error: Encoder " + parentEnc +
86                                            " " + Integer.toHexString(codePoint) + " -> \\u" +
87                                            Integer.toHexString(map[codePoint]) + ", expected \\u" +
88                                            Integer.toHexString(expectedParentValue));
89                     }
90                     // Fill in new expected value
91                     map[codePoint] = expectedEuroValue;
92                 }
93                 ++i; // Skip over null at end of set
94 
95                 // Now verify the euro encoder
96                 currentEnc = euroEnc;
97                 for (int j=-128; j<128; ++j) {
98                     bytes[0] = (byte)j;
99                     char euroValue = new String(bytes, euroEnc).charAt(0);
100                     chars[0] = euroValue;
101                     // NOTE: 0x25 doesn't round trip on the EBCDIC code pages,
102                     // so we don't check that code point in the sanity check.
103                     if (j != 0x0025) {
104                         int euroRoundTrip = new String(chars).getBytes(euroEnc)[0];
105                         if (euroRoundTrip != j) {
106                             pass = false;
107                             System.out.println("Error: Encoder " + euroEnc +
108                                            " fails round-trip at " + j);
109                         }
110                     }
111                     // Compare against the map
112                     if (euroValue != map[(j+0x100)&0xFF]) {
113                         pass = false;
114                         System.out.println("Error: Encoder " + euroEnc +
115                                            " " + Integer.toHexString((j+0x100)&0xFF) + " -> \\u" +
116                                            Integer.toHexString(euroValue) + ", expected \\u" +
117                                            Integer.toHexString(map[(j+0x100)&0xFF]));
118                     }
119                 }
120             } catch (UnsupportedEncodingException e) {
121                 System.out.println("Unsupported encoding " + currentEnc);
122                 pass = false;
123                 while (i < DATA.length && DATA[i] != null) ++i;
124                 ++i; // Skip over null
125             }
126         }
127         if (!pass) {
128             throw new RuntimeException("Bug 4114080 - Euro encoder test failed");
129         }
130     }
131     static String[] DATA = {
132         // New converter, parent converter, [ code point that changed, parent code point value,
133         // euro code point value ], null
134         // Any number of changed code points may be specified, including zero.
135         "ISO8859_15_FDIS", "ISO8859_1",
136             "A4", "\u00A4", "\u20AC",
137             "A6", "\u00A6", "\u0160",
138             "A8", "\u00A8", "\u0161",
139             "B4", "\u00B4", "\u017D",
140             "B8", "\u00B8", "\u017E",
141             "BC", "\u00BC", "\u0152",
142             "BD", "\u00BD", "\u0153",
143             "BE", "\u00BE", "\u0178",
144             null,
145         // 923 is IBM's name for ISO 8859-15; make sure they're identical
146         "Cp923", "ISO8859_15_FDIS", null,
147         "Cp858", "Cp850", "D5", "\u0131", "\u20AC", null,
148         "Cp1140", "Cp037", "9F", "\u00A4", "\u20AC", null,
149         "Cp1141", "Cp273", "9F", "\u00A4", "\u20AC", null,
150         "Cp1142", "Cp277", "5A", "\u00A4", "\u20AC", null,
151         "Cp1143", "Cp278", "5A", "\u00A4", "\u20AC", null,
152         "Cp1144", "Cp280", "9F", "\u00A4", "\u20AC", null,
153         "Cp1145", "Cp284", "9F", "\u00A4", "\u20AC", null,
154         "Cp1146", "Cp285", "9F", "\u00A4", "\u20AC", null,
155         "Cp1147", "Cp297", "9F", "\u00A4", "\u20AC", null,
156         "Cp1148", "Cp500", "9F", "\u00A4", "\u20AC", null,
157         "Cp1149", "Cp871", "9F", "\u00A4", "\u20AC", null,
158     };
159 }
160