--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/charsetmapping/SBCS.java Thu Nov 14 11:19:32 2013 +0100
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.charsetmapping;
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.Formatter;
+import java.util.regex.*;
+import java.nio.charset.*;
+import static build.tools.charsetmapping.Utils.*;
+
+public class SBCS {
+
+ public static void genClass(String args[]) throws Exception {
+
+ Scanner s = new Scanner(new File(args[0], args[2]));
+ while (s.hasNextLine()) {
+ String line = s.nextLine();
+ if (line.startsWith("#") || line.length() == 0)
+ continue;
+ String[] fields = line.split("\\s+");
+ if (fields.length < 5) {
+ System.err.println("Misconfiged sbcs line <" + line + ">?");
+ continue;
+ }
+ String clzName = fields[0];
+ String csName = fields[1];
+ String hisName = fields[2];
+ boolean isASCII = Boolean.valueOf(fields[3]);
+ String pkgName = fields[4];
+ System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName);
+
+ genClass0(args[0], args[1], "SingleByte-X.java.template",
+ clzName, csName, hisName, pkgName, isASCII);
+ }
+ }
+
+ private static void toString(char[] sb, int off, int end,
+ Formatter out, String closure,
+ boolean comment) {
+ while (off < end) {
+ out.format(" \"");
+ for (int j = 0; j < 8; j++) {
+ if (off == end)
+ break;
+ char c = sb[off++];
+ switch (c) {
+ case '\b':
+ out.format("\\b"); break;
+ case '\t':
+ out.format("\\t"); break;
+ case '\n':
+ out.format("\\n"); break;
+ case '\f':
+ out.format("\\f"); break;
+ case '\r':
+ out.format("\\r"); break;
+ case '\"':
+ out.format("\\\""); break;
+ case '\'':
+ out.format("\\'"); break;
+ case '\\':
+ out.format("\\\\"); break;
+ default:
+ out.format("\\u%04X", c & 0xffff);
+ }
+ }
+ if (comment) {
+ if (off == end)
+ out.format("\" %s // 0x%02x - 0x%02x%n",
+ closure, off-8, off-1);
+ else
+ out.format("\" + // 0x%02x - 0x%02x%n",
+ off-8, off-1);
+ } else {
+ if (off == end)
+ out.format("\"%s%n", closure);
+ else
+ out.format("\" +%n");
+ }
+ }
+ }
+
+ static Pattern sbmap = Pattern.compile("0x(\\p{XDigit}++)\\s++(?:U\\+|0x)?(\\p{XDigit}++)(?:\\s++#.*)?");
+
+ private static void genClass0(String srcDir, String dstDir,
+ String template,
+ String clzName,
+ String csName,
+ String hisName,
+ String pkgName,
+ boolean isASCII)
+ throws Exception
+ {
+ StringBuilder b2cSB = new StringBuilder();
+ StringBuilder b2cNRSB = new StringBuilder();
+ StringBuilder c2bNRSB = new StringBuilder();
+
+ char[] sb = new char[0x100];
+ char[] c2bIndex = new char[0x100];
+ int c2bOff = 0;
+ Arrays.fill(sb, UNMAPPABLE_DECODING);
+ Arrays.fill(c2bIndex, UNMAPPABLE_DECODING);
+
+ // (1)read in .map to parse all b->c entries
+ FileInputStream in = new FileInputStream(
+ new File(srcDir, clzName + ".map"));
+ Parser p = new Parser(in, sbmap);
+ Entry e = null;
+
+ while ((e = p.next()) != null) {
+ sb[e.bs] = (char)e.cp;
+ if (c2bIndex[e.cp>>8] == UNMAPPABLE_DECODING) {
+ c2bOff += 0x100;
+ c2bIndex[e.cp>>8] = 1;
+ }
+ }
+
+ Formatter fm = new Formatter(b2cSB);
+ fm.format("%n");
+
+ // vm -server shows cc[byte + 128] access is much faster than
+ // cc[byte&0xff] so we output the upper segment first
+ toString(sb, 0x80, 0x100, fm, "+", true);
+ toString(sb, 0x00, 0x80, fm, ";", true);
+ fm.close();
+
+ // (2)now the .nr file which includes "b->c" non-roundtrip entries
+ File f = new File(srcDir, clzName + ".nr");
+ if (f.exists()) {
+ in = new FileInputStream(f);
+ fm = new Formatter(b2cNRSB);
+ p = new Parser(in, sbmap);
+ e = null;
+
+ fm.format("// remove non-roundtrip entries%n");
+ fm.format(" b2cMap = b2cTable.toCharArray();%n");
+ while ((e = p.next()) != null) {
+ fm.format(" b2cMap[%d] = UNMAPPABLE_DECODING;%n",
+ (e.bs>=0x80)?(e.bs-0x80):(e.bs+0x80));
+ }
+ fm.close();
+ }
+
+ // (3)finally the .c2b file which includes c->b non-roundtrip entries
+ f = new File(srcDir, clzName + ".c2b");
+ if (f.exists()) {
+ in = new FileInputStream(f);
+ fm = new Formatter(c2bNRSB);
+ p = new Parser(in, sbmap);
+ e = null;
+ ArrayList<Entry> es = new ArrayList<Entry>();
+ while ((e = p.next()) != null) {
+ if (c2bIndex[e.cp>>8] == UNMAPPABLE_DECODING) {
+ c2bOff += 0x100;
+ c2bIndex[e.cp>>8] = 1;
+ }
+ es.add(e);
+ }
+ fm.format("// non-roundtrip c2b only entries%n");
+ if (es.size() < 100) {
+ fm.format(" c2bNR = new char[%d];%n", es.size() * 2);
+ int i = 0;
+ for (Entry entry: es) {
+ fm.format(" c2bNR[%d] = 0x%x; c2bNR[%d] = 0x%x;%n",
+ i++, entry.bs, i++, entry.cp);
+ }
+ } else {
+ char[] cc = new char[es.size() * 2];
+ int i = 0;
+ for (Entry entry: es) {
+ cc[i++] = (char)entry.bs;
+ cc[i++] = (char)entry.cp;
+ }
+ fm.format(" c2bNR = (%n");
+ toString(cc, 0, i, fm, ").toCharArray();", false);
+ }
+ fm.close();
+ }
+
+ // (4)it's time to generate the source file
+ String b2c = b2cSB.toString();
+ String b2cNR = b2cNRSB.toString();
+ String c2bNR = c2bNRSB.toString();
+
+ Scanner s = new Scanner(new File(srcDir, template));
+ PrintStream out = new PrintStream(new FileOutputStream(
+ new File(dstDir, clzName + ".java")));
+
+ while (s.hasNextLine()) {
+ String line = s.nextLine();
+ int i = line.indexOf("$");
+ if (i == -1) {
+ out.println(line);
+ continue;
+ }
+ if (line.indexOf("$PACKAGE$", i) != -1) {
+ line = line.replace("$PACKAGE$", pkgName);
+ }
+ if (line.indexOf("$NAME_CLZ$", i) != -1) {
+ line = line.replace("$NAME_CLZ$", clzName);
+ }
+ if (line.indexOf("$NAME_CS$", i) != -1) {
+ line = line.replace("$NAME_CS$", csName);
+ }
+ if (line.indexOf("$NAME_ALIASES$", i) != -1) {
+ if ("sun.nio.cs".equals(pkgName))
+ line = line.replace("$NAME_ALIASES$",
+ "StandardCharsets.aliases_" + clzName);
+ else
+ line = line.replace("$NAME_ALIASES$",
+ "ExtendedCharsets.aliasesFor(\"" + csName + "\")");
+ }
+ if (line.indexOf("$NAME_HIS$", i) != -1) {
+ line = line.replace("$NAME_HIS$", hisName);
+ }
+ if (line.indexOf("$CONTAINS$", i) != -1) {
+ if (isASCII)
+ line = " return ((cs.name().equals(\"US-ASCII\")) || (cs instanceof " + clzName + "));";
+ else
+ line = " return (cs instanceof " + clzName + ");";
+ }
+ if (line.indexOf("$B2CTABLE$") != -1) {
+ line = line.replace("$B2CTABLE$", b2c);
+ }
+ if (line.indexOf("$C2BLENGTH$") != -1) {
+ line = line.replace("$C2BLENGTH$", "0x" + Integer.toString(c2bOff, 16));
+ }
+ if (line.indexOf("$NONROUNDTRIP_B2C$") != -1) {
+ if (b2cNR.length() == 0)
+ continue;
+ line = line.replace("$NONROUNDTRIP_B2C$", b2cNR);
+ }
+
+ if (line.indexOf("$NONROUNDTRIP_C2B$") != -1) {
+ if (c2bNR.length() == 0)
+ continue;
+ line = line.replace("$NONROUNDTRIP_C2B$", c2bNR);
+ }
+ out.println(line);
+ }
+ out.close();
+ }
+}