diff --git a/examples/user_types/Decoder.java b/examples/user_types/Decoder.java index cbfcb24a41425e42125d82949467ca645516077e..929e92e3a155617312db09d3e414cf67f2cf8ec4 100644 --- a/examples/user_types/Decoder.java +++ b/examples/user_types/Decoder.java @@ -4,19 +4,21 @@ import java.io.InputStream; import se.lth.control.labcomm.DecoderChannel; import se.lth.control.labcomm.TypeDef; -import se.lth.control.labcomm.TypeBinding; +import se.lth.control.labcomm.TypeDefParser; +//import se.lth.control.labcomm.TypeBinding; public class Decoder implements twoLines.Handler, +// TypeDef.Handler, +// TypeBinding.Handler, + TypeDefParser.TypeDefListener, twoInts.Handler, theFirstInt.Handler, - theSecondInt.Handler, - TypeDef.Handler, - TypeBinding.Handler - + theSecondInt.Handler { - DecoderChannel decoder; + private DecoderChannel decoder; + private TypeDefParser tdp; public Decoder(InputStream in) throws Exception @@ -26,9 +28,13 @@ public class Decoder twoLines.register(decoder, this); theFirstInt.register(decoder, this); theSecondInt.register(decoder, this); - TypeDef.register(decoder, this); - TypeBinding.register(decoder, this); + this.tdp = TypeDefParser.registerTypeDefParser(decoder); + // TypeDef.register(decoder, this); + // TypeBinding.register(decoder, this); + + tdp.addListener(this); + try { System.out.println("Running decoder."); decoder.run(); @@ -45,12 +51,16 @@ public class Decoder return "Line from "+genPoint(l.start)+" to "+genPoint(l.end); } - public void handle_TypeDef(TypeDef d) throws java.io.IOException { - System.out.println("Got TypeDef: "+d.getName()+"("+d.getIndex()+")"); - } +// public void handle_TypeDef(TypeDef d) throws java.io.IOException { +// System.out.println("Got TypeDef: "+d.getName()+"("+d.getIndex()+")"); +// } +// +// public void handle_TypeBinding(TypeBinding d) throws java.io.IOException { +// System.out.println("Got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+""); +// } - public void handle_TypeBinding(TypeBinding d) throws java.io.IOException { - System.out.println("Got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+""); + public void onTypeDef(TypeDef d) { + System.out.println("onTypeDef: "+d.getName()+"("+d.getIndex()+")"); } public void handle_twoInts(twoInts d) throws java.io.IOException { diff --git a/lib/java/Makefile b/lib/java/Makefile index bd3055c0a6ffe61f955e96fbfb2a67d79e730b54..697fd803d86bac15614e285084eab70703e8dca3 100644 --- a/lib/java/Makefile +++ b/lib/java/Makefile @@ -12,6 +12,7 @@ MODULES=Constant \ SampleType \ TypeDef \ TypeBinding \ + TypeDefParser \ Writer \ WriterWrapper diff --git a/lib/java/se/lth/control/labcomm/TypeBinding.java b/lib/java/se/lth/control/labcomm/TypeBinding.java index 36b84fb02ccf321290e567cea7c6a7b49df75340..0ea2782e154481457418a07840e51b4adad08bee 100644 --- a/lib/java/se/lth/control/labcomm/TypeBinding.java +++ b/lib/java/se/lth/control/labcomm/TypeBinding.java @@ -28,74 +28,92 @@ public class TypeBinding implements SampleType { public interface Handler extends SampleHandler { public void handle_TypeBinding(TypeBinding value) throws Exception; } - + public static void register(Decoder d, Handler h) throws IOException { d.register(Dispatcher.singleton(), h); } - + public static void register(Encoder e) throws IOException { register(e,false); } - + public static void register(Encoder e, boolean sendMetaData) throws IOException { throw new IOException("cannot send TypeDefs"); } - + static class Dispatcher implements SampleDispatcher<TypeBinding> { - + private static Dispatcher singleton; - + public synchronized static Dispatcher singleton() { if(singleton==null) singleton=new Dispatcher(); return singleton; } - + public Class<TypeBinding> getSampleClass() { return TypeBinding.class; } - + public String getName() { return "TypeBinding"; } - + public byte getTypeDeclTag() { throw new Error("Should not be called"); } - + public boolean isSample() { throw new Error("Should not be called"); } public boolean hasStaticSignature() { throw new Error("Should not be called"); } - + /** return the flat signature. Intended use is on decoder side */ public byte[] getSignature() { return null; // not used for matching } - + public void encodeTypeDef(Encoder e, int index) throws IOException{ throw new Error("Should not be called"); } - + // public boolean canDecodeAndHandle() { // return true; // } - + public void decodeAndHandle(Decoder d, SampleHandler h) throws Exception { ((Handler)h).handle_TypeBinding(TypeBinding.decode(d)); } - + public boolean hasDependencies() { return false; } } - + public static void encode(Encoder e, TypeBinding value) throws IOException { throw new Error("Should not be called"); } - + + /* HERE BE DRAGONS! + * This exposes (and relies on the stability of) indices that are + * internal to a decoder. + * + * The SAMPLE_DEF and TYPE_DEF must already have been received for the + * indices to be known, so this can be changed to instead return + * references to the SampleDispactcher corresponding to the sample type + * and the matching TypeDef. + * + * Sketch: + * + * SampleDispatcher sd = d.getDispatcherForId(sampleIndex); + * TypeDef td = d.getTypeDefForId(typeIndex); + * + * return new TypeBinding(sd, td); + * + * assuming that the Decoder keeps a registry for TypeDefs + */ public static TypeBinding decode(Decoder d) throws IOException { TypeBinding result; int sampleIndex = d.decodePacked32(); diff --git a/lib/java/se/lth/control/labcomm/TypeDef.java b/lib/java/se/lth/control/labcomm/TypeDef.java index 8c9cc7063d4b0614d229dc023a9fc3064128ab98..c7a78be4710cd17c021324e5593ec0de56dc32c4 100644 --- a/lib/java/se/lth/control/labcomm/TypeDef.java +++ b/lib/java/se/lth/control/labcomm/TypeDef.java @@ -21,6 +21,10 @@ public class TypeDef implements SampleType { return name; } + public byte[] getSignature() { + return signature; + } + public void dump() { System.out.print("=== TypeDef "+getName()+"( "+Integer.toHexString(getIndex())+") : "); for (byte b : signature) { @@ -99,6 +103,9 @@ public class TypeDef implements SampleType { throw new Error("Should not be called"); } + protected TypeDef() { + } + public TypeDef(int index, String name, byte sig[]) { this.index = index; this.name = name; diff --git a/lib/java/se/lth/control/labcomm/TypeDefParser.java b/lib/java/se/lth/control/labcomm/TypeDefParser.java new file mode 100644 index 0000000000000000000000000000000000000000..5a7f7aa7410fa9ba36a4de5318305b79d8ea20f8 --- /dev/null +++ b/lib/java/se/lth/control/labcomm/TypeDefParser.java @@ -0,0 +1,77 @@ +package se.lth.control.labcomm; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +import se.lth.control.labcomm.Decoder; +import se.lth.control.labcomm.TypeDef; +import se.lth.control.labcomm.TypeBinding; + +public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler { + + static class SelfBinding extends TypeDef { + + private byte[] dummy = new byte[0]; + public String getName() {return "self";} + public int getIndex() {return 0;} + public byte[] getSignature() {return dummy;} + } + + public interface TypeDefListener { + void onTypeDef(TypeDef d); + } + + private HashMap<Integer,TypeDef> typeDefs; + private HashMap<Integer,Integer> typeBindings; + private HashSet<TypeDefListener> listeners; + + protected TypeDefParser() { + typeDefs = new HashMap<Integer,TypeDef>(); + typeBindings = new HashMap<Integer,Integer>(); + listeners = new HashSet<TypeDefListener>(); + + typeDefs.put(0, new SelfBinding()); + } + + public void addListener(TypeDefListener l) { + listeners.add(l); + } + + public void handle_TypeDef(TypeDef d) throws java.io.IOException { + //System.out.println("Got TypeDef: "+d.getName()+"("+d.getIndex()+")"); + typeDefs.put(d.getIndex(), d); + } + + 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()); + + Iterator<TypeDefListener> it = listeners.iterator(); + while(it.hasNext()){ + //it.next().onTypeDef(getTypeDefForIndex(d.getSampleIndex())); + it.next().onTypeDef(typeDefs.get(d.getTypeIndex())); + } + } + + //* temporary testing method */ + public TypeDef getTypeDefForIndex(int sampleIndex) { + return typeDefs.get(typeBindings.get(sampleIndex)); + } + + + /** Factory method + * @return a new TypeDefParser registered on d + */ + public static TypeDefParser registerTypeDefParser(Decoder d) throws java.io.IOException { + + TypeDefParser res = new TypeDefParser(); + + TypeDef.register(d,res); + TypeBinding.register(d,res); + + return res; + } +} + +