package xtc.lang.blink.agent; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.HashMap; /** * A hard coded Java class generator. This tool takes Java class files, and * generates a C source file and optionally a C header file that define a * character arrays that contain the input class files. * * @author Byeongcheol Lee */ public class GenerateHardcodedJavaClass { /** * Print the reason why this program can not accept a user command line, and * show the command line usage. * * @param reason The reason. */ public static void usage(String reason) { if (reason != null) { System.out.println(reason); } System.out.println( "usage: " + GenerateHardcodedJavaClass.class.getName() + " [-o <output file>] [-h <output header file]" + "[<array name> <input file>] [<array name> <input file>] ...\n" + " " ); System.exit(-1); } /** * Parse the user command line arguments and run the application. * * @param args The arguments. */ public static void main(String[] args) { //parse arguments String outputSourceFileName = null; String outputHeaderFileName = null; HashMap<String,String> array2ClassFileMap = new HashMap<String,String>(); for(int i = 0;i < args.length;i++) { if (args[i].equals("-o") ) { if ((i + 1) < args.length) { outputSourceFileName = args[++i]; } else { usage("Please, specify output file after -o"); } } else if (args[i].equals("-h")) { if ((i+1) < args.length) { outputHeaderFileName = args[++i]; } else { usage("Please, specify output header file name after -h"); } } else { if ((i + 1) < args.length) { String arrayName = args[i]; String inputFileName = args[++i]; File f = new File(inputFileName); if (f.isFile() && f.canRead()) { if (array2ClassFileMap.containsKey(arrayName)) { usage("Duplicated array name: " + arrayName); } else { array2ClassFileMap.put(arrayName, inputFileName); } } else { usage("You need a read acess permission: " + inputFileName); } } else { usage("Please, specify input file"); } } } if (array2ClassFileMap.size() <= 0) { usage("Please, specify at least one <array name, input file> pair"); } // run this tool and generates a header file and a source file. try { // generate header file. if ( outputHeaderFileName != null) { PrintWriter headerWriter = new PrintWriter(new FileOutputStream(outputHeaderFileName)); generateHeaderFile(outputHeaderFileName, array2ClassFileMap, headerWriter); headerWriter.flush(); headerWriter.close(); } //generate source file. PrintWriter os = new PrintWriter( (outputSourceFileName == null) ? System.out : new FileOutputStream( outputSourceFileName)); generateSourceFile(array2ClassFileMap, os); os.flush(); os.close(); } catch (IOException e) { System.err.println("Can not recover from the input or output fault"); } } /** * Generate header file declaring a set of character arrays for the Java class * files. * * @param headerFile The header file name. * @param map The map. * @param os The output stream. */ private static void generateHeaderFile(String headerFile, HashMap<String,String> map, PrintWriter os) throws IOException { String symbolName = "_" + headerFile.toUpperCase().replace('.', '_') + "_"; os.println("#ifndef " + symbolName); os.println("#define " + symbolName); for(final String arrayName : map.keySet()) { String inputFileName = map.get(arrayName); File inputFile = new File(inputFileName); long length = inputFile.length(); os.printf("extern const signed char %s[%d];\n", arrayName, length); } os.println("#endif /* " + symbolName + " */"); } /** * Read Java class files and generate C source lines. * * @param map The map. * @param os The output. */ private static void generateSourceFile(HashMap<String,String> map, PrintWriter os) throws IOException { os.write("/* This file is generated by " + GenerateHardcodedJavaClass.class.getName() + ". */\n"); for(final String arrayName : map.keySet()) { String inputFileName = map.get(arrayName); long length = new File(inputFileName).length(); InputStream is = new FileInputStream(inputFileName); BufferedInputStream bis = new BufferedInputStream(is); os.write("/* This array is from " + inputFileName + ". */\n"); os.printf("const char signed %s[%d] = {\n", arrayName, length); int c, i=1; while ((c = is.read()) >= 0) { os.printf("0x%02x, ", c); if (i % 8 == 0) {os.write("\n");} i++; } os.write("\n"); os.write("};\n"); bis.close(); } } }