info.freelibrary.marc4j.converter.impl.CodeTableGenerator Maven / Gradle / Ivy
/**
* Copyright (C) 2002 Bas Peters
*
* This file is part of MARC4J
*
* MARC4J is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* MARC4J is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with MARC4J; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package info.freelibrary.marc4j.converter.impl;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Vector;
/**
* Invoked at build time to generate a java source file (named CodeTableGenerated.java) which when compiled will
* implement the CodeTableInterface (primarily through switch statements) and which can be used be the AnselToUnicode
* converter instead of this class, and which will produce the same results as the object CodeTable.
* The following routines are only used in the code generation process, and are not available to be called from within
* an application that uses Marc4j.
* The routines generated for converting MARC8 multibyte characters to unicode are split into several routines to
* workaround a limitation in java that a method can only contain 64k of code when it is compiled.
*
* @author Robert Haschart
* @author Kevin S. Clarke
*/
public class CodeTableGenerator extends CodeTable {
/**
* Creates a CodeTableGenerator from the supplied {@link InputStream}.
*
* @param byteStream
*/
public CodeTableGenerator(final InputStream byteStream) {
super(byteStream);
}
/**
* The main function called when generating a codetable.
*
* @param args
* @throws FileNotFoundException
*/
public static void main(final String args[]) throws FileNotFoundException {
final InputStream in = CodeTable.class.getResourceAsStream("resources/codetables.xml");
final CodeTableGenerator ctGenerator = new CodeTableGenerator(in);
if (args.length > 0) {
final PrintStream printStream = new PrintStream(new File(args[0]));
ctGenerator.dumpTableAsSwitchStatement(printStream);
} else {
ctGenerator.dumpTableAsSwitchStatement(System.out);
}
}
private void dumpTableAsSwitchStatement(final PrintStream out) {
out.println("package info.freelibrary.marc4j.converter.impl;");
out.println("");
out.println("/**");
out.println(" * An implementation of CodeTableInterface that is used in converting MARC8");
out.println(" * data to UTF8 data, that doesn't rely on any data files or resources or");
out.println(" * data structures");
out.println(" *");
out.println(" * Warning: This file is generated by running the main routine in the file");
out.println(" * CodeTableGenerator.java");
out.println(" *");
out.println(" * Warning: Do not edit this file, or all edits will be lost at the next build.");
out.println(" */");
out.println("public class CodeTableGenerated implements CodeTableInterface {");
out.println(" /**");
out.println(" * Returns true if combining; else, false.");
out.println(" *");
out.println(" * @param i");
out.println(" * @param g0");
out.println(" * @param g1");
out.println(" */");
out.println(" public boolean isCombining(final int i, final int g0, final int g1) {");
out.println(" switch (i <= 0x7E ? g0 : g1) {");
final Object combiningKeys[] = combining.keySet().toArray();
Arrays.sort(combiningKeys);
for (int combiningSel = 0; combiningSel < combiningKeys.length; combiningSel++) {
final Integer nextKey = (Integer) combiningKeys[combiningSel];
out.println(" case 0x" + Integer.toHexString(nextKey) + ":");
final Vector v = combining.get(nextKey);
if (v.size() > 0) {
out.println(" switch (i) {");
for (final Integer vVal : v) {
out.println(" case 0x" + Integer.toHexString(vVal) + ":");
}
out.println(" return true;");
out.println(" default:");
out.println(" return false;");
out.println(" }");
} else {
out.println(" return false;");
}
}
out.println(" default:");
out.println(" return false;");
out.println(" }");
out.println(" }");
out.println("");
out.println(" /**");
out.println(" * Returns char.");
out.println(" *");
out.println(" * @param c");
out.println(" * @param mode");
out.println(" */");
out.println(" public char getChar(final int c, final int mode) {");
out.println(" int code = getCharCode(c, mode);");
out.println(" if (code == -1) {");
out.println(" return (char)0;");
out.println(" }");
out.println(" if (code != 0) {");
out.println(" return (char)code;");
out.println(" }");
out.println(" code = getCharCode(c < 0x80 ? c + 0x80 : c - 0x80 , mode);");
out.println(" return (char)code;");
out.println(" }");
out.println("");
out.println(" private int getCharCode(final int c, final int mode) {");
out.println(" if (c == 0x20) {");
out.println(" return c;");
out.println(" }");
out.println(" switch (mode) {");
final Integer charsetsKeys[] = charsets.keySet().toArray(new Integer[0]);
Arrays.sort(charsetsKeys);
for (int index = 0; index < charsetsKeys.length; index++) {
final Integer nextKey = charsetsKeys[index];
final String hex = Integer.toHexString(nextKey);
out.println(" case 0x" + hex + ":");
if (nextKey.intValue() == 0x31) {
out.println(" return getMultiByteChar(c);");
} else {
final HashMap map = charsets.get(nextKey);
final Integer keyArray[] = map.keySet().toArray(new Integer[0]);
Arrays.sort(keyArray);
out.println(" switch(c) {");
for (int sel = 0; sel < keyArray.length; sel++) {
final Integer mKey = keyArray[sel];
final Character c = map.get(mKey);
if (c != null) {
final String kHex = Integer.toHexString(mKey);
final String vHex = Integer.toHexString(c.charValue());
out.println(" case 0x" + kHex + ":\n return 0x" +
vHex + ";");
} else {
final String kHex = Integer.toHexString(mKey);
out.println(" case 0x" + kHex + ":\n return 0;");
}
}
out.println(" default:");
out.println(" return 0;");
out.println(" }");
}
}
out.println(" default:");
out.println(" return -1;"); // unknown charset specified
out.println(" }");
out.println(" }");
out.println("");
final StringBuffer getMultiByteFunc = new StringBuffer();
getMultiByteFunc.append(" private int getMultiByteChar(final int c) {\n");
final HashMap map = charsets.get(new Integer(0x31));
final Integer keyArray[] = map.keySet().toArray(new Integer[0]);
Arrays.sort(keyArray);
// Note the switch statements generated for converting multibyte
// characters must be divided up like this so that the 64K code
// size per method limitation is not exceeded.
dumpPartialMultiByteTable(out, getMultiByteFunc, keyArray, map, 0x210000, 0x214fff);
dumpPartialMultiByteTable(out, getMultiByteFunc, keyArray, map, 0x215000, 0x21ffff);
dumpPartialMultiByteTable(out, getMultiByteFunc, keyArray, map, 0x220000, 0x22ffff);
dumpPartialMultiByteTable(out, getMultiByteFunc, keyArray, map, 0x230000, 0x27ffff);
dumpPartialMultiByteTable(out, getMultiByteFunc, keyArray, map, 0x280000, 0x7f7fff);
getMultiByteFunc.append(" return 0;\n");
getMultiByteFunc.append(" }");
out.println(getMultiByteFunc.toString());
out.println("}");
}
private void dumpPartialMultiByteTable(final PrintStream out, final StringBuffer buffer,
final Integer keyArray[], final HashMap map, final int startByte, final int endByte) {
final String startByteStr = "0x" + Integer.toHexString(startByte);
final String endByteStr = "0x" + Integer.toHexString(endByte);
buffer.append(" if (c >= " + startByteStr + " && c <= " + endByteStr +
") {\n return getMultiByteChar_" + startByteStr + "_" + endByteStr + "(c);\n }\n");
out.println(" private char getMultiByteChar_" + startByteStr + "_" + endByteStr + "(final int c) {");
out.println(" switch (c) {");
for (int sel = 0; sel < keyArray.length; sel++) {
final Integer mKey = keyArray[sel];
final Character c = map.get(mKey);
if (mKey >= startByte && mKey <= endByte) {
if (c != null) {
final String kHex = Integer.toHexString(mKey);
final String vHex = Integer.toHexString(c.charValue());
out.println(" case 0x" + kHex + ":\n return (char)0x" + vHex + ";");
} else {
final String kHex = Integer.toHexString(mKey);
out.println(" case 0x" + kHex + ":\n return (char)0;");
}
}
}
out.println(" default:");
out.println(" return (char)0;");
out.println(" }");
out.println(" }");
out.println("");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy