Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * @(#)StructParser.java  
    *
    * Copyright (c) 2000-2012 Werner Randelshofer, Goldau, Switzerland.
    * All rights reserved.
    *
    * You may not use, copy or modify this file, except in compliance with the
    * license agreement you entered into with Werner Randelshofer.
    * For details see accompanying license terms.
   */
  package org.monte.media.binary;
  
  import java.io.*;
  import java.util.*;
  import java.text.*;
Parses structured binary data using C-like data declarations. Syntax:

 Declarations ::= { MagicDeclaration | DescriptionDeclaration | EnumDeclaration | SetDeclaration | TypedefDeclaration } EOF
 MagicDeclaration ::= "magic" identifier ("ushort" hexLiteral[".." hexLiteral] | stringLiteral) ";"
 DescriptionDeclaration ::= "description" identifier stringLiteral "," stringLiteral ";"
 EnumDeclaration ::= EnumSpecifier identifier ";"
 SetDeclaration ::= SetSpecifier identifier ";"
 TypedefDeclaration ::= "typedef" TypeSpecifier identifier ";"
 EnumSpecifier ::= "enum" ( identifier | "{" identifier ["=" magicOrIntLiteral] {"," identifier ["=" intLiteral]} "}" )
 SetSpecifier ::= "set" ( identifier | "{" identifier "=" intLiteral {"," identifier "=" intLiteral} "}" )
 TypeSpecifier ::= ( StructSpecifier | (PrimitiveSpecifier [EnumSpecifier | SetSpecifier]) ) [ArrayList]
 StructSpecifier ::= "struct (identifier | "{" MemberDeclaration {"," MemberDeclaration } "}" )
 MemberDeclaration ::= TypeSpecifier identifier [ArrayList] ";"
 PrimitiveSpecifier ::= "uint1" | "uint2" | "uint4" | "uint5" | "uint8" 
                         | "uint12" | "uint16" | "uint31LE" | "uint32"
                         | "int9" | "int16" | "int32"
                         | "ubyte" | "byte" | "short"
                         | "ushort" | "int" | "long" | "float" | "double"
                         | "extended"
                         | "char" | "charbyte" | "cstring" | "utf8" | "pstring"
                         | "pstring32"
                         | "utf16le" | "magic" | "mactimestamp" | "bcd2"
                         | "bcd4"
                         | "fixed16d16" | "fixed2d30" | "fixed8d8"
                         | "ataricolor"
 ArrayList ::= "[" [ArraySize] "]" {"," identifier "[" [ArraySize] "]" }
 ArraySize ::= () | intLiteral [("-"|"+"|"=="|"!=") intLiteral]
 

Author(s):
Werner Randelshofer, Hausmatt 10, CH-6405 Goldau, Swityerland
Version:
$Id: StructParser.java 299 2013-01-03 07:40:18Z werner $
  
  public class StructParser extends Object {
  
      protected static final long MAC_TIMESTAMP_EPOCH = new GregorianCalendar(1904, ., 1).getTimeInMillis();
      private Declarations declarations;
  
      public StructParser() {
      }
  
      public StructParser(Reader rthrows IOExceptionParseException {
          parse(r);
      }
  
      public String getName(String magic) {
          return getName((Objectmagic);
      }
  
      public String getName(Object magic) {
          MagicDeclaration md = (MagicDeclaration..get(magic);
          DescriptionDeclaration dd = (md == null) ? null : (DescriptionDeclaration..get(md.identifier);
          return (dd == null) ? null : dd.name;
      }
  
      public String getIdentifierName(String magic) {
          MagicDeclaration md = (MagicDeclaration..get(magic);
          DescriptionDeclaration dd = (md == null) ? null : (DescriptionDeclaration..get(md.identifier);
          return (md == null) ? null : md.identifier;
      }
  
      public boolean isMagicDeclared(String magic) {
          return isMagicDeclared((Objectmagic);
      }
  
      public boolean isMagicDeclared(Object magic) {
          MagicDeclaration md = (MagicDeclaration..get(magic);
          return md != null;
      }
  
      public boolean isTypeDeclared(String magic) {
          return isTypeDeclared((Objectmagic);
      }
  
      public boolean isTypeDeclared(Object magic) {
         TypedefDeclaration typedef = null;
 
         //DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
         MagicDeclaration magicdef = (MagicDeclaration..get(magic);
         if (magicdef == null) {
             return false;
         }
         typedef = (TypedefDeclaration..get(magicdef.identifier);
         return typedef != null;
     }
 
     public String getDescription(String magic) {
         return getDescription((Objectmagic);
     }
 
     public String getDescription(Object magic) {
         MagicDeclaration md = (MagicDeclaration..get(magic);
         DescriptionDeclaration dd = (md == null) ? null : (DescriptionDeclaration..get(md.identifier);
         return (dd == null) ? null : dd.description;
     }
 
     public StructTableModel readStruct(String magicbyte[] data)
             throws IOException {
         return .readStruct(magicnew ByteArrayImageInputStream(data));
     }
 
     public StructTableModel readStruct(int magicbyte[] data)
             throws IOException {
         return .readStruct(magicnew ByteArrayImageInputStream(data));
     }
 
     public StructTableModel readStruct(String magicInputStream data)
             throws IOException {
         if (data instanceof ImageInputStream) {
             return .readStruct(magic, (ImageInputStreamdata);
         } else {
             return .readStruct(magicnew MemoryCacheImageInputStream(data));
         }
     }
 
     public StructTableModel readStruct(int magicInputStream data)
             throws IOException {
         if (data instanceof ImageInputStream) {
             return .readStruct(magic, (ImageInputStreamdata);
         } else {
             return .readStruct(magicnew MemoryCacheImageInputStream(data));
         }
     }

    
Consumes the number of bytes needed by the specified struct from the input stream, and returns them as a byte array.
 
     private static String errorMsg(String textStreamPosTokenizer scanner) {
         StringBuffer b = new StringBuffer();
         b.append("line ");
         b.append(Integer.toString(scanner.lineno()));
         /*        b.append(' ');
         b.append(Integer.toString(scanner.getStartPosition()));
         b.append("..");
         b.append(Integer.toString(scanner.getEndPosition()));*/
         b.append(": ");
         b.append(text);
         b.append(" instead of ");
         switch (scanner.ttype) {
             case .:
                 b.append('\'');
                 b.append(scanner.sval);
                 b.append('\'');
                 break;
             case .:
                 b.append("EOF");
                 break;
             case .:
                 b.append("EOL");
                 break;
             case .:
                 b.append(Double.toString(scanner.nval));
                 break;
             case '"':
                 b.append('"');
                 b.append(scanner.sval);
                 b.append('"');
                 break;
             default:
                 b.append('\'');
                 b.append((charscanner.ttype);
                 b.append('\'');
                 b.append("(0x");
                 b.append(Integer.toHexString(scanner.ttype));
                 b.append(')');
                 break;
         }
         return b.toString();
     }
 
     protected void parse(Reader r)
             throws IOExceptionParseException {
         StreamPosTokenizer scanner = new StreamPosTokenizer(r);
         scanner.resetSyntax();
         scanner.wordChars('a''z');
         scanner.wordChars('A''Z');
         scanner.wordChars(128 + 32, 255);
         scanner.wordChars('_''_');
         scanner.whitespaceChars(0, ' ');
         //scanner.commentChar('/');
         scanner.quoteChar('"');
         scanner.quoteChar('\'');
         scanner.parseNumbers();
         scanner.parseHexNumbers();
         scanner.slashSlashComments(true);
         scanner.slashStarComments(true);
         scanner.ordinaryChar(';');
         scanner.ordinaryChar('[');
         scanner.ordinaryChar(']');
         scanner.ordinaryChar('{');
         scanner.ordinaryChar('}');
         scanner.ordinaryChar('+');
         scanner.ordinaryChar('-');
 
          = new Declarations(scanner);
     }

    
Declarations expression.

 Declarations ::= { MagicDeclaration | DescriptionDeclaration | EnumDeclaration | SetDeclaration | TypedefDeclaration }
 
 
     protected static class Declarations {
 
         public Hashtable magics = new Hashtable();
         public Hashtable descriptions = new Hashtable();
         public Hashtable enums = new Hashtable();
         public Hashtable sets = new Hashtable();
         public Hashtable typedefs = new Hashtable();
 
         public Declarations(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
             while (scanner.nextToken() != .) {
                 if (scanner.ttype == .) {
                     if (scanner.sval.equals("magic")) {
                         scanner.pushBack();
                         MagicDeclaration md = new MagicDeclaration(scanner);
                         if (md.magic != null) {
                             .put(md.magicmd);
                         } else {
                             for (int i = md.ushortMagicFromi <= md.ushortMagicToi++) {
                                 .put(imd);
                             }
                         }
                     } else if (scanner.sval.equals("description")) {
                         scanner.pushBack();
                         DescriptionDeclaration dd = new DescriptionDeclaration(scanner);
                         .put(dd.identifierdd);
                     } else if (scanner.sval.equals("enum")) {
                         scanner.pushBack();
                         EnumDeclaration ed = new EnumDeclaration(scanner);
                         .put(ed.identifiered);
                     } else if (scanner.sval.equals("set")) {
                         scanner.pushBack();
                         SetDeclaration sd = new SetDeclaration(scanner);
                         .put(sd.identifiersd);
                     } else if (scanner.sval.equals("typedef")) {
                         scanner.pushBack();
                         TypedefDeclaration td = new TypedefDeclaration(scanner);
                         .put(td.identifiertd);
                     } else {
                         throw new ParseException(errorMsg("Declarations: Expected 'magic', 'description', 'enum', 'set' or 'typedef' "scanner));
                     }
                 }
             }
         }
 
         private StructTableModel readStruct(Object magicImageInputStream in)
                 throws IOException {
             Vector result = new Vector();
             TypedefDeclaration typedef = null;
 
             //DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
             MagicDeclaration magicdef = (MagicDeclaration.get(magic);
             if (magicdef == null) {
                 //System.out.println("StructParser.StructTableModel.readStruct() unknow magic:"+magic);
                 //new Exception().printStackTrace();
                 if (magic instanceof Integer) {
                     throw new IOException("unknown magic:" + Integer.toHexString((Integermagic));
                 } else {
                     throw new IOException("unknown magic:" + magic);
                 }
             }
             typedef = (TypedefDeclaration.get(magicdef.identifier);
             if (typedef == null) {
                 //System.out.println("StructParser.StructTableModel.readStruct() typedef not found for magic:"+magic+" magicdef.identifier:"+magicdef.identifier);
                 throw new IOException("unknown type:" + magicdef.identifier);
             }
             try {
                 Object obj = typedef.read(intypedef.identifierthisresult);
                 if (obj != null) {
                     StructTableModel.Value value = new StructTableModel.Value();
                     value.declaration = typedef.identifier;
                     value.value = obj;
                     result.addElement(value);
                 }
             } catch (EOFException e) {
             }
             return new StructTableModel(typedefresult);
         }
     }

    
MagicDeclaration expression.

 MagicDeclaration ::= "magic" identifier ("ushort" hexLiteral[".." hexLiteral] | stringLiteral) ";"
 
 
     protected static class MagicDeclaration {
 
         public String identifier;
        
If magic is null, then ushortMagicFrom/ushortMagicTo is used.
 
         public String magic;
         public int ushortMagicFrom;
         public int ushortMagicTo;
 
         public MagicDeclaration(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
             if (scanner.nextToken() != . || !scanner.sval.equals("magic")) {
                 throw new ParseException(errorMsg("MagicDeclaration: 'magic' expected"scanner));
             }
             if (scanner.nextToken() != .) {
                 throw new ParseException(errorMsg("MagicDeclaration: identifier expected"scanner));
             }
              = scanner.sval;
 
             if (scanner.nextToken() == .
                     && scanner.sval.equals("ushort")) {
                 if (scanner.nextToken() != .) {
                     throw new ParseException(errorMsg("MagicDeclaration: ushort literal expected"scanner));
                 }
                  = (intscanner.nval;
                 if (scanner.nextToken() == '.') {
                     if (scanner.nextToken() != '.') {
                         throw new ParseException(errorMsg("MagicDeclaration: interval literal expected"scanner));
                     }
                     if (scanner.nextToken() != .) {
                         throw new ParseException(errorMsg("MagicDeclaration: end interval literal expected"scanner));
                     }
                      = (intscanner.nval;
                 } else {
                      = ;
                     scanner.pushBack();
                 }
             } else {
                 if (scanner.ttype != '"') {
                     throw new ParseException(errorMsg("MagicDeclaration: string literal expected"scanner));
                 }
                  = scanner.sval;
             }
             if (scanner.nextToken() != ';') {
                 throw new ParseException(errorMsg("MagicDeclaration: ';' expected"scanner));
             }
         }
     }
     /*
     private static int parseHexLiteral(StreamPosTokenizer scanner)
     throws IOException, ParseException {
     scanner.
     if (scanner.nextToken() != StreamPosTokenizer.TT_NUMBER || scanner.nval != 0) {
     throw new ParseException(errorMsg("MagicDeclaration: hex literal expected",scanner));
     }
     System.out.println("StructParser.MagicDeclaration nval::"+scanner.nval);
     System.out.println("StructParser.MagicDeclaration next TOken:"+scanner.nextToken());
     
     }*/

    
DescriptionDeclaration expression.

 DescriptionDeclaration ::= "description" identifier stringLiteral "," stringLiteral ";"
 
 
     protected static class DescriptionDeclaration {
 
         public String identifier;
         public String name;
         public String description;
 
         public DescriptionDeclaration(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
             if (scanner.nextToken() != . || !scanner.sval.equals("description")) {
                 throw new ParseException(errorMsg("DescriptionDeclaration: 'magic' expected"scanner));
             }
             if (scanner.nextToken() != .) {
                 throw new ParseException(errorMsg("DescriptionDeclaration: identifier expected"scanner));
             }
              = scanner.sval;
             if (scanner.nextToken() != '"') {
                 throw new ParseException(errorMsg("DescriptionDeclaration: string literal (title) expected"scanner));
             }
              = scanner.sval;
             if (scanner.nextToken() != ',') {
                 throw new ParseException(errorMsg("DescriptionDeclaration: ',' expected"scanner));
             }
             if (scanner.nextToken() != '"') {
                 throw new ParseException(errorMsg("DescriptionDeclaration: string literal (description) expected"scanner));
             }
              = scanner.sval;
             while (scanner.nextToken() == '+') {
                 if (scanner.nextToken() != '"') {
                     throw new ParseException(errorMsg("DescriptionDeclaration: string literal (description) after '+' expected"scanner));
                 }
                  += scanner.sval;
             }
             scanner.pushBack();
             if (scanner.nextToken() != ';') {
                 throw new ParseException(errorMsg("DescriptionDeclaration: ';' expected"scanner));
             }
         }
     }

    
EnumDeclaration expression.

 EnumDeclaration ::= EnumSpecifier identifier ";"
 
 
     protected static class EnumDeclaration {
 
         public EnumSpecifier enumSpecifier;
         public String identifier;
 
         public EnumDeclaration(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
              = new EnumSpecifier(scanner);
 
             if (scanner.nextToken() != .) {
                 throw new ParseException(errorMsg("EnumDeclaration: identifier expected"scanner));
             }
              = scanner.sval;
 
             if (scanner.nextToken() != ';') {
                 throw new ParseException(errorMsg("EnumDeclaration: ';' expected"scanner));
             }
         }
     }

    
SetDeclaration expression.

 SetDeclaration ::= SetSpecifier identifier ";"
 
 
     protected static class SetDeclaration {
 
         public SetSpecifier setSpecifier;
         public String identifier;
 
         public SetDeclaration(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
              = new SetSpecifier(scanner);
 
             if (scanner.nextToken() != .) {
                 throw new ParseException(errorMsg("SetDeclaration: identifier expected"scanner));
             }
              = scanner.sval;
 
             if (scanner.nextToken() != ';') {
                 throw new ParseException(errorMsg("SetDeclaration: ';' expected"scanner));
             }
         }
     }

    
TypedefDeclaration expression.

 TypedefDeclaration ::= "typedef" TypeSpecifier identifier ";"
 
 
     protected static class TypedefDeclaration {
 
         public TypeSpecifier typeSpecifier;
         public String identifier;
 
         public TypedefDeclaration(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
             if (scanner.nextToken() != . || !scanner.sval.equals("typedef")) {
                 throw new ParseException(errorMsg("TypedefDeclaration: 'typedef' expected"scanner));
             }
 
              = new TypeSpecifier(scanner);
 
             if (scanner.nextToken() != .) {
                 throw new ParseException(errorMsg("TypedefDeclaration: identifier expected"scanner));
             }
              = scanner.sval;
 
             if (scanner.nextToken() != ';') {
                 throw new ParseException(errorMsg("TypedefDeclaration: ';' expected"scanner));
             }
             //System.out.println("typedef "+typeSpecifier+" "+identifier+";");
         }
 
         private int getResolvedType(Declarations declarationsthrows IOException {
             return .getResolvedPrimitiveType(declarations);
         }
 
         private Object read(ImageInputStream inString parentIdentifierDeclarations declarationsVector result)
                 throws IOException {
             return .read(inparentIdentifierdeclarationsresult);
         }
     }

    
EnumSpecifier expression.

 EnumSpecifier ::= "enum" ( identifier | "{" identifier ["=" intLiteral] {"," identifier ["=" intLiteral]} "}" )
 
 
     protected static class EnumSpecifier {
 
         public Hashtable members;
         public String identifier;
         public boolean isMagicEnum;
 
         public EnumSpecifier(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
             if (scanner.nextToken() != . || !scanner.sval.equals("enum")) {
                 throw new ParseException(errorMsg("EnumSpecifier: 'enum' expected"scanner));
             }
 
             if (scanner.nextToken() == .) {
                  = scanner.sval;
             } else if (scanner.ttype == '{') {
                 String name;
                 int value = -1;
                  = new Hashtable();
                 do {
                     if (scanner.nextToken() == '}') {
                         break;
                     }
                     if (scanner.ttype != .
                             && scanner.ttype != '"') {
                         throw new ParseException(errorMsg("EnumSpecifier: enumeration name expected"scanner));
                     }
                     name = scanner.sval;
 
                     if (scanner.nextToken() == '=') {
                         MagicOrIntLiteral literal = new MagicOrIntLiteral(scanner);
                         value = literal.intValue();
                          = literal.isMagic();
                     } else {
                         value++;
                         scanner.pushBack();
                     }
 
                     .put(new Integer(value), name);
                 } while (scanner.nextToken() == ',');
                 if (scanner.ttype != '}') {
                     throw new ParseException(errorMsg("EnumSpecifier: '}' expected"scanner));
                 }
             } else {
                 throw new ParseException(errorMsg("EnumSpecifier: identifier or '{' expected"scanner));
             }
              = scanner.sval;
         }
 
         public String toEnumString(int valueDeclarations declarations) {
             if ( != null) {
                 EnumDeclaration enumDecl = (EnumDeclarationdeclarations.enums.get();
                 if (enumDecl == null) {
                     throw new InternalError("Enum Declaration missing for " + );
                 }
                 return enumDecl.enumSpecifier.toEnumString(valuedeclarations);
             } else {
                 StringBuffer buf = new StringBuffer();
                 Integer intValue = new Integer(value);
                 if () {
                     buf.append('"');
                     buf.append(MagicOrIntLiteral.toMagic(value));
                     buf.append('"');
                 } else {
                     buf.append(Integer.toString(value));
                     /*
                     buf.append("0x");
                     buf.append(Integer.toHexString(value));*/
                 }
                 buf.append(" {");
                 if (.get(intValue) != null) {
                     buf.append(.get(intValue).toString());
                 }
                 buf.append('}');
                 return buf.toString();
             }
         }
 
         public String toEnumString(String valueDeclarations declarations) {
             if ( != null) {
                 EnumDeclaration enumDecl = (EnumDeclarationdeclarations.enums.get();
                 if (enumDecl == null) {
                     throw new InternalError("Enum Declaration missing for " + );
                 }
                 return enumDecl.enumSpecifier.toEnumString(valuedeclarations);
             } else {
                 if (value == null || value.length() != 4 || !) {
                     return value;
                 } else {
                     return toEnumString(MagicOrIntLiteral.toInt(value), declarations);
                 }
             }
         }
     }

    
SetSpecifier expression.

 SetSpecifier ::= "set" ( identifier | "{" identifier "=" intLiteral {"," identifier "=" intLiteral} "}" )
 
 
     protected static class SetSpecifier {
 
         public Hashtable members;
         public String identifier;
 
         public SetSpecifier(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
             if (scanner.nextToken() != . || !scanner.sval.equals("set")) {
                 throw new ParseException(errorMsg("SetSpecifier: 'set' expected"scanner));
             }
 
             if (scanner.nextToken() == .) {
                  = scanner.sval;
             } else if (scanner.ttype == '{') {
                 String name;
                 int value = 0;
                  = new Hashtable();
                 do {
 
                     if (scanner.nextToken() != . && scanner.ttype!='"') {
                         throw new ParseException(errorMsg("SetSpecifier: set name expected"scanner));
                     }
                     name = scanner.sval;
 
                     if (scanner.nextToken() == '=') {
                         value = (new IntLiteral(scanner)).intValue();
                     } else {
                         value = (value == 0) ? 1 : value << 1;
                         scanner.pushBack();
                     }
                     .put(new Integer(value), name);
                 } while (scanner.nextToken() == ',');
                 if (scanner.ttype != '}') {
                     throw new ParseException(errorMsg("SetSpecifier: '}' expected"scanner));
                 }
             } else {
                 throw new ParseException(errorMsg("SetSpecifier: identifier or '{' expected"scanner));
             }
              = scanner.sval;
         }
 
         public String toSetString(int valueDeclarations declarations) {
             if ( != null) {
                 SetDeclaration setDecl = (SetDeclarationdeclarations.sets.get();
                 if (setDecl == null) {
                     throw new InternalError("Set Declaration missing for " + );
                 }
                 return setDecl.setSpecifier.toSetString(valuedeclarations);
             } else {
                 StringBuffer buf = new StringBuffer();
                 buf.append("0x");
                 buf.append(Integer.toHexString(value));
                 buf.append(" {");
                 Enumeration enm = .keys();
                 boolean isFirst = true;
                 while (enm.hasMoreElements()) {
                     Object key = enm.nextElement();
                     int intKey = ((Numberkey).intValue();
                     if ((intKey == 0 && value == 0) || ((intKey & value) == intKey)) {
                         if (isFirst) {
                             isFirst = false;
                         } else {
                             buf.append(", ");
                         }
                         buf.append(.get(key).toString());
                     }
                 }
                 buf.append('}');
                 return buf.toString();
             }
         }
     }

    
TypeSpecifier expression.

 TypeSpecifier ::= ( StructSpecifier | (PrimitiveSpecifier [EnumSpecifier | SetSpecifier]) ) [ArrayList]
 ArrayList ::= "[" [ArraySize] "]" {"," identifier "[" [ArraySize] "]" }
 
 
     protected static class TypeSpecifier {
 
         public StructSpecifier structSpecifier;
         public PrimitiveSpecifier primitiveSpecifier;
         public EnumSpecifier enumSpecifier;
         public SetSpecifier setSpecifier;
         public Vector arrayList;
 
         public TypeSpecifier(StreamPosTokenizer scanner)
                 throws IOExceptionParseException {
             if (scanner.nextToken() == . && scanner.sval.equals("struct")) {
                 scanner.pushBack();
                  = new StructSpecifier(scanner);
             } else {
                 scanner.pushBack();
                  = new PrimitiveSpecifier(scanner);
 
                 scanner.nextToken();
                 if (scanner.ttype == . && scanner.sval.equals("enum")) {
                     scanner.pushBack();
                      = new EnumSpecifier(scanner);
                 } else if (scanner.ttype == . && scanner.sval.equals("set")) {
                     scanner.pushBack();
                      = new SetSpecifier(scanner);
                 } else {
                     scanner.pushBack();
                 }
             }
 
             // ArrayList Begin
             if (scanner.nextToken() == '[') {
                  = new Vector();
                 do {
                     .addElement(new ArraySize(scanner));
                     if (scanner.nextToken() != ']') {
                         throw new ParseException(errorMsg("MemberDeclaration: ']' expected"scanner));
                     }
                 } while (scanner.nextToken() == '[');
                 scanner.pushBack();
             } else {
                 scanner.pushBack();
             }
             // ArrayList End
         }
 
         private int getResolvedPrimitiveType(Declarations declarationsthrows IOException {
             if ( != null) {
                 return .;
             } else if ( != null) {
                 return .getResolvedPrimitveType(declarations);
             } else {
                 return .;
             }
         }
 
         private Object read(ImageInputStream inString parentIdentifierDeclarations declarationsString identifierVector result)
                 throws IOException {
             if ( != null) {
                 if ( != null) {
                     // ArrayList Begin
                     Enumeration enm = .elements();
                     while (enm.hasMoreElements()) {
                         ArraySize arraySize = (ArraySizeenm.nextElement();
                         int size = arraySize.getArraySize(declarationsresult);
                         if (size == .) {
                             try {
                                 for (int i = 0;; i++) {
                                     int loc = result.size();
                                     .read(inparentIdentifierdeclarationsresult);
 
                                     for (int j = locj < result.size(); j++) {
                                         StructTableModel.Value arrayValue = (StructTableModel.Valueresult.elementAt(j);
                                         arrayValue.index = (arrayValue.index == null) ? "[" + i + "]" : "[" + i + "]" + arrayValue.index;
                                     }
                                 }
                             } catch (EOFException e) {
                             }
                         } else {
                             for (int i = 0; i < sizei++) {
                                 int loc = result.size();
                                 .read(inparentIdentifierdeclarationsresult);
 
                                 for (int j = locj < result.size(); j++) {
                                     StructTableModel.Value arrayValue = (StructTableModel.Valueresult.elementAt(j);
                                     arrayValue.index = (arrayValue.index == null) ? "[" + i + "]" : "[" + i + "]" + arrayValue.index;
                                 }
                             }
                         }
                     }
                     return null;
                 } else {
                     .read(inparentIdentifierdeclarationsresult);
                     return null;
                 }
             } else if (.getResolvedPrimitveType(declarations) == .) {
                 if ( != null) {
                     StringBuffer buf = new StringBuffer();
                     buf.append('\"');
                     boolean hasValue = false;
 
                     // ArrayList Begin
                     Enumeration enm = .elements();
                     while (enm.hasMoreElements()) {
                         ArraySize arraySize = (ArraySizeenm.nextElement();
                         int size = arraySize.getArraySize(declarationsresult);
                         if (size == .) {
                             try {
                                 for (int i = 0;; i++) {
                                     //if (i > 0) {
                                     //  buf.append(", ");
                                     //}
                                     Object value = readValue(inparentIdentifier + "[" + i + "]"declarationsresult);
                                     if (value != null) {
                                         hasValue = true;
                                         if (value.toString().equals("0x20")) {
                                             buf.append(' ');
                                         } else {
                                             buf.append(value.toString());
                                         }
                                     }
                                 }
                             } catch (EOFException e) {
                             }
                         } else {
                             for (int i = 0; i < sizei++) {
                                 //if (i > 0) {
                                 //    buf.append(", ");
                                 //}
                                 Object value = readValue(inparentIdentifier + "[" + i + "]"declarationsresult);
                                 if (value != null) {
                                     hasValue = true;
                                     if (value.toString().equals("0x20")) {
                                         buf.append(' ');
                                     } else {
                                         buf.append(value.toString());
                                     }
                                 }
                             }
                         }
                     }
                     // ArrayList End
                     if (hasValue) {
                         buf.append('\"');
                         return buf.toString();
                     } else {
                         return null;
                     }
                 } else {
                     return readValue(inparentIdentifierdeclarationsresult);
                 }
             } else if (.getResolvedPrimitveType(declarations) == .) {
                 if ( != null) {
                     StringBuffer buf = new StringBuffer();
                     ByteArrayOutputStream bout = new ByteArrayOutputStream();
                     buf.append("0x");
                     boolean hasValue = false;
 
                     // ArrayList Begin
                     Enumeration enm = .elements();
                     while (enm.hasMoreElements()) {
                         ArraySize arraySize = (ArraySizeenm.nextElement();
                         int size = arraySize.getArraySize(declarationsresult);
                         if (size == .) {
                             try {
                                 for (int i = 0;; i++) {
                                     //if (i > 0) {
                                     //  buf.append(", ");
                                     //}
                                     Integer value = (IntegerreadValue(inparentIdentifier + "[" + i + "]"declarationsresult);
                                     if (value != null) {
                                         hasValue = true;
                                         String str = Integer.toHexString(value & 0xff);
                                         if (str.length() == 1) {
                                             buf.append('0');
                                         }
                                         buf.append(str);
                                         bout.write(value);
                                     }
                                 }
                             } catch (EOFException e) {
                             }
                         } else {
                             for (int i = 0; i < sizei++) {
                                 //if (i > 0) {
                                 //    buf.append(", ");
                                 //}
                                 Integer value = (IntegerreadValue(inparentIdentifier + "[" + i + "]"declarationsresult);
                                 if (value != null) {
                                     hasValue = true;
                                     String str = Integer.toHexString(value & 0xff);
                                     if (str.length() == 1) {
                                         buf.append('0');
                                     }
                                     buf.append(str);
                                     bout.write(value);
                                 }
                             }
                         }
                     }
                     // ArrayList End
                     if (hasValue) {
                         if (true) {
                             return bout.toByteArray();
                         }
                         //buf.append('}');
                         return buf.toString();
                     } else {
                         return null;
                     }
                 } else {
                     return readValue(inparentIdentifierdeclarationsresult);
                 }
             } else {
                 if ( != null) {
                     StringBuffer buf = new StringBuffer();
                     buf.append('{');
                     boolean hasValue = false;
 
                     // ArrayList Begin
                     Enumeration enm = .elements();
                     while (enm.hasMoreElements()) {
                         ArraySize arraySize = (ArraySizeenm.nextElement();
                         int size = arraySize.getArraySize(declarationsresult);
                         if (size == .) {
                             try {
                                 for (int i = 0;; i++) {
                                     if (i > 0) {
                                         buf.append(", ");
                                     }
                                     Object value = readValue(inparentIdentifier + "[" + i + "]"declarationsresult);
                                     if (value != null) {
                                         hasValue = true;
                                         buf.append(value.toString());
                                     }
                                 }
                             } catch (EOFException e) {
                             }
                         } else {
                             for (int i = 0; i < sizei++) {
                                 if (i > 0) {
                                     buf.append(", ");
                                 }
                                 Object value;
                                 if (arraySize.type == . || arraySize.type == .) {
                                     value = readValue(inparentIdentifierdeclarationsresult);
                                 } else {
                                     value = readValue(inparentIdentifier + "[" + i + "]"declarationsresult);
                                 }
                                 if (value != null) {
                                     hasValue = true;
                                     buf.append(value.toString());
                                 }
                             }
                         }
                     }
                     // ArrayList End
                     if (hasValue) {
                         buf.append('}');
                         return buf.toString();
                     } else {
                         return null;
                     }
                 } else {
                     return readValue(inparentIdentifierdeclarationsresult);
                 }
             }
         }
 
         private Object readValue(ImageInputStream inString parentIdentifierDeclarations declarationsVector result)
                 throws IOException {
             Object value = .read(inparentIdentifierdeclarationsresult);
             if (value != null) {
                 if (value instanceof Number) {
                     int intValue = ((Numbervalue).intValue();
                     if ( != null) {
                         value = .toEnumString(intValuedeclarations);
                     } else if ( != null) {
                         value = .toSetString(intValuedeclarations);
                     }
                 } else if (value instanceof String) {
                     if ( != null) {
                         value = .toEnumString((Stringvaluedeclarations);
                     }
                 }
             }
             return value;
         }
 
         @Override
         public String toString() {
             StringBuffer buf = new StringBuffer();
             buf.append("TypeSpecifier ");
             buf.append("" + );
             buf.append("" + );
            buf.append("" + );
            buf.append("" + );
            buf.append("" + );
            return buf.toString();
        }
    }

    
StructSpecifier expression.

 StructSpecifier ::= "struct (identifier | "{" MemberDeclaration { MemberDeclaration } "}" )
 
    protected static class StructSpecifier {
        public String identifier;
        public Vector members;
        public StructSpecifier(StreamPosTokenizer scanner)
                throws IOExceptionParseException {
            if (scanner.nextToken() != . || !scanner.sval.equals("struct")) {
                throw new ParseException(errorMsg("StructSpecifier: 'struct' expected"scanner));
            }
            scanner.nextToken();
            if (scanner.ttype == .) {
                 = scanner.sval;
            } else if (scanner.ttype == '{') {
                 = new Vector();
                while (scanner.nextToken() != '}') {
                    scanner.pushBack();
                    .addElement(new MemberDeclaration(scanner));
                }
            } else {
                throw new ParseException(errorMsg("StructSpecifier: identifier or '{' expected"scanner));
            }
        }
        private void read(ImageInputStream inString parentIdentifierDeclarations declarationsVector result)
                throws IOException {
            //try {
            Enumeration enm = .elements();
            while (enm.hasMoreElements()) {
                MemberDeclaration aMember = (MemberDeclarationenm.nextElement();
                aMember.read(inparentIdentifierdeclarationsresult);
            }
            /*
            } catch (IOException e) {
            System.out.println("StructParser.StructSpecifier.read(...) IOException @ "+identifier);
            e.printStackTrace();
            throw e;
            }*/
        }
    }

    
MemberDeclaration expression.

 MemberDeclaration ::= TypeSpecifier identifier [ArrayList] ";"
 ArrayList ::= "[" [ArraySize] "]" {"," identifier "[" [ArraySize] "]" }
 
    protected static class MemberDeclaration {