From c6e943c40e68df16c36cc62f54c28e77df41c9b0 Mon Sep 17 00:00:00 2001
From: Sven Gestegard Robertz <sven.robertz@cs.lth.se>
Date: Mon, 2 Feb 2015 00:50:48 +0100
Subject: [PATCH] sketched typedef parsing/pretty printing

---
 examples/user_types/Decoder.java              |   8 +
 .../se/lth/control/labcomm/TypeDefParser.java | 199 +++++++++++++++++-
 2 files changed, 204 insertions(+), 3 deletions(-)

diff --git a/examples/user_types/Decoder.java b/examples/user_types/Decoder.java
index 929e92e..22b9c2b 100644
--- a/examples/user_types/Decoder.java
+++ b/examples/user_types/Decoder.java
@@ -1,6 +1,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.io.IOException;
 
 import se.lth.control.labcomm.DecoderChannel;
 import se.lth.control.labcomm.TypeDef;
@@ -61,6 +62,13 @@ public class Decoder
 
   public void onTypeDef(TypeDef d) {
     System.out.println("onTypeDef: "+d.getName()+"("+d.getIndex()+")");
+    for(byte b: d.getSignature()) {
+       System.out.print(Integer.toHexString(b)+" ");
+    }
+    System.out.println(); 
+    try {
+       tdp.parseSignature(d.getIndex());
+    } catch(IOException ex) { ex.printStackTrace();}   
   }
 
   public void handle_twoInts(twoInts d) throws java.io.IOException {
diff --git a/lib/java/se/lth/control/labcomm/TypeDefParser.java b/lib/java/se/lth/control/labcomm/TypeDefParser.java
index 5a7f7aa..f6904bc 100644
--- a/lib/java/se/lth/control/labcomm/TypeDefParser.java
+++ b/lib/java/se/lth/control/labcomm/TypeDefParser.java
@@ -3,6 +3,12 @@ package se.lth.control.labcomm;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedList;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.EOFException;
 
 import se.lth.control.labcomm.Decoder;
 import se.lth.control.labcomm.TypeDef;
@@ -45,12 +51,24 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
 
     public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
         //System.out.println("TDP got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+"");
-        typeBindings.put(d.getSampleIndex(), d.getTypeIndex());
+        TypeDef td;
+        if(d.getTypeIndex() == Constant.TYPE_BIND_SELF){
+            //TODO: make the sample_def signature a TypeDef.
+            // e.g., by looking up the signature in the decoder
+            // (how to expose that?)
+            //td = typeDefs.get(d.getTypeIndex());
+           
+            //XXX this will return a SelfBinding (w/o a signature)
+            td = getTypeDefForIndex(d.getSampleIndex());
+        } else {
+            typeBindings.put(d.getSampleIndex(), d.getTypeIndex());
+            td = getTypeDefForIndex(d.getSampleIndex());
+        }
         
         Iterator<TypeDefListener> it = listeners.iterator();
         while(it.hasNext()){
-            //it.next().onTypeDef(getTypeDefForIndex(d.getSampleIndex()));
-            it.next().onTypeDef(typeDefs.get(d.getTypeIndex()));
+            it.next().onTypeDef(td);
+            //it.next().onTypeDef(typeDefs.get(d.getTypeIndex()));
         }
     }
 
@@ -72,6 +90,181 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
 
         return res;
     }
