Make List type safe. Remove/suppress all warnings.
[marc4j.git] / src / org / marc4j / converter / impl / CodeTableGenerator.java
1  // $Id: CodeTableGenerator.java,v 1.2 2008/10/17 06:47:06 haschart Exp $\r
2 /**\r
3  * Copyright (C) 2002 Bas Peters\r
4  *\r
5  * This file is part of MARC4J\r
6  *\r
7  * MARC4J is free software; you can redistribute it and/or\r
8  * modify it under the terms of the GNU Lesser General Public\r
9  * License as published by the Free Software Foundation; either\r
10  * version 2.1 of the License, or (at your option) any later version.\r
11  *\r
12  * MARC4J is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
15  * Lesser General Public License for more details.\r
16  *\r
17  * You should have received a copy of the GNU Lesser General Public\r
18  * License along with MARC4J; if not, write to the Free Software\r
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
20  */\r
21 \r
22 package org.marc4j.converter.impl;\r
23 \r
24 import java.io.InputStream;\r
25 import java.io.PrintStream;\r
26 import java.util.Arrays;\r
27 import java.util.HashMap;\r
28 import java.util.Iterator;\r
29 import java.util.Vector;\r
30 \r
31 /**\r
32  * Invoked at build time to generate a java source file (named CodeTableGenerated.java) \r
33  * which when compiled will implement the CodeTableInterface (primarily through switch statements)\r
34  * and which can be used be the AnselToUnicode converter instead of this class, and which will\r
35  * produce the same results as the object CodeTable.\r
36  * <br>\r
37  * The following routines are only used in the code generation process, and are not available to\r
38  * be called from within an application that uses Marc4j. \r
39  * <br>\r
40  * The routines generated for converting MARC8 multibyte characters to unicode are \r
41  * split into several routines to workaround a limitation in java that a method can only contain 64k of code when it is compiled. \r
42  * \r
43  * @author Robert Haschart\r
44  * @version $Revision: 1.2 $\r
45  *  \r
46  */\r
47 public class CodeTableGenerator extends CodeTable {\r
48 \r
49         public CodeTableGenerator(InputStream byteStream) \r
50         {\r
51                 super(byteStream);\r
52         }\r
53 \r
54     public static void main(String args[])\r
55     {\r
56         CodeTableGenerator ct = new CodeTableGenerator(CodeTable.class.getResourceAsStream("resources/codetables.xml"));\r
57         ct.dumpTableAsSwitchStatement(System.out);\r
58     }\r
59 \r
60     @SuppressWarnings("rawtypes")\r
61     private void dumpTableAsSwitchStatement(PrintStream output)\r
62     {\r
63         output.println("package org.marc4j.converter.impl;");\r
64         output.println("");\r
65         output.println("/** ");\r
66         output.println(" *  An implementation of CodeTableInterface that is used in converting MARC8");\r
67         output.println(" *  data to UTF8 data, that doesn't rely on any data files or resources or data structures");\r
68         output.println(" *  ");\r
69         output.println(" *  Warning: This file is generated by running the main routine in the file CodeTableGenerator.java ");\r
70         output.println(" *  Warning: Do not edit this file, or all edits will be lost at the next build. ");\r
71         output.println(" */" );\r
72         output.println("public class CodeTableGenerated implements CodeTableInterface {");\r
73         output.println("\tpublic boolean isCombining(int i, int g0, int g1) {");\r
74         output.println("\t\tswitch (i <= 0x7E ? g0 : g1) {");\r
75         Object combiningKeys[] = combining.keySet().toArray();\r
76         Arrays.sort(combiningKeys);\r
77         for (int combiningSel = 0; combiningSel < combiningKeys.length; combiningSel++)\r
78         {\r
79             Integer nextKey = (Integer)combiningKeys[combiningSel];\r
80             output.println("\t\t\tcase 0x"+Integer.toHexString(nextKey)+":");\r
81             Vector v = (Vector) combining.get(nextKey);\r
82             Iterator vIter = v.iterator();\r
83             if (vIter.hasNext())\r
84             {\r
85                 output.println("\t\t\t\tswitch(i) {");\r
86                 while (vIter.hasNext())\r
87                 {\r
88                     Integer vVal = (Integer)vIter.next();\r
89                     output.println("\t\t\t\t\tcase 0x"+Integer.toHexString(vVal)+":");\r
90                 }\r
91                 output.println("\t\t\t\t\t\treturn(true);");\r
92                 output.println("\t\t\t\t\tdefault:");\r
93                 output.println("\t\t\t\t\t\treturn(false);");\r
94                 output.println("\t\t\t\t}");\r
95             }\r
96             else\r
97             {\r
98                 output.println("\t\t\t\treturn(false);");\r
99             }\r
100         }\r
101         output.println("\t\t\tdefault:");\r
102         output.println("\t\t\t\treturn(false);");\r
103         output.println("\t\t\t}");\r
104         output.println("\t}");\r
105         output.println("");\r
106         output.println("\tpublic char getChar(int c, int mode) {");\r
107         output.println("\t\tint code = getCharCode(c, mode);");\r
108         output.println("\t\tif (code == -1) return((char)0);");\r
109         output.println("\t\tif (code != 0) return((char)code);");\r
110         output.println("\t\tcode = getCharCode(c < 0x80 ? c + 0x80 : c - 0x80 , mode);");\r
111         output.println("\t\treturn((char)code);");\r
112         output.println("\t}");\r
113         output.println("");\r
114         output.println("\tprivate int getCharCode(int c, int mode) {");\r
115         output.println("\t\tif (c == 0x20) return  c;");\r
116         output.println("\t\tswitch (mode) {");\r
117         Object charsetsKeys[] = charsets.keySet().toArray();\r
118         Arrays.sort(charsetsKeys);\r
119         for (int charsetSel = 0; charsetSel < charsetsKeys.length; charsetSel++)\r
120         {\r
121             Integer nextKey = (Integer)charsetsKeys[charsetSel];\r
122             output.println("\t\t\tcase 0x"+Integer.toHexString(nextKey)+":");\r
123             if (nextKey.intValue() == 0x31)\r
124             {\r
125                 output.println("\t\t\t\treturn(getMultiByteChar(c));");\r
126             }\r
127             else\r
128             {\r
129                 HashMap map = (HashMap) charsets.get(nextKey);\r
130                 Object keyArray[] = map.keySet().toArray();\r
131                 Arrays.sort(keyArray);\r
132                 output.println("\t\t\t\tswitch(c) {");\r
133                 for (int sel = 0; sel < keyArray.length; sel++)\r
134                 {\r
135                     Integer mKey = (Integer)keyArray[sel];\r
136                     Character c = (Character)map.get(mKey);\r
137                     if (c != null)\r
138                         output.println("\t\t\t\t\tcase 0x"+Integer.toHexString(mKey)+":  return(0x"+Integer.toHexString((int)c.charValue())+"); ");\r
139                     else\r
140                         output.println("\t\t\t\t\tcase 0x"+Integer.toHexString(mKey)+":  return(0); ");\r
141                 }\r
142                 output.println("\t\t\t\t\tdefault:  return(0);");\r
143                 output.println("\t\t\t\t}");\r
144             }\r
145         }\r
146         output.println("\t\t\tdefault: return(-1);  // unknown charset specified ");\r
147         output.println("\t\t}");\r
148         output.println("\t}");\r
149         output.println("");\r
150         StringBuffer getMultiByteFunc = new StringBuffer();\r
151         getMultiByteFunc.append("\tprivate int getMultiByteChar(int c) {\n");\r
152                 \r
153         HashMap map = (HashMap) charsets.get(new Integer(0x31));\r
154         Object keyArray[] = map.keySet().toArray();\r
155         Arrays.sort(keyArray);\r
156         \r
157         // Note the switch statements generated for converting multibyte characters must be \r
158         // divided up like this so that the 64K code size per method limitation is not exceeded. \r
159         \r
160         dumpPartialMultiByteTable(output, getMultiByteFunc, keyArray, map, 0x210000, 0x214fff);\r
161         dumpPartialMultiByteTable(output, getMultiByteFunc, keyArray, map, 0x215000, 0x21ffff);\r
162         dumpPartialMultiByteTable(output, getMultiByteFunc, keyArray, map, 0x220000, 0x22ffff);\r
163         dumpPartialMultiByteTable(output, getMultiByteFunc, keyArray, map, 0x230000, 0x27ffff);\r
164         dumpPartialMultiByteTable(output, getMultiByteFunc, keyArray, map, 0x280000, 0x7f7fff);\r
165         \r
166         getMultiByteFunc.append("\t\treturn(0);\n");\r
167         getMultiByteFunc.append("\t}");\r
168         output.println(getMultiByteFunc.toString());\r
169         \r
170         output.println("}");\r
171     }\r
172 \r
173     @SuppressWarnings("rawtypes")\r
174     private void dumpPartialMultiByteTable(PrintStream output, StringBuffer buffer, Object keyArray[], HashMap map, int startByte, int endByte)\r
175     {\r
176         String startByteStr = "0x"+Integer.toHexString(startByte);\r
177         String endByteStr = "0x"+Integer.toHexString(endByte);\r
178         buffer.append("\t\tif (c >= "+startByteStr+" && c <= "+endByteStr+")  return (getMultiByteChar_"+startByteStr+"_"+endByteStr+"(c));\n");\r
179         \r
180         output.println("\tprivate char getMultiByteChar_"+startByteStr+"_"+endByteStr+"(int c) {");\r
181         output.println("\t\tswitch(c) {");\r
182         for (int sel = 0; sel < keyArray.length; sel++)\r
183         {\r
184             Integer mKey = (Integer)keyArray[sel];\r
185             Character c = (Character)map.get(mKey);\r
186             if (mKey >= startByte && mKey <= endByte)\r
187             {\r
188                 if (c != null)\r
189                     output.println("\t\t\tcase 0x"+Integer.toHexString(mKey)+":  return((char)0x"+Integer.toHexString((int)c.charValue())+"); ");\r
190                 else\r
191                     output.println("\t\t\tcase 0x"+Integer.toHexString(mKey)+":  return((char)0); ");\r
192             }\r
193         }\r
194         output.println("\t\t\tdefault: return((char)0);");\r
195         output.println("\t\t}");\r
196         output.println("\t}");  \r
197         output.println("");  \r
198     }\r
199     \r
200 \r
201 }\r