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 }