/* * 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.File; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.BufferedReader; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.Scanner; import java.util.Formatter; public class Utils { public final static char UNMAPPABLE_DECODING = '\uFFFD'; public final static int UNMAPPABLE_ENCODING = 0xFFFD; public static class Entry { public int bs; //byte sequence reps public int cp; //Unicode codepoint public int cp2; //CC of composite public Entry () {} public Entry (int bytes, int cp, int cp2) { this.bs = bytes; this.cp = cp; this.cp2 = cp2; } } public static class Parser { static final Pattern basic = Pattern.compile("(?:0x)?(\\p{XDigit}++)\\s++(?:0x)?(\\p{XDigit}++)?\\s*+.*"); static final int gBS = 1; static final int gCP = 2; static final int gCP2 = 3; BufferedReader reader; boolean closed; Matcher matcher; int gbs, gcp, gcp2; public Parser (InputStream in, Pattern p, int gbs, int gcp, int gcp2) throws IOException { this.reader = new BufferedReader(new InputStreamReader(in)); this.closed = false; this.matcher = p.matcher(""); this.gbs = gbs; this.gcp = gcp; this.gcp2 = gcp2; } public Parser (InputStream in, Pattern p) throws IOException { this(in, p, gBS, gCP, gCP2); } public Parser (InputStream in) throws IOException { this(in, basic, gBS, gCP, gCP2); } protected boolean isDirective(String line) { return line.startsWith("#"); } protected Entry parse(Matcher matcher, Entry mapping) { mapping.bs = Integer.parseInt(matcher.group(gbs), 16); mapping.cp = Integer.parseInt(matcher.group(gcp), 16); if (gcp2 <= matcher.groupCount() && matcher.group(gcp2) != null) mapping.cp2 = Integer.parseInt(matcher.group(gcp2), 16); else mapping.cp2 = 0; return mapping; } public Entry next() throws Exception { return next(new Entry()); } // returns null and closes the input stream if the eof has beenreached. public Entry next(Entry mapping) throws Exception { if (closed) return null; String line; while ((line = reader.readLine()) != null) { if (isDirective(line)) continue; matcher.reset(line); if (!matcher.lookingAt()) { //System.out.println("Missed: " + line); continue; } return parse(matcher, mapping); } reader.close(); closed = true; return null; } } public static class Output { private Formatter out; public Output(Formatter out) { this.out = out; } public void close() { out.close(); } private void toChar(String fmt, char c) { 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(fmt, c & 0xffff); } } public void format(String fmt, Object ... args) { out.format(fmt, args); } public void format(char[] cc, int off, int end, String closure) { while (off < end) { out.format(" \""); for (int j = 0; j < 8; j++) { if (off == end) break; toChar("\\u%04X", cc[off++]); } if (off == end) out.format("\" %s%n", closure); else out.format("\" + %n"); } } public void format(char[] cc, String closure) { format(cc, 0, cc.length, closure); } public void format(char[] db, int b1, int b2Min, int b2Max, String closure) { char[] cc = new char[b2Max - b2Min + 1]; int off = 0; for (int b2 = b2Min; b2 <= b2Max; b2++) { cc[off++] = db[(b1 << 8) | b2]; } format(cc, 0, cc.length, closure); } public void format(char[] date) { int off = 0; int end = date.length; while (off < end) { out.format(" "); for (int j = 0; j < 8 && off < end; j++) { toChar("'\\u%04X',", date[off++]); } out.format("%n"); } } } public static String getCopyright(File f) throws IOException { Scanner s = new Scanner(f, "ISO-8859-1"); StringBuilder sb = new StringBuilder(); while (s.hasNextLine()) { String ln = s.nextLine(); sb.append(ln + "\n"); // assume we have the copyright as the first comment if (ln.matches("^\\s\\*\\/$")) break; } s.close(); return sb.toString(); } }