File indexing completed on 2024-05-26 04:44:33

0001 package mso.generator;
0002 
0003 import java.io.FileWriter;
0004 import java.io.IOException;
0005 import java.io.PrintWriter;
0006 import java.util.regex.Matcher;
0007 import java.util.regex.Pattern;
0008 
0009 import mso.generator.utils.Choice;
0010 import mso.generator.utils.Limitation;
0011 import mso.generator.utils.MSO;
0012 import mso.generator.utils.Member;
0013 import mso.generator.utils.Stream;
0014 import mso.generator.utils.Struct;
0015 import mso.generator.utils.Type;
0016 import mso.generator.utils.TypeRegistry;
0017 
0018 public class JavaParserGenerator {
0019     void generate(MSO mso, String dir, String packagename, String classname)
0020             throws IOException {
0021         FileWriter fout = new FileWriter(dir + "/"
0022                 + packagename.replace('.', '/') + "/" + classname + ".java");
0023         PrintWriter out = new PrintWriter(fout);
0024         out.println("package " + packagename + ";");
0025         out.println("import java.io.IOException;");
0026         out.println("public class " + classname + " {");
0027         out.println(
0028                 "    Object parse(String key, LEInputStream in) throws IOException {");
0029         boolean first = true;
0030         for (Stream s : mso.streams) {
0031             out.print("        ");
0032             if (first) {
0033                 first = false;
0034             } else {
0035                 out.print("} else ");
0036             }
0037             out.println("if (\"" + s.key + "\".equals(key)) {"); // TODO: fix
0038             // for
0039             // \001 and \005
0040             // prefix
0041             out.println("            return parse" + s.type + "(in);");
0042         }
0043         out.println("        } else {");
0044         out.println("            return parseTODOS(in);");
0045         out.println("        }");
0046         out.println("    }");
0047 
0048         out.println(
0049                 "    void serialize(String key, Object o, LEOutputStream out) throws IOException {");
0050         first = true;
0051         for (Stream s : mso.streams) {
0052             out.print("        ");
0053             if (first) {
0054                 first = false;
0055             } else {
0056                 out.print("} else ");
0057             }
0058             out.println("if (\"" + s.key + "\".equals(key)) {"); // TODO: fix
0059             // for
0060             // \001 and \005
0061             // prefix
0062             out.println("            write((" + s.type + ")o, out);");
0063         }
0064         out.println("        } else {");
0065         out.println("            write((TODOS)o, out);");
0066         out.println("        }");
0067         out.println("    }");
0068 
0069         for (Struct s : mso.structs) {
0070             printStructureParser(out, s);
0071             printStructureWriter(out, s);
0072         }
0073 
0074         out.println("}");
0075 
0076         for (Struct s : mso.structs) {
0077             printStructureClass(out, s);
0078         }
0079 
0080         out.close();
0081         fout.close();
0082     }
0083 
0084     private static void printStructureParser(PrintWriter out, Struct s) {
0085         out.println("    " + s.name + " parse" + s.name
0086                 + "(LEInputStream in) throws IOException  {");
0087         out.println("        " + s.name + " _s = new " + s.name + "();");
0088         if (s.containsKnownLengthArrayMember) {
0089             out.println("        int _c;");
0090         }
0091         boolean variableArray = false;
0092         for (Member m : s.members) {
0093             if (m.isArray && m.count == null && m.size == null) {
0094                 variableArray = s.containsUnknownLengthArrayMember;
0095             }
0096         }
0097         if (s.containsOptionalMember || variableArray || s.containsChoice) {
0098             out.println("        Object _m;");
0099         }
0100         if (variableArray) {
0101             out.println("        boolean _atend;");
0102         }
0103         for (Member m : s.members) {
0104             printStructureMemberParser(out, m);
0105         }
0106         if (s.name.contains("RecordHeader")) {
0107             out.println("System.out.println(in.getPosition()+\" \"+_s);");
0108         }
0109         out.println("        return _s;");
0110         out.println("    }");
0111     }
0112 
0113     private static void printStructureWriter(PrintWriter out, Struct s) {
0114         out.println("    void write(" + s.name
0115                 + " _s, LEOutputStream out) throws IOException  {");
0116         for (Member m : s.members) {
0117             printStructureMemberWriter(out, m);
0118         }
0119         out.println("    }");
0120     }
0121 
0122     private static void printStructureMemberWriter(PrintWriter out, Member m) {
0123         String s = "        ";
0124         if (m.condition != null) {
0125             out.println(
0126                     "        if (" + getExpression("_s", m.condition) + ") {");
0127             s = s + "    ";
0128         }
0129         if (m.isChoice) {
0130             boolean first = true;
0131             Choice c = (Choice) m.type();
0132             for (String t : c.getChoiceNames()) {
0133                 out.print(s);
0134                 if (!first) {
0135                     out.print("} else ");
0136                 }
0137                 first = false;
0138                 out.println("if (_s." + m.name + " instanceof " + t + ") {");
0139                 out.println(
0140                         s + "    write((" + t + ")_s." + m.name + ", out);");
0141             }
0142             out.println(s + "}");
0143         } else if (m.isArray) {
0144             String t = getTypeName(m);
0145             out.println(s + "for (" + t + " _i: _s." + m.name + ") {");
0146             if (m.isStruct) {
0147                 out.println(s + "    write(_i, out);");
0148             } else {
0149                 out.println(s + "    out.write" + m.type().name + "(_i);");
0150             }
0151             out.println(s + "}");
0152         } else if (m.isStruct) {
0153             out.print(s);
0154             if (m.isOptional) {
0155                 out.print("if (_s." + m.name + " != null) ");
0156             }
0157             out.println("write(_s." + m.name + ", out);");
0158         } else {
0159             out.println(
0160                     s + "out.write" + m.type().name + "(_s." + m.name + ");");
0161         }
0162         if (m.condition != null) {
0163             out.println("        }");
0164         }
0165     }
0166 
0167     private static String getTypeName(Member m) {
0168         final Type t = m.type();
0169         final TypeRegistry r = m.registry;
0170         if (t instanceof Struct) {
0171             return m.type().name;
0172         } else if (t instanceof Choice) {
0173             return "Object";
0174         } else if (t == r.bit) {
0175             return "boolean";
0176         } else if (t == r.uint2 || t == r.uint3 || t == r.uint4 || t == r.uint5
0177                 || t == r.uint6 || t == r.uint7 || t == r.uint8) {
0178             return "byte";
0179         } else if (t == r.uint9 || t == r.uint12 || t == r.uint13
0180                 || t == r.uint14 || t == r.uint15 || t == r.int16) {
0181             return "short";
0182         } else if (t == r.uint16 || t == r.uint20 || t == r.uint30
0183                 || t == r.uint32 || t == r.int32) {
0184             return "int";
0185         }
0186         return t.name;
0187     }
0188 
0189     private static String getMemberDeclaration(Member m) {
0190         if (m.isArray) {
0191             if (m.count == null) {
0192                 return "final java.util.List<" + m.type().name + "> " + m.name
0193                         + " = new java.util.ArrayList<" + m.type().name + ">()";
0194             } else {
0195                 return getTypeName(m) + "[] " + m.name;
0196             }
0197         } else {
0198             return getTypeName(m) + " " + m.name;
0199         }
0200     }
0201 
0202     private static void printStructureClass(PrintWriter out, Struct s) {
0203         out.println("class " + s.name + " {");
0204         for (Member m : s.members) {
0205             String d = getMemberDeclaration(m);
0206             out.println("    " + d + ";");
0207         }
0208 
0209         // function toString
0210         out.println("    public String toString() {");
0211         out.println("        String _s = \"" + s.name + ":\";");
0212         for (Member m : s.members) {
0213             out.print("        _s = _s + \"" + m.name + ": \" + String.valueOf("
0214                     + m.name + ") + \"");
0215             if (m.isInteger && !m.isArray) {
0216                 out.print("(\" + Integer.toHexString(" + m.name
0217                         + ").toUpperCase() + \")");
0218             }
0219             out.println(", \";");
0220         }
0221         out.println("        return _s;");
0222         out.println("    }");
0223         out.println("}");
0224 
0225     }
0226 
0227     private static String prependStructureToExpression(String expression,
0228             String structureName) {
0229         if (expression.length() > 0) {
0230             Pattern p = Pattern.compile("([^.\\w])([.a-zA-Z])");
0231             Matcher m = p.matcher(expression);
0232             expression = m.replaceAll("$1" + structureName + ".$2");
0233             p = Pattern.compile("^([a-zA-Z])");
0234             m = p.matcher(expression);
0235             expression = m.replaceAll(structureName + ".$1");
0236         }
0237         return expression;
0238     }
0239 
0240     private static void printStructureMemberParser(PrintWriter out, Member m) {
0241         String s = "        ";
0242         String condition = null;
0243         if (m.condition != null) {
0244             condition = prependStructureToExpression(m.condition, "_s");
0245             s = s + "    ";
0246             out.println("        if (" + condition + ") {");
0247         }
0248         String count = null;
0249         if (m.count != null) {
0250             count = prependStructureToExpression(m.count, "_s");
0251         }
0252         String parse;
0253         if (m.isStruct) {
0254             parse = "parse" + m.type().name + "(in);";
0255         } else {
0256             parse = "in.read" + m.type().name + "();";
0257         }
0258 
0259         if (m.isChoice) {
0260             printChoiceParser(out, s, m);
0261             return;
0262         }
0263         if (m.isArray && m.count == null) {
0264             if (m.size != null) {
0265                 printFixedSizeArrayParser(out, s, m, m.size);
0266             } else {
0267                 // array for which no size is given: parse items until one fails
0268                 printVariableArrayParser(out, s, m);
0269             }
0270             return;
0271         }
0272         if (m.isOptional) {
0273             printOptionalMemberParser(out, s, m);
0274             return;
0275         }
0276         if (count != null) {
0277             out.println(s + "_c = " + count + ";");
0278         }
0279         out.print(s + "_s." + m.name + " = ");
0280         if (count != null) {
0281             if (m.type() == m.registry.uint8) {
0282                 out.println("in.readBytes(_c);");
0283             } else {
0284                 out.println("new " + getTypeName(m) + "[_c];");
0285                 out.println(s + "for (int _j=0; _j<_c; ++_j) {");
0286                 out.println(s + "    _s." + m.name + "[_j] = " + parse);
0287                 printLimitationCheck(out, "            ",
0288                         "_s." + m.name + "[_j]", m);
0289                 out.println(s + "}");
0290             }
0291         } else {
0292             out.println(parse);
0293             printLimitationCheck(out, "        ", "_s." + m.name, m);
0294         }
0295         if (condition != null) {
0296             out.println("        }");
0297         }
0298     }
0299 
0300     private static void printChoiceParser(PrintWriter out, String s, Member m) {
0301         String closing = "";
0302         String exception = "_x";
0303         out.println(s + "_m = in.setMark();");
0304         Choice c = (Choice) m.type();
0305         String choices[] = c.getChoiceNames();
0306         int length = (m.isOptional) ? choices.length : choices.length - 1;
0307         for (int i = 0; i < length; ++i) {
0308             out.println(s + "try {");
0309             out.println(
0310                     s + "    _s." + m.name + " = parse" + choices[i] + "(in);");
0311             out.println(s + "} catch (IOException " + exception + ") {");
0312             out.println(s + "    if (!(" + exception
0313                     + " instanceof IncorrectValueException) && !(" + exception
0314                     + " instanceof java.io.EOFException)) throw " + exception
0315                     + ";");
0316             // out
0317             // .println(s
0318             // + " if (in.distanceFromMark(_m) > 16) throw new IOException("
0319             // + exception + ");//onlyfordebug");
0320             out.println(s + "    in.rewind(_m);");
0321             exception = exception + "x";
0322             closing = closing + "}";
0323         }
0324         if (!m.isOptional) {
0325             out.println(s + "    _s." + m.name + " = parse"
0326                     + choices[choices.length - 1] + "(in);");
0327         }
0328         out.println(s + closing + " finally {");
0329         out.println(s + "    in.releaseMark(_m);");
0330         out.println(s + "}");
0331     }
0332 
0333     private static void printFixedSizeArrayParser(PrintWriter out, String s, Member m,
0334             String msize) {
0335         out.println(s + "int _startPos = in.getPosition();");
0336         out.println(s + "while (in.getPosition() - _startPos < "
0337                 + getExpression("_s", msize) + ") {");
0338         out.println(s + "    " + m.type().name + " _t = parse" + m.type().name
0339                 + "(in);");
0340         out.println(s + "    _s." + m.name + ".add(_t);");
0341         out.println(s + "}");
0342     }
0343 
0344     private static void printVariableArrayParser(PrintWriter out, String s, Member m) {
0345         out.println(s + "_atend = false;");
0346         out.println(s + "while (!_atend) {");
0347         // out
0348         // .println(s
0349         // +
0350         // " System.out.println(\"round \"+(_i++) + \" \" +
0351         // in.getPosition());");
0352         out.println(s + "    _m = in.setMark();");
0353         out.println(s + "    try {");
0354         out.println(s + "        " + m.type().name + " _t = parse"
0355                 + m.type().name + "(in);");
0356         out.println(s + "        _s." + m.name + ".add(_t);");
0357         out.println(s + "    } catch(IncorrectValueException _e) {");
0358         // out
0359         // .println(s
0360         // +
0361         // " if (in.distanceFromMark(_m) > 16) throw new
0362         // IOException(_e);//onlyfordebug");
0363         out.println(s + "        _atend = true;");
0364         out.println(s + "        in.rewind(_m);");
0365         out.println(s + "    } catch(java.io.EOFException _e) {");
0366         out.println(s + "        _atend = true;");
0367         out.println(s + "        in.rewind(_m);");
0368         out.println(s + "    } finally {");
0369         out.println(s + "        in.releaseMark(_m);");
0370         out.println(s + "   }");
0371         out.println(s + "}");
0372     }
0373 
0374     private static void printOptionalMemberParser(PrintWriter out, String s, Member m) {
0375         out.println(s + "_m = in.setMark();");
0376         out.println(s + "try {");
0377         out.println(
0378                 s + "    _s." + m.name + " = parse" + m.type().name + "(in);");
0379         out.println(s + "} catch(IncorrectValueException _e) {");
0380         out.println(s
0381                 + "    if (in.distanceFromMark(_m) > 16) throw new IOException(_e);//onlyfordebug");
0382         out.println(s + "    in.rewind(_m);");
0383         out.println(s + "} catch(java.io.EOFException _e) {");
0384         out.println(s + "    in.rewind(_m);");
0385         out.println(s + "} finally {");
0386         out.println(s + "    in.releaseMark(_m);");
0387         out.println(s + "}");
0388     }
0389 
0390     private static void printLimitationCheck(PrintWriter out, String s, String name,
0391             Member m) {
0392         for (Limitation l : m.limitations) {
0393             String mname = l.name;
0394             if (!"".equals(mname)) {
0395                 mname = name + "." + mname;
0396             } else {
0397                 mname = name;
0398             }
0399             final String condition = getCondition(mname, l);
0400 
0401             out.println(s + "if (!(" + condition + ")) {");
0402             String exceptionType = "IncorrectValueException";
0403             // if (!condition.contains(".recType")
0404             // && !condition.contains(".recVer")
0405             // && !condition.contains(".recInstance")) {
0406             // // special value for debugging: we only have recoverable
0407             // // exceptions in record headers, remove this in final code
0408             // exceptionType = "IOException";
0409             // }
0410             out.println(s + "    throw new " + exceptionType
0411                     + "(in.getPosition() + \"" + condition
0412                     + " for value \" + String.valueOf(" + name + ") );");
0413             out.println(s + "}");
0414         }
0415     }
0416 
0417     private static String getExpression(String structure, String expression) {
0418         if (Pattern.matches(".*[A-Za-z].*", expression)) {
0419             return prependStructureToExpression(expression, structure);
0420         }
0421         return structure + expression;
0422     }
0423 
0424     private static String getCondition(String mname, Limitation l) {
0425         final String value = l.value;
0426         final String expression = l.expression;
0427         if (value != null) {
0428             return getCondition(mname, value);
0429         } else if (expression != null) {
0430             return getExpression(mname, expression);
0431         } else {
0432             throw new Error("Either expression or value should be set.");
0433         }
0434     }
0435 
0436     private static String getCondition(String name, String value) {
0437         String cmp = " == ";
0438         String cmb = " || ";
0439         if (value.startsWith("!")) {
0440             value = value.substring(1);
0441             cmp = " != ";
0442             cmb = " && ";
0443         }
0444         if (value.contains("|")) {
0445             String values[] = value.split("\\|");
0446             String c = name + cmp + values[0];
0447             for (int i = 1; i < values.length; ++i) {
0448                 c = c + cmb + name + cmp + values[i];
0449             }
0450             return c;
0451         }
0452         return name + cmp + value;
0453     }
0454 }