/* * Copyright (c) 2008, 2010, 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.regex.*; import java.util.*; import static build.tools.charsetmapping.Utils.*; public class JIS0213 { // regex pattern to parse the "jis0213.map" file static Pattern sjis0213 = Pattern.compile("0x(\\p{XDigit}++)\\s++U\\+(\\p{XDigit}++)(?:\\+(\\p{XDigit}++))?\\s++#.*"); static void genClass(String argv[]) throws IOException { InputStream in = new FileInputStream(argv[0]) ; OutputStream out = new FileOutputStream(argv[1]); int[] sb = new int[0x100]; // singlebyte int[] db = new int[0x10000]; // doublebyte int[] indexC2B = new int[256]; Entry[] supp = new Entry[0x10000]; Entry[] comp = new Entry[0x100]; int suppTotal = 0; int compTotal = 0; int b1Min1 = 0x81; int b1Max1 = 0x9f; int b1Min2 = 0xe0; int b1Max2 = 0xfc; int b2Min = 0x40; int b2Max = 0xfe; //init for (int i = 0; i < 0x80; i++) sb[i] = i; for (int i = 0x80; i < 0x100; i++) sb[i] = UNMAPPABLE_DECODING; for (int i = 0; i < 0x10000; i++) db[i] = UNMAPPABLE_DECODING; try { Parser p = new Parser(in, sjis0213); Entry e = null; while ((e = p.next()) != null) { if (e.cp2 != 0) { comp[compTotal++] = e; } else { if (e.cp <= 0xffff) { if (e.bs <= 0xff) sb[e.bs] = e.cp; else db[e.bs] = e.cp; indexC2B[e.cp>>8] = 1; } else { supp[suppTotal++] = e; } } } ByteArrayOutputStream baos = new ByteArrayOutputStream(); // c2b Index Table, always the first one writeINDEXC2B(baos, indexC2B); writeSINGLEBYTE(baos, sb); writeDOUBLEBYTE1(baos, db, b1Min1, b1Max1, b2Min, b2Max); writeDOUBLEBYTE2(baos, db, b1Min2, b1Max2, b2Min, b2Max); writeSUPPLEMENT(baos, supp, suppTotal); writeCOMPOSITE(baos, comp, compTotal); writeSIZE(out, baos.size()); baos.writeTo(out); out.close(); } catch (Exception x) { x.printStackTrace(); } } static Comparator<Entry> comparatorCP = new Comparator<Entry>() { public int compare(Entry m1, Entry m2) { return m1.cp - m2.cp; } public boolean equals(Object obj) { return this == obj; } }; // tags of different charset mapping tables private final static int MAP_SINGLEBYTE = 0x1; // 0..256 : c private final static int MAP_DOUBLEBYTE1 = 0x2; // min..max: c private final static int MAP_DOUBLEBYTE2 = 0x3; // min..max: c [DB2] private final static int MAP_SUPPLEMENT = 0x5; // db,c private final static int MAP_SUPPLEMENT_C2B = 0x6; // c,db private final static int MAP_COMPOSITE = 0x7; // db,base,cc private final static int MAP_INDEXC2B = 0x8; // index table of c->bb private static final void writeShort(OutputStream out, int data) throws IOException { out.write((data >>> 8) & 0xFF); out.write((data ) & 0xFF); } private static final void writeShortArray(OutputStream out, int type, int[] array, int off, int size) // exclusive throws IOException { writeShort(out, type); writeShort(out, size); for (int i = off; i < size; i++) { writeShort(out, array[off+i]); } } private static final void writeSIZE(OutputStream out, int data) throws IOException { out.write((data >>> 24) & 0xFF); out.write((data >>> 16) & 0xFF); out.write((data >>> 8) & 0xFF); out.write((data ) & 0xFF); } private static void writeINDEXC2B(OutputStream out, int[] indexC2B) throws IOException { writeShort(out, MAP_INDEXC2B); writeShort(out, indexC2B.length); int off = 0; for (int i = 0; i < indexC2B.length; i++) { if (indexC2B[i] != 0) { writeShort(out, off); off += 256; } else { writeShort(out, -1); } } } private static void writeSINGLEBYTE(OutputStream out, int[] sb) throws IOException { writeShortArray(out, MAP_SINGLEBYTE, sb, 0, 256); } private static void writeDOUBLEBYTE(OutputStream out, int type, int[] db, int b1Min, int b1Max, int b2Min, int b2Max) throws IOException { writeShort(out, type); writeShort(out, b1Min); writeShort(out, b1Max); writeShort(out, b2Min); writeShort(out, b2Max); writeShort(out, (b1Max - b1Min + 1) * (b2Max - b2Min + 1)); for (int b1 = b1Min; b1 <= b1Max; b1++) { for (int b2 = b2Min; b2 <= b2Max; b2++) { writeShort(out, db[b1 * 256 + b2]); } } } private static void writeDOUBLEBYTE1(OutputStream out, int[] db, int b1Min, int b1Max, int b2Min, int b2Max) throws IOException { writeDOUBLEBYTE(out, MAP_DOUBLEBYTE1, db, b1Min, b1Max, b2Min, b2Max); } private static void writeDOUBLEBYTE2(OutputStream out, int[] db, int b1Min, int b1Max, int b2Min, int b2Max) throws IOException { writeDOUBLEBYTE(out, MAP_DOUBLEBYTE2, db, b1Min, b1Max, b2Min, b2Max); } // the c2b table is output as well private static void writeSUPPLEMENT(OutputStream out, Entry[] supp, int size) throws IOException { writeShort(out, MAP_SUPPLEMENT); writeShort(out, size * 2); // db at first half, cc at the low half for (int i = 0; i < size; i++) { writeShort(out, supp[i].bs); } for (int i = 0; i < size; i++) { writeShort(out, supp[i].cp); } //c2b writeShort(out, MAP_SUPPLEMENT_C2B); writeShort(out, size*2); Arrays.sort(supp, 0, size, comparatorCP); for (int i = 0; i < size; i++) { writeShort(out, supp[i].cp); } for (int i = 0; i < size; i++) { writeShort(out, supp[i].bs); } } private static void writeCOMPOSITE(OutputStream out, Entry[] comp, int size) throws IOException { writeShort(out, MAP_COMPOSITE); writeShort(out, size*3); // comp is sorted already for (int i = 0; i < size; i++) { writeShort(out, (char)comp[i].bs); writeShort(out, (char)comp[i].cp); writeShort(out, (char)comp[i].cp2); } } }