/* * Copyright (c) 2009, 2017, 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. * * 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 org.openjdk.asmtools.jcdec; import static org.openjdk.asmtools.jcoder.JcodTokens.*; import org.openjdk.asmtools.jdis.uEscWriter; import org.openjdk.asmtools.util.I18NResourceBundle; import org.openjdk.asmtools.util.ProductInfo; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; /** * Main program of the JavaCard DeCoder * */ public class Main { /*-------------------------------------------------------- */ /* Main Fields */ /** * Name of the program. */ String program; public static final I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(Main.class); /** * The stream where error message are printed. */ PrintWriter out; boolean DebugFlag = false; boolean printDetails = false; int shift = 0; private static final char hexTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /*-------------------------------------------------------- */ static String toHex(long val, int width) { StringBuffer s = new StringBuffer(); for (int i = width * 2 - 1; i >= 0; i--) { s.append(hexTable[((int) (val >> (4 * i))) & 0xF]); } return "0x" + s.toString(); } static String toHex(long val) { int width; for (width = 8; width > 0; width--) { if ((val >> (width - 1) * 8) != 0) { break; } } return toHex(val, width); } void printByteHex(PrintWriter out, int b) { out.print(hexTable[(b >> 4) & 0xF]); out.print(hexTable[b & 0xF]); } /*========================================================*/ void out_begin(String s) { for (int i = 0; i < shift; i++) { out.print(" "); } out.println(s); shift++; } void out_print(String s) { for (int i = 0; i < shift; i++) { out.print(" "); } out.print(s); } void out_println(String s) { for (int i = 0; i < shift; i++) { out.print(" "); } out.println(s); } void out_end(String s) { shift--; for (int i = 0; i < shift; i++) { out.print(" "); } out.println(s); } String startArray(int length) { return "[" + (printDetails ? Integer.toString(length) : "") + "]"; } void printBytes(DataInputStream in, int len) throws IOException { try { for (int i = 0; i < len; i++) { if (i % 8 == 0) { out_print("0x"); } printByteHex(out, in.readByte()); if (i % 8 == 7) { out.println(";"); } } } finally { if (len % 8 != 0) { out.println(";"); } } } /*========================================================*/ static final int EXPORT_MAGIC = 0x00FACADE; static final int HEADER_MAGIC = 0xDECAFFED; static String[] compNames = { "Header", "Directory", "Applet", "Import", "ConstantPool", "Class", "Method", "StaticField", "RefLocation", "Export", "Descriptor" }; static String compName(int compNum) { try { return compNames[compNum - 1]; } catch (ArrayIndexOutOfBoundsException e) { return "tag " + compNum + "???"; } } String[] cPoolStrings; void decodeAttr(DataInputStream in) throws IOException { int name_cpx = in.readUnsignedShort(), len = in.readInt(); String AttrName = null; String endingComment = "Attr(#" + name_cpx + ")"; try { endingComment = AttrName = cPoolStrings[name_cpx]; } catch (ArrayIndexOutOfBoundsException e) { } if (printDetails) { out_begin("Attr(#" + name_cpx + ", " + len + ") { // " + AttrName); } else { out_begin("Attr(#" + name_cpx + ") { // " + AttrName); } if (AttrName == null) { printBytes(in, len); } else if (AttrName.equals("ConstantValue")) { if (len != 2) { out_println("// invalid length of ConstantValue attr: " + len + " (should be 2)"); printBytes(in, len); } else { out_println("#" + in.readUnsignedShort() + ";"); } } else { printBytes(in, len); } out_end("} // end " + endingComment); } void decodeExp(String inpName) throws IOException { DataInputStream in = new DataInputStream(new FileInputStream(inpName)); out_println("file " + inpName); out_begin("{ // export file"); int magic = in.readInt(); out_print(toHex(magic, 4) + "; // "); if (magic != EXPORT_MAGIC) { out.print("wrong magic: 0x" + Integer.toString(EXPORT_MAGIC, 16) + " expected"); } else { out_print("magic"); } out.println(); out_println(in.readUnsignedByte() + "b; // minor version"); out_println(in.readUnsignedByte() + "b; // major version"); int cp_count = in.readUnsignedShort(); cPoolStrings = new String[cp_count]; out_begin(startArray(cp_count) + " { // Constant Pool"); for (int i = 0; i < cp_count; i++) { int tag = in.readUnsignedByte(); ConstType tg = constType(tag); switch (tg) { case CONSTANT_UTF8: out_print("Utf8 \""); StringBuffer sb = new StringBuffer(); String s = in.readUTF(); cPoolStrings[i] = s; for (int k = 0; k < s.length(); k++) { char c = s.charAt(k); switch (c) { case '\t': sb.append('\\').append('t'); break; case '\n': sb.append('\\').append('n'); break; case '\r': sb.append('\\').append('r'); break; case '\"': sb.append('\\').append('\"'); break; default: sb.append(c); } } out.println(sb.append("\"; // #").append(i).toString()); break; case CONSTANT_INTEGER: out_println("int " + toHex(in.readInt(), 4) + "; // #" + i); break; case CONSTANT_CLASS: out_println("class #" + in.readUnsignedShort() + "; // #" + i); break; case CONSTANT_JAVACARD_PACKAGE: out_begin("package { // #" + i); out_println(toHex(in.readUnsignedByte(), 1) + "; // flags"); out_println("#" + in.readUnsignedShort() + "; // name"); out_println(in.readUnsignedByte() + "b; // minor version"); out_println(in.readUnsignedByte() + "b; // major version"); int aid_len = in.readUnsignedByte(); out_begin("Bytes" + startArray(aid_len) + "b {"); printBytes(in, aid_len); out_end("};"); // Bytes[] out_end("};"); // package info break; default: throw new Error("invalid constant type: " + (int) tag); } } ; out_end("} // Constant pool"); out_println("#" + in.readUnsignedShort() + "; // this package"); int class_count = in.readUnsignedByte(); out_begin(startArray(class_count) + "b { // classes"); for (int i = 0; i < class_count; i++) { out_begin("{ // class " + i); out_println(in.readUnsignedByte() + "b; // token"); int flags = in.readUnsignedShort(); out_print("0x"); printByteHex(out, flags >> 8); printByteHex(out, flags); out.println("; // flags"); out_println("#" + in.readUnsignedShort() + "; // this class"); int sup_count = in.readUnsignedShort(); out_begin(startArray(sup_count) + " { // supers"); for (int k = 0; k < sup_count; k++) { out_println("#" + in.readUnsignedShort() + ";"); } out_end("} // supers"); int int_count = in.readUnsignedByte(); out_begin(startArray(int_count) + "b { // interfaces"); for (int k = 0; k < int_count; k++) { out_println("#" + in.readUnsignedShort() + ";"); } out_end("} // interfaces"); int field_count = in.readUnsignedShort(); out_begin(startArray(field_count) + " { // fields"); for (int k = 0; k < field_count; k++) { out_begin("{ // field " + k); out_println(in.readUnsignedByte() + "b; // token"); int f_flags = in.readUnsignedShort(); out_print("0x"); printByteHex(out, f_flags >> 8); printByteHex(out, f_flags); out.println("; // flags"); out_println("#" + in.readUnsignedShort() + "; // this field name"); out_println("#" + in.readUnsignedShort() + "; // this field descriptor"); int attr_count = in.readUnsignedShort(); out_begin(startArray(attr_count) + " { // Attributes"); for (int ai = 0; ai < attr_count; ai++) { decodeAttr(in); } out_end("} // Attributes"); out_end("};"); } out_end("} // fields"); int mth_count = in.readUnsignedShort(); out_begin(startArray(mth_count) + " { // methods"); for (int k = 0; k < mth_count; k++) { out_begin("{ // method " + k); out_println(in.readUnsignedByte() + "b; // token"); int mth_flags = in.readUnsignedShort(); out_print("0x"); printByteHex(out, mth_flags >> 8); printByteHex(out, mth_flags); out.println("; // flags"); out_println("#" + in.readUnsignedShort() + "; // this method name"); out_println("#" + in.readUnsignedShort() + "; // this method descriptor"); out_end("};"); } out_end("} // methods"); out_end("};"); } out_end("} // classes"); endComponent(in); } DataInputStream beginComponent(String inpName) throws IOException { DataInputStream in = new DataInputStream(new FileInputStream(inpName)); out_println("file " + inpName); int tag = in.readUnsignedByte(); out_print("Component(" + tag); int size = in.readUnsignedShort(); if (printDetails) { out.print(", " + size); } out_begin(") { // " + compName(tag)); return in; } void endComponent(DataInputStream in) throws IOException { out_end("};"); // Component int avail = in.available(); if (avail > 0) { out.println("=========== extra bytes:"); for (int k = 0; k < 8; k++) { printBytes(in, avail >= 8 ? 8 : avail); avail = in.available(); if (avail == 0) { break; } } if (avail > 0) { out.println(" there is also " + avail + " bytes available"); } } in.close(); } ArrayList methodsLengths = null; ArrayList methodsOffsets = null; void decodeHeader(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int magic = in.readInt(); out_print(toHex(magic, 4) + "; // "); if (magic != HEADER_MAGIC) { out.print("wrong magic: 0x" + Integer.toString(HEADER_MAGIC, 16) + " expected"); } else { out_print("magic"); } out.println(); out_println(in.readUnsignedByte() + "b; // minor version"); out_println(in.readUnsignedByte() + "b; // major version"); out_println(toHex(in.readUnsignedByte(), 1) + "; // flags"); out_begin("{ // package info"); out_println(in.readUnsignedByte() + "b; // minor version"); out_println(in.readUnsignedByte() + "b; // major version"); int aid_len = in.readUnsignedByte(); out_begin("Bytes" + startArray(aid_len) + "b {"); printBytes(in, aid_len); out_end("};"); // Bytes[] out_end("};"); // package info endComponent(in); } void decodeDirectory(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int i; out_begin("{ // component sizes"); for (i = 0; i < 11; i++) { out_println(in.readUnsignedShort() + "; // " + (i + 1)); } out_end("};"); out_begin("{ // static field size"); out_println(in.readUnsignedShort() + "; // image size"); out_println(in.readUnsignedShort() + "; // array init count"); out_println(in.readUnsignedShort() + "; // array init size"); out_end("};"); out_println(in.readUnsignedByte() + "b; // import count"); out_println(in.readUnsignedByte() + "b; // applet count"); int custom_count = in.readUnsignedByte(); out_begin(startArray(custom_count) + "b { // custom components"); for (i = 0; i < custom_count; i++) { out_print("Comp(" + in.readUnsignedByte()); // tag; int size2 = in.readUnsignedShort(); if (printDetails) { out_print(", " + size2); } out_begin(") {"); int aid_len = in.readUnsignedByte(); out_begin("Bytes" + startArray(aid_len) + "b {"); printBytes(in, aid_len); out_end("};"); out_end("};"); } out_end("};"); endComponent(in); } void decodeApplet(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int applet_count = in.readUnsignedByte(); out_begin(startArray(applet_count) + "b { // applets"); for (int i = 0; i < applet_count; i++) { out_begin("{ // applet " + i); int aid_len = in.readUnsignedByte(); out_begin("Bytes" + startArray(aid_len) + "b {"); printBytes(in, aid_len); out_end("};"); // Bytes[] out_println(in.readUnsignedShort() + "; // install method offset"); out_end("};"); // applet } out_end("};"); // applets endComponent(in); } void decodeImport(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int package_count = in.readUnsignedByte(); out_begin(startArray(package_count) + "b { // packages"); for (int i = 0; i < package_count; i++) { out_begin("{ // package " + i); out_println(in.readUnsignedByte() + "b; // minor version"); out_println(in.readUnsignedByte() + "b; // major version"); int aid_len = in.readUnsignedByte(); out_begin("Bytes" + startArray(aid_len) + "b {"); printBytes(in, aid_len); out_end("};"); // Bytes[] out_end("};"); // package info } out_end("};"); // package info endComponent(in); } static String[] refNames = { "Classref", "InstanceFieldref", "VirtualMethodref", "SuperMethodref", "StaticFieldref", "StaticMethodref" }; void decodeConstantPool(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int items_count = in.readUnsignedShort(); out_begin(startArray(items_count) + " { // items"); for (int i = 0; i < items_count; i++) { int tag = in.readUnsignedByte(); int info1 = in.readUnsignedByte(), info2 = in.readUnsignedByte(), info3 = in.readUnsignedByte(); out_print(tag + "b "); if ((tag > 0) && (tag <= 6)) { if ((info1 & 0x80) == 0) { if (tag <= 4) { out_print(((info1 << 8) | info2) + " " + info3 + "b;"); } else { out_print(info1 + "b " + ((info2 << 8) | info3) + ";"); } out.print(" // internal "); } else { out.print(info1 + "b " + info2 + "b " + info3 + "b;"); out.print(" // external "); } out.println(refNames[tag - 1]); } else { out.print(info1 + "b " + info2 + "b " + info3 + "b;"); out.println(" // unknown tag "); } } out_end("};"); // CP array endComponent(in); } void printClassref(DataInputStream in) throws IOException { int info1 = in.readUnsignedByte(), info2 = in.readUnsignedByte(); if ((info1 & 0x80) == 0) { out_print(((info1 << 8) | info2) + ";"); out_print(" // internal "); } else { out_print(info1 + "b " + info2 + "b;"); out_print(" // external "); } out_println(" Classref "); } void decodeClass(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); for (int i = 0; in.available() > 0; i++) { out_begin("{ // class " + i); int bitfield = in.readUnsignedByte(); int interface_count = bitfield & 0x0F; out_print("0x"); printByteHex(out, bitfield); out.println("; // bitfield"); if ((bitfield & 0x80) != 0) { // interface for (int k = 0; k < interface_count; k++) { printClassref(in); } } else { // class printClassref(in); out_println(in.readUnsignedByte() + "b; // declared instance size"); out_println(in.readUnsignedByte() + "b; // first reference token"); out_println(in.readUnsignedByte() + "b; // reference count"); out_println(in.readUnsignedByte() + "b; // public method table base"); int pumrc = in.readUnsignedByte(); out_println(pumrc + "b; // public method table count"); out_println(in.readUnsignedByte() + "b; // package method table base"); int pamrc = in.readUnsignedByte(); out_println(pamrc + "b; // package method table count"); out_begin("{ // public method table"); for (int k = 0; k < pumrc; k++) { out_println(in.readUnsignedShort() + ";"); } out_end("};"); out_begin("{ // package method table"); for (int k = 0; k < pamrc; k++) { out_println(in.readUnsignedShort() + ";"); } out_end("};"); out_begin("{ // implemented interfaces"); for (int k = 0; k < interface_count; k++) { out_begin("{ // interface " + k); printClassref(in); int count = in.readUnsignedByte(); out_begin("Bytes" + startArray(count) + "b {"); printBytes(in, count); out_end("};"); // Bytes[] out_end("};"); } out_end("};"); } out_end("};"); } endComponent(in); } void decodeDescriptor(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); methodsLengths = new ArrayList<>(); methodsOffsets = new ArrayList<>(); int class_count = in.readUnsignedByte(); out_begin(startArray(class_count) + "b { // classes"); for (int c = 0; c < class_count; c++) { out_begin("{ // class " + c); out_println(in.readUnsignedByte() + "b; // token"); out_print("0x"); printByteHex(out, in.readUnsignedByte()); out.println("; // flags"); printClassref(in); int icount = in.readUnsignedByte(); out_println(icount + "b; // interface count"); int fcount = in.readUnsignedShort(); out_println(fcount + "; // field count"); int mcount = in.readUnsignedShort(); out_println(mcount + "; // method count"); if (icount != 0) { out_begin("{ // interfaces"); for (int i = 0; i < icount; i++) { printClassref(in); } out_end("};"); } for (int i = 0; i < fcount; i++) { out_begin("{ // field " + i); out_println(in.readUnsignedByte() + "b; // token"); int flags = in.readUnsignedByte(); out_print("0x"); printByteHex(out, flags); out.println("; // flags"); if ((flags & 0x08) == 0) { printClassref(in); out_println(in.readUnsignedByte() + "b; // token"); } else { // static field int info1 = in.readUnsignedByte(), info2 = in.readUnsignedByte(), info3 = in.readUnsignedByte(); if ((info1 & 0x80) == 0) { out_print(info1 + "b " + ((info2 << 8) | info3) + ";"); out.println(" // internal field"); } else { out.print(info1 + "b " + info2 + "b " + info3 + "b;"); out.println(" // external field"); } } int type = in.readUnsignedShort(); if ((type & 0x8000) == 0) { out_println(type + "; // reference type"); } else { out_print("0x"); printByteHex(out, type >> 8); printByteHex(out, type); out.println("; // primitive type"); } out_end("};"); } for (int i = 0; i < mcount; i++) { int token = in.readUnsignedByte(); int flags = in.readUnsignedByte(); int m_offset = in.readUnsignedShort(); int t_offset = in.readUnsignedShort(); int bytecode_count = in.readUnsignedShort(); if (m_offset != 0) { out_begin("{ // method " + i + " (" + methodsLengths.size() + ")"); methodsLengths.add(bytecode_count); methodsOffsets.add(m_offset); } else { out_begin("{ // method " + i); } out_println(token + "b; // token"); out_print("0x"); printByteHex(out, flags); out.println("; // flags"); out_println(m_offset + "; // method offset"); out_println(t_offset + "; // type offset"); out_println(bytecode_count + "; // bytecode count"); out_println(in.readUnsignedShort() + "; // exception handler count"); out_println(in.readUnsignedShort() + "; // exception handler index"); out_end("};"); } out_end("};"); // class i } out_end("}; // classes"); int cp_count = in.readUnsignedShort(); out_begin(startArray(cp_count) + " { // constant pool types"); for (int i = 0; i < cp_count; i++) { int type = in.readUnsignedShort(); if (type == 0xFFFF) { out_println("0xFFFF;"); } else { out_println(type + "; "); } } out_end("}; // constant pool types"); out_begin("{ // type descriptors"); for (int i = 0; in.available() > 0; i++) { int nibble_count = in.readUnsignedByte(); out_print(nibble_count + "b; "); printBytes(in, (nibble_count + 1) / 2); } out_end("}; // type descriptors"); endComponent(in); } void decodeMethod(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int handler_count = in.readUnsignedByte(); out_begin(startArray(handler_count) + "b { // exception handlers"); for (int i = 0; i < handler_count; i++) { out_print(in.readUnsignedShort() + ", "); int bitfield = in.readUnsignedShort(); out.print("0x"); printByteHex(out, bitfield >> 8); printByteHex(out, bitfield); out.print(", " + in.readUnsignedShort() + ", "); out.println(in.readUnsignedShort() + "; // handler " + i); } out_end("};"); // handlers if (methodsLengths == null) { out.println("// Descriptor.cap absent - methods not printed"); } else { int f_offset = 1 + handler_count * 8; for (int i = 0; i < methodsLengths.size(); i++) { out_begin("{ // method " + i); int m_offset = methodsOffsets.get(i); if (m_offset != f_offset) { out.println("file offset=" + f_offset + " but m_offset=" + m_offset); break; } int bitfield = in.readUnsignedByte(); if ((bitfield & 0x80) == 0) { out_print("0x"); printByteHex(out, bitfield); out.println("; // flags, max_stack"); out_print("0x"); printByteHex(out, in.readUnsignedByte()); out.println("; // nargs, max_locals"); f_offset += 2; } else { out_print("0x"); printByteHex(out, bitfield); out.println("; // flags, padding"); out_println(in.readUnsignedByte() + "b; // max_stack"); out_println(in.readUnsignedByte() + "b; // nargs"); out_println(in.readUnsignedByte() + "b; // max_locals"); f_offset += 4; } int bytecode_count = methodsLengths.get(i); out_begin("{ // bytecodes"); printBytes(in, bytecode_count); f_offset += bytecode_count; out_end("};"); out_end("};"); } } endComponent(in); } void decodeStaticField(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int image_size = in.readUnsignedShort(); out_println(image_size + "; // image size"); int reference_count = in.readUnsignedShort(); out_println(reference_count + "; // reference count"); int array_init_count = in.readUnsignedShort(); out_begin(startArray(array_init_count) + " { // array_init_info"); for (int i = 0; i < array_init_count; i++) { out_println(in.readUnsignedByte() + "b // type "); int count = in.readUnsignedShort(); out_begin("Bytes" + startArray(count) + "s { // values"); printBytes(in, count); out_end("};"); // Bytes[] } out_end("};"); // array_init_info int default_value_count = in.readUnsignedShort(); out_println(default_value_count + "; // default value count"); int non_default_value_count = in.readUnsignedShort(); out_begin("Bytes" + startArray(non_default_value_count) + "s { // non default values"); printBytes(in, non_default_value_count); out_end("};"); // Bytes[] endComponent(in); } void decodeRefLocation(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int byte_index_count = in.readUnsignedShort(); out_begin("Bytes" + startArray(byte_index_count) + "s { // offsets to byte indices"); printBytes(in, byte_index_count); out_end("};"); // Bytes[] byte_index_count = in.readUnsignedShort(); out_begin("Bytes" + startArray(byte_index_count) + "s { // offsets to byte2 indices"); printBytes(in, byte_index_count); out_end("};"); // Bytes[] endComponent(in); } void decodeExport(String inpName) throws IOException { DataInputStream in = beginComponent(inpName); int class_count = in.readUnsignedByte(); out_begin(startArray(class_count) + "b { // classes"); for (int i = 0; i < class_count; i++) { out_begin("{ // class " + i); out_println(in.readUnsignedShort() + "; // class offset"); int fcount = in.readUnsignedByte(); out_println(fcount + "b; // static field count"); int mcount = in.readUnsignedByte(); out_println(mcount + "b; // static method count"); out_begin("{ // static field offsets"); for (int j = 0; j < fcount; j++) { out_println(in.readUnsignedShort() + "; // field " + j + " offset"); } out_end("};"); out_begin("{ // static method offsets"); for (int j = 0; j < mcount; j++) { out_println(in.readUnsignedShort() + "; // method " + j + " offset"); } out_end("};"); out_end("};"); // class i } out_end("};"); // classes endComponent(in); } /*========================================================*/ /** * Constructor. */ public Main(PrintWriter out, String program) { this.out = out; this.program = program; } public void error(String msg) { out.println(program + ": " + msg); } /** * Usage */ public void usage() { out.println(i18n.getString("jcdec.usage")); out.println(i18n.getString("jcdec.opt.g")); out.println(i18n.getString("jcdec.opt.version")); } /** * Run the decoder */ public synchronized boolean decode(String argv[]) { // int flags = F_WARNINGS; long tm = System.currentTimeMillis(); ArrayList vargs = new ArrayList<>(); ArrayList vj = new ArrayList<>(); boolean nowrite = false; int addOptions = 0; // Parse arguments for (int i = 0; i < argv.length; i++) { String arg = argv[i]; if (arg.equals("-g")) { printDetails = true; vargs.add(arg); } else if (arg.equals("-v")) { DebugFlag = true; vargs.add(arg); out.println("arg[" + i + "]=" + argv[i] + "/verbose"); } else if (arg.equals("-version")) { out.println(ProductInfo.FULL_VERSION); } else if (arg.startsWith("-")) { //out.println("arg["+i+"]="+argv[i]+"/invalid flag"); error(i18n.getString("jcdec.error.invalid_flag", arg)); usage(); return false; } else { vargs.add(arg); vj.add(arg); } } if (vj.isEmpty()) { usage(); return false; } // String[] names = new String[vj.size()]; // vj.copyInto(names); String[] names = null; names = vj.toArray(names); decode: for (int k = 0; k < names.length; k++) { String inpname = names[k]; try { if (inpname.endsWith(".cap")) { String shortName = inpname.substring(0, inpname.length() - 4); if (shortName.endsWith("Header")) { decodeHeader(inpname); } else if (shortName.endsWith("Directory")) { decodeDirectory(inpname); } else if (shortName.endsWith("Applet")) { decodeApplet(inpname); } else if (shortName.endsWith("Import")) { decodeImport(inpname); } else if (shortName.endsWith("ConstantPool")) { decodeConstantPool(inpname); } else if (shortName.endsWith("Class")) { decodeClass(inpname); } else if (shortName.endsWith("Descriptor")) { decodeDescriptor(inpname); } else if (shortName.endsWith("Method")) { decodeMethod(inpname); } else if (shortName.endsWith("StaticField")) { decodeStaticField(inpname); } else if (shortName.endsWith("RefLocation")) { decodeRefLocation(inpname); } else if (shortName.endsWith("Export")) { decodeExport(inpname); } else { continue decode; } out.println(""); } else if (inpname.endsWith(".exp")) { decodeExp(inpname); out.println(""); } continue decode; } catch (FileNotFoundException ee) { error(i18n.getString("jcdec.error.cannot_read", inpname)); } catch (Error ee) { ee.printStackTrace(); error(i18n.getString("jcdec.error.fatal_error")); } catch (Exception ee) { ee.printStackTrace(); error(i18n.getString("jcdec.error.fatal_exception")); } return false; } return true; } /** * Main program */ public static void main(String argv[]) { Main decoder = new Main(new PrintWriter(new uEscWriter(System.out)), "jcdec"); System.exit(decoder.decode(argv) ? 0 : 1); } }