+
+
+///// parsing
+//
+//
+
+    private class ParserState {
+        private ByteArrayInputStream bis;
+        private DataInputStream in;
+
+        private LinkedList<Integer> typeStack;
+
+
+        private ParserState() {
+            typeStack = new LinkedList<Integer>();
+        }
+
+        public ParserState(int typeIdx) {
+            this();
+            pushType(typeIdx);
+        }
+         
+        public ParserState(byte sig[]) {
+            this();
+            bis= new ByteArrayInputStream(sig);
+            in = new DataInputStream(bis);
+        }
+
+        public void pushType(int typeIdx) {
+            if(typeIdx >= 0x40 && !typeStack.contains(typeIdx)) {
+                typeStack.push(typeIdx);
+            } else {
+                //throw new Error("typeIdx < 0x40");
+            }
+        }
+
+        public void popType() {
+            int tid = typeStack.pop();
+            TypeDef td2 = typeDefs.get(tid);
+            System.out.println(td2.getName());
+            bis =new ByteArrayInputStream(td2.getSignature());
+            in = new DataInputStream(bis);
+        }
+
+        public boolean moreTypes() {
+            return !typeStack.isEmpty();
+        }
+        public String decodeString() throws IOException {
+            int len = decodePacked32() & 0xffffffff;
+            byte[] chars = new byte[len];
+            for(int i=0; i<len; i++) {
+                chars[i] = in.readByte();
+            }
+            return new String(chars);
+        }
+
+        public int decodePacked32() throws IOException {
+            long res=0;
+            byte i=0;
+            boolean cont=true;
+
+            do {
+            byte c = in.readByte();
+            res = (res << 7) | (c & 0x7f);
+            cont = (c & 0x80) != 0;
+            i++;
+            } while(cont);
+
+            return (int) (res & 0xffffffff);
+        }
+    }
+
+//    public HierarchicalTypeDef parseSignature(int typeIndex) {
+    public void parseSignature(int typeIndex) throws IOException{
+//    public void parseSignature(TypeDef td) throws IOException{
+
+        //TypeDef td = getTypeDefForIndex(sampleIndex);
+
+//        byte sig[] = td.getSignature();
+
+//        ParserState s = new ParserState(sig);
+        ParserState s = new ParserState(typeIndex);
+
+        try {
+      //      parseType(s);
+
+            while(s.moreTypes()) {
+                s.popType();
+                parseType(s);
+            }
+
+        } catch(java.io.EOFException ex) {
+            System.out.println("EOF: self_binding");
+        }
+    }    
+
+    private void parseArray(ParserState in) throws IOException {
+        int numIdx = in.decodePacked32();
+        int idx[] = new int[numIdx];
+        for(int i=0; i<numIdx; i++){
+            idx[i] = in.decodePacked32(); 
+            System.out.println(idx[i]);
+        }
+        int type = in.decodePacked32();
+        lookupType(type, in); 
+    }
+
+    private void parseStruct(ParserState in) throws IOException {
+        System.out.println("struct");
+        int numFields = in.decodePacked32();
+        for(int i=0; i<numFields; i++) {
+            parseField(in);
+        }
+    }
+
+    private void parseField(ParserState in) throws IOException {
+        String name = in.decodeString();
+        System.out.print("    "+name+" : ");
+        parseType(in);
+    }
+
+    private void lookupType(int tag, ParserState in) {
+        switch(tag) {
+            case Constant.BOOLEAN:
+                System.out.println("boolean");
+                break;
+            case Constant.BYTE:
+                System.out.println("byte");
+                break;
+            case Constant.SHORT:
+                System.out.println("short");
+                break;
+            case Constant.INT:
+                System.out.println("int");
+                break;
+            case Constant.LONG:
+                System.out.println("long");
+                break;
+            case Constant.FLOAT:
+                System.out.println("float");
+                break;
+            case Constant.DOUBLE:
+                System.out.println("double");
+                break;
+            case Constant.STRING:
+                System.out.println("string");
+                break;
+            default:
+                {
+                    TypeDef td = typeDefs.get(tag);
+                    System.out.println(td.getName());
+                }
+                in.pushType(tag);
+                break;
+        }
+    }
+
+    private void parseType(ParserState in) throws IOException {
+        int tag = in.decodePacked32();
+        switch(tag) {
+            case 0:
+                System.out.println("SELF");
+                break;
+            case Constant.ARRAY:
+                parseArray(in);
+                break;
+            case Constant.STRUCT:
+                parseStruct(in);
+                break;
+            default:
+                lookupType(tag, in);
+                break;
+        }    
+    }
+
 }
 
 
-- 
GitLab