2246N/A/*
2362N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2246N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2246N/A *
2246N/A * This code is free software; you can redistribute it and/or modify it
2246N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
2246N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
2246N/A *
2246N/A * This code is distributed in the hope that it will be useful, but WITHOUT
2246N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2246N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2246N/A * version 2 for more details (a copy is included in the LICENSE file that
2246N/A * accompanied this code).
2246N/A *
2246N/A * You should have received a copy of the GNU General Public License version
2246N/A * 2 along with this work; if not, write to the Free Software Foundation,
2246N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2246N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
2246N/A */
2246N/A
2246N/Apackage build.tools.charsetmapping;
2246N/Aimport java.io.*;
2246N/Aimport java.util.Arrays;
2246N/Aimport java.util.ArrayList;
2246N/Aimport java.util.Scanner;
2246N/Aimport java.util.Formatter;
2246N/Aimport java.util.regex.*;
2246N/Aimport java.nio.charset.*;
2246N/Aimport static build.tools.charsetmapping.Utils.*;
2246N/A
2246N/Apublic class DBCS {
2246N/A // pattern used by this class to read in mapping table
2246N/A static Pattern mPattern = Pattern.compile("(?:0x)?(\\p{XDigit}++)\\s++(?:0x)?(\\p{XDigit}++)(?:\\s++#.*)?");
2246N/A
2246N/A public static void genClass(String args[]) throws Exception {
2246N/A
2246N/A Scanner s = new Scanner(new File(args[0], args[2]));
2246N/A while (s.hasNextLine()) {
2246N/A String line = s.nextLine();
2246N/A if (line.startsWith("#") || line.length() == 0)
2246N/A continue;
2246N/A String[] fields = line.split("\\s+");
2246N/A if (fields.length < 10) {
2246N/A System.err.println("Misconfiged sbcs line <" + line + ">?");
2246N/A continue;
2246N/A }
2246N/A String clzName = fields[0];
2246N/A String csName = fields[1];
2246N/A String hisName = ("null".equals(fields[2]))?null:fields[2];
2246N/A String type = fields[3].toUpperCase();
2246N/A if ("BASIC".equals(type))
2246N/A type = "";
2246N/A else
2246N/A type = "_" + type;
2246N/A String pkgName = fields[4];
2246N/A boolean isASCII = Boolean.valueOf(fields[5]);
2246N/A int b1Min = toInteger(fields[6]);
2246N/A int b1Max = toInteger(fields[7]);
2246N/A int b2Min = toInteger(fields[8]);
2246N/A int b2Max = toInteger(fields[9]);
2246N/A System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName);
2246N/A genClass0(args[0], args[1], "DoubleByte-X.java.template",
2246N/A clzName, csName, hisName, pkgName,
2246N/A isASCII, type,
2246N/A b1Min, b1Max, b2Min, b2Max);
2246N/A }
2246N/A }
2246N/A
2246N/A static int toInteger(String s) {
2246N/A if (s.startsWith("0x") || s.startsWith("0X"))
2246N/A return Integer.valueOf(s.substring(2), 16);
2246N/A else
2246N/A return Integer.valueOf(s);
2246N/A }
2246N/A
2246N/A private static void genClass0(String srcDir, String dstDir, String template,
2246N/A String clzName,
2246N/A String csName,
2246N/A String hisName,
2246N/A String pkgName,
2246N/A boolean isASCII,
2246N/A String type,
2246N/A int b1Min, int b1Max,
2246N/A int b2Min, int b2Max)
2246N/A throws Exception
2246N/A {
2246N/A
2246N/A StringBuilder b2cSB = new StringBuilder();
2246N/A StringBuilder b2cNRSB = new StringBuilder();
2246N/A StringBuilder c2bNRSB = new StringBuilder();
2246N/A
2246N/A char[] db = new char[0x10000];
2246N/A char[] c2bIndex = new char[0x100];
2246N/A int c2bOff = 0x100; // first 0x100 for unmappable segs
2246N/A
2246N/A Arrays.fill(db, UNMAPPABLE_DECODING);
2246N/A Arrays.fill(c2bIndex, UNMAPPABLE_DECODING);
2246N/A
2246N/A char[] b2cIndex = new char[0x100];
2246N/A Arrays.fill(b2cIndex, UNMAPPABLE_DECODING);
2246N/A
2246N/A // (1)read in .map to parse all b->c entries
2246N/A FileInputStream in = new FileInputStream(new File(srcDir, clzName + ".map"));
2246N/A Parser p = new Parser(in, mPattern);
2246N/A Entry e = null;
2246N/A while ((e = p.next()) != null) {
2246N/A db[e.bs] = (char)e.cp;
2246N/A
2246N/A if (e.bs > 0x100 && // db
2246N/A b2cIndex[e.bs>>8] == UNMAPPABLE_DECODING) {
2246N/A b2cIndex[e.bs>>8] = 1;
2246N/A }
2246N/A
2246N/A if (c2bIndex[e.cp>>8] == UNMAPPABLE_DECODING) {
2246N/A c2bOff += 0x100;
2246N/A c2bIndex[e.cp>>8] = 1;
2246N/A }
2246N/A }
2246N/A Output out = new Output(new Formatter(b2cSB));
2246N/A out.format("%n static final String b2cSBStr =%n");
2246N/A out.format(db, 0x00, 0x100, ";");
2246N/A
2246N/A out.format("%n static final String[] b2cStr = {%n");
2246N/A for (int i = 0; i < 0x100; i++) {
2246N/A if (b2cIndex[i] == UNMAPPABLE_DECODING) {
2246N/A out.format(" null,%n"); //unmappable segments
2246N/A } else {
2246N/A out.format(db, i, b2Min, b2Max, ",");
2246N/A }
2246N/A }
2246N/A
2246N/A out.format(" };%n");
2246N/A out.close();
2246N/A
2246N/A // (2)now parse the .nr file which includes "b->c" non-roundtrip entries
2246N/A File f = new File(srcDir, clzName + ".nr");
2246N/A if (f.exists()) {
2246N/A StringBuilder sb = new StringBuilder();
2246N/A in = new FileInputStream(f);
2246N/A p = new Parser(in, mPattern);
2246N/A e = null;
2246N/A while ((e = p.next()) != null) {
2246N/A // A <b,c> pair
2246N/A sb.append((char)e.bs);
2246N/A sb.append((char)e.cp);
2246N/A }
2246N/A char[] nr = sb.toString().toCharArray();
2246N/A out = new Output(new Formatter(b2cNRSB));
2246N/A out.format("String b2cNR =%n");
2246N/A out.format(nr, 0, nr.length, ";");
2246N/A out.close();
2246N/A } else {
2246N/A b2cNRSB.append("String b2cNR = null;");
2246N/A }
2246N/A
2246N/A // (3)finally the .c2b file which includes c->b non-roundtrip entries
2246N/A f = new File(srcDir, clzName + ".c2b");
2246N/A if (f.exists()) {
2246N/A StringBuilder sb = new StringBuilder();
2246N/A in = new FileInputStream(f);
2246N/A p = new Parser(in, mPattern);
2246N/A e = null;
2246N/A while ((e = p.next()) != null) {
2246N/A // A <b,c> pair
2246N/A if (c2bIndex[e.cp>>8] == UNMAPPABLE_DECODING) {
2246N/A c2bOff += 0x100;
2246N/A c2bIndex[e.cp>>8] = 1;
2246N/A }
2246N/A sb.append((char)e.bs);
2246N/A sb.append((char)e.cp);
2246N/A }
2246N/A char[] nr = sb.toString().toCharArray();
2246N/A out = new Output(new Formatter(c2bNRSB));
2246N/A out.format("String c2bNR =%n");
2246N/A out.format(nr, 0, nr.length, ";");
2246N/A out.close();
2246N/A } else {
2246N/A c2bNRSB.append("String c2bNR = null;");
2246N/A }
2246N/A
2246N/A // (4)it's time to generate the source file
2246N/A String b2c = b2cSB.toString();
2246N/A String b2cNR = b2cNRSB.toString();
2246N/A String c2bNR = c2bNRSB.toString();
2246N/A
2246N/A Scanner s = new Scanner(new File(srcDir, template));
2246N/A PrintStream ops = new PrintStream(new FileOutputStream(
2246N/A new File(dstDir, clzName + ".java")));
2246N/A if (hisName == null)
2246N/A hisName = "";
2246N/A
2246N/A while (s.hasNextLine()) {
2246N/A String line = s.nextLine();
2246N/A if (line.indexOf("$") == -1) {
2246N/A ops.println(line);
2246N/A continue;
2246N/A }
2246N/A line = line.replace("$PACKAGE$" , pkgName)
2246N/A .replace("$IMPLEMENTS$", (hisName == null)?
2246N/A "" : "implements HistoricallyNamedCharset")
2246N/A .replace("$NAME_CLZ$", clzName)
2246N/A .replace("$NAME_ALIASES$",
2246N/A "sun.nio.cs".equals(pkgName) ?
2246N/A "StandardCharsets.aliases_" + clzName :
2246N/A "ExtendedCharsets.aliasesFor(\"" + csName + "\")")
2246N/A .replace("$NAME_CS$" , csName)
2246N/A .replace("$CONTAINS$",
2246N/A "MS932".equals(clzName)?
2246N/A "return ((cs.name().equals(\"US-ASCII\")) || (cs instanceof JIS_X_0201) || (cs instanceof " + clzName + "));":
2246N/A (isASCII ?
2246N/A "return ((cs.name().equals(\"US-ASCII\")) || (cs instanceof " + clzName + "));":
2246N/A "return (cs instanceof " + clzName + ");"))
2246N/A .replace("$HISTORICALNAME$",
2246N/A (hisName == null)? "" :
2246N/A " public String historicalName() { return \"" + hisName + "\"; }")
2246N/A .replace("$DECTYPE$", type)
2246N/A .replace("$ENCTYPE$", type)
2246N/A .replace("$B1MIN$" , "0x" + Integer.toString(b1Min, 16))
2246N/A .replace("$B1MAX$" , "0x" + Integer.toString(b1Max, 16))
2246N/A .replace("$B2MIN$" , "0x" + Integer.toString(b2Min, 16))
2246N/A .replace("$B2MAX$" , "0x" + Integer.toString(b2Max, 16))
2246N/A .replace("$B2C$", b2c)
2246N/A .replace("$C2BLENGTH$", "0x" + Integer.toString(c2bOff, 16))
2246N/A .replace("$NONROUNDTRIP_B2C$", b2cNR)
2246N/A .replace("$NONROUNDTRIP_C2B$", c2bNR);
2246N/A
2246N/A ops.println(line);
2246N/A }
2246N/A ops.close();
2246N/A }
2246N/A}