diff --git a/compiler/2014/Java_CodeGen.jrag b/compiler/2014/Java_CodeGen.jrag index 478a0ac4222f5cebdff8af2168197784e79543d8..c17cdb2a75c236c1fc2532611ac3003fce5e531c 100644 --- a/compiler/2014/Java_CodeGen.jrag +++ b/compiler/2014/Java_CodeGen.jrag @@ -454,10 +454,10 @@ aspect Java_Class { env.println(); } - //public void TypeDecl.Java_emitSignature(Java_env env) { - // Signature signature = getSignature(); - // signature.Java_emitSignature(env, true); - //} + public void TypeDecl.Java_emitSignature(Java_env env) { + Signature signature = getSignature(); + signature.Java_emitSignature(env, true); + } public void Decl.Java_emitSignature(Java_env env) { //always emit the flat signature, as it is needed @@ -465,10 +465,10 @@ aspect Java_Class { //the type_ids of dependent types. Therefore, flat sigs //are used for matching Java_emitFlatSignature(env); - //if(isReferenced() || isSampleDecl()){ - // Signature signature = getSignature(); - // signature.Java_emitSignature(env, !isSampleDecl()); - //} + if(isReferenced() || isSampleDecl()){ + Signature signature = getSignature(); + signature.Java_emitSignature(env, !isSampleDecl()); + } } public void Decl.Java_emitFlatSignature(Java_env env){ @@ -497,7 +497,8 @@ aspect Java_Class { //XXX TODO: refactor: split into a static class ("TypeDefSingleton"?)and a (smaller) dispatcher public void Decl.Java_emitDispatcher(Java_env env, boolean isSample) { - String genericStr = ""; //env.versionHasMetaData()?"<"+getName()+">":""; + // String genericStr = ""; //env.versionHasMetaData()?"<"+getName()+">":""; + String genericStr = "<"+getName()+">"; env.println("private static Dispatcher dispatcher = new Dispatcher();"); env.println(); env.println("public SampleDispatcher getDispatcher() {"); @@ -553,7 +554,11 @@ aspect Java_Class { env.println("/** return the flat signature. */"); env.println("public byte[] getSignature() {"); env.indent(); - env.println("return signature;"); + if(isSample) { + env.println("return signature;"); + } else { + env.println("throw new Error(\"a TYPE_DEF has no flat signature\");"); + } env.unindent(); env.println("}"); env.println(); @@ -563,15 +568,16 @@ aspect Java_Class { // env.unindent(); // env.println("}"); // env.println(); -// env.println("public void encodeSignatureMetadata(Encoder e, int index) throws IOException{"); -// env.indent(); -// env.println("e.encodePacked32(Constant.TYPE_DEF);"); -// env.println("e.encodePacked32(index);"); -// env.println("e.encodeString(getName());"); -// env.println("emitSignature(e);"); -// env.unindent(); -// env.println("}"); -// env.println(); + env.println("public void encodeTypeDef(Encoder e, int index) throws IOException{"); + env.indent(); + env.println("e.begin(Constant.TYPE_DEF);"); + env.println("e.encodePacked32(index);"); + env.println("e.encodeString(getName());"); + env.println("emitSignature(e);"); + env.println("e.end(null);"); + env.unindent(); + env.println("}"); + env.println(); env.println("public boolean canDecodeAndHandle() {"); env.indent(); env.println("return "+isSample+";"); diff --git a/lib/java/se/lth/control/labcomm/Encoder.java b/lib/java/se/lth/control/labcomm/Encoder.java index 203366e850ec1bcaae73c09c15b1cd1e3b842a12..41901151c2efeab95c24d66ab85caa3e088dfc4f 100644 --- a/lib/java/se/lth/control/labcomm/Encoder.java +++ b/lib/java/se/lth/control/labcomm/Encoder.java @@ -6,8 +6,11 @@ public interface Encoder { public void register(SampleDispatcher dispatcher) throws IOException; public void registerSampleRef(SampleDispatcher dispatcher) throws IOException; - public void begin(Class<? extends Sample> c) throws IOException; - public void end(Class<? extends Sample> c) throws IOException; + public void begin(Class<? extends SampleType> c) throws IOException; + public void end(Class<? extends SampleType> c) throws IOException; + + public void begin(int t) throws IOException; + public int getTypeId(Class<? extends SampleType> c) throws IOException; public void encodeBoolean(boolean value) throws IOException; public void encodeByte(byte value) throws IOException; diff --git a/lib/java/se/lth/control/labcomm/EncoderChannel.java b/lib/java/se/lth/control/labcomm/EncoderChannel.java index 01330fe22216b0a32941d981c9ad67602765e251..0872414cad14518ebb330ec0914830ea47798d5d 100644 --- a/lib/java/se/lth/control/labcomm/EncoderChannel.java +++ b/lib/java/se/lth/control/labcomm/EncoderChannel.java @@ -10,9 +10,10 @@ public class EncoderChannel implements Encoder { private Writer writer; private ByteArrayOutputStream bytes = new ByteArrayOutputStream(); private DataOutputStream data = new DataOutputStream(bytes); - private EncoderRegistry def_registry = new EncoderRegistry(); - private EncoderRegistry ref_registry = new EncoderRegistry(); - private int current_tag; + private EncoderRegistry sample_def_registry = new EncoderRegistry(); + private EncoderRegistry sample_ref_registry = new EncoderRegistry(); + private EncoderRegistry type_def_registry = new EncoderRegistry(); + private int current_tag; public EncoderChannel(Writer writer) throws IOException { this.writer = writer; @@ -26,42 +27,63 @@ public class EncoderChannel implements Encoder { this(new WriterWrapper(writer)); } - public void register(SampleDispatcher dispatcher) throws IOException { - switch (dispatcher.getTypeDeclTag()) { - case Constant.SAMPLE_DEF: { - int index = def_registry.add(dispatcher); + private void bindType(int sampleId, int typeId) throws IOException { + begin(Constant.TYPE_BINDING); + encodePacked32(sampleId); + encodePacked32(typeId); + end(null); + } + + private void registerSample(SampleDispatcher dispatcher) throws IOException { + int index = sample_def_registry.add(dispatcher); + begin(dispatcher.getTypeDeclTag()); + encodePacked32(index); + encodeString(dispatcher.getName()); + byte[] signature = dispatcher.getSignature(); + encodePacked32(signature.length); + for (int i = 0 ; i < signature.length ; i++) { + encodeByte(signature[i]); + } + end(null); + int tindex = registerTypeDef(dispatcher); + bindType(index, tindex); + + } + + private int registerTypeDef(SampleDispatcher dispatcher) throws IOException { + //XXX A bit crude; maybe add boolean registry.contains(...) and check + // if already registered + try { + return type_def_registry.getTag(dispatcher); + } catch (IOException e) { + int index = type_def_registry.add(dispatcher); begin(dispatcher.getTypeDeclTag()); encodePacked32(index); encodeString(dispatcher.getName()); - byte[] signature = dispatcher.getSignature(); - encodePacked32(signature.length); - for (int i = 0 ; i < signature.length ; i++) { - encodeByte(signature[i]); - } + dispatcher.encodeTypeDef(this, index); end(null); + return index; + } + } + + public void register(SampleDispatcher dispatcher) throws IOException { + switch (dispatcher.getTypeDeclTag()) { + case Constant.SAMPLE_DEF: { + registerSample(dispatcher); break; } case Constant.TYPE_DEF: { - int index = def_registry.add(dispatcher); - begin(dispatcher.getTypeDeclTag()); - encodePacked32(index); - encodeString(dispatcher.getName()); - byte[] signature = dispatcher.getSignature(); - encodePacked32(8); - for (int i = 0 ; i < 8; i++) { - encodeByte((byte) 0xff); - } - end(null); + registerTypeDef(dispatcher); break; } default: - throw new Error("Unknown typeDeclTag: "+dispatcher.getTypeDeclTag()); - } + throw new Error("Unknown typeDeclTag: "+dispatcher.getTypeDeclTag()); + } } public void registerSampleRef(SampleDispatcher dispatcher) throws IOException { System.err.println(dispatcher); - int index = ref_registry.add(dispatcher); + int index = sample_ref_registry.add(dispatcher); begin(Constant.SAMPLE_REF); encodePacked32(index); encodeString(dispatcher.getName()); @@ -73,16 +95,16 @@ public class EncoderChannel implements Encoder { end(null); } - private void begin(int tag) { + public void begin(int tag) { current_tag = tag; bytes.reset(); } - public void begin(Class<? extends Sample> c) throws IOException { - begin(def_registry.getTag(c)); + public void begin(Class<? extends SampleType> c) throws IOException { + begin(sample_def_registry.getTag(c)); } - public void end(Class<? extends Sample> c) throws IOException { + public void end(Class<? extends SampleType> c) throws IOException { data.flush(); WritePacked32(writer, current_tag); WritePacked32(writer, bytes.size()); @@ -90,19 +112,26 @@ public class EncoderChannel implements Encoder { bytes.reset(); } + /** + * @return the id of a TYPE_DEF + */ + public int getTypeId(Class<? extends SampleType> c) throws IOException { + return type_def_registry.getTag(c); + } + private void WritePacked32(Writer s, long value) throws IOException { byte[] tmp1 = new byte[5]; byte[] tmp2 = new byte[1]; long v = value & 0xffffffff; int i; - + for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) { tmp1[i] = (byte)(v & 0x7f | (i!=0?0x80:0x00)); } for (i = i - 1 ; i >= 0 ; i--) { tmp2[0] = tmp1[i]; writer.write(tmp2); - } + } } public void encodeBoolean(boolean value) throws IOException{ @@ -144,7 +173,7 @@ public class EncoderChannel implements Encoder { tmps.writeUTF(value); tmps.flush(); byte[] tmp = tmpb.toByteArray(); - + encodePacked32(tmp.length-2); for (int i = 2 ; i < tmp.length ; i++) { encodeByte(tmp[i]); @@ -167,7 +196,7 @@ public class EncoderChannel implements Encoder { public void encodeSampleRef(Class value) throws IOException { int index = 0; try { - index = ref_registry.getTag(value); + index = sample_ref_registry.getTag(value); } catch (NullPointerException e) { } data.writeInt(index); diff --git a/lib/java/se/lth/control/labcomm/EncoderRegistry.java b/lib/java/se/lth/control/labcomm/EncoderRegistry.java index cd0cf72f5f45ed9ccc3cb6ce1902c9c2e37333bf..f990d1813920a0624c557b4a895cae1f64331a69 100644 --- a/lib/java/se/lth/control/labcomm/EncoderRegistry.java +++ b/lib/java/se/lth/control/labcomm/EncoderRegistry.java @@ -42,7 +42,11 @@ public class EncoderRegistry { return e.getIndex(); } - public int getTag(Class<? extends Sample> sample) throws IOException { + public int getTag(SampleDispatcher d) throws IOException { + return getTag(d.getSampleClass()); + } + + public int getTag(Class<? extends SampleType> sample) throws IOException { Entry e = byClass.get(sample); if (e == null) { throw new IOException("'" + @@ -52,4 +56,8 @@ public class EncoderRegistry { return e.index; } + public boolean contains(Class<? extends SampleType> sample) { + return byClass.containsKey(sample); + } + } diff --git a/lib/java/se/lth/control/labcomm/Sample.java b/lib/java/se/lth/control/labcomm/Sample.java index f86f486b4bae2276780f73e24b33d03717c95840..2dd432b878f509538aca71f0b7840ff8fe2513b2 100644 --- a/lib/java/se/lth/control/labcomm/Sample.java +++ b/lib/java/se/lth/control/labcomm/Sample.java @@ -1,6 +1,6 @@ package se.lth.control.labcomm; -public interface Sample { +public interface Sample extends SampleType { public SampleDispatcher getDispatcher(); diff --git a/lib/java/se/lth/control/labcomm/SampleDispatcher.java b/lib/java/se/lth/control/labcomm/SampleDispatcher.java index 58e3d1debdb47e31125088cf9bb6502d0ebc74b5..aeef84e1a3ac9f739dbe54fb4056a535ad6a68de 100644 --- a/lib/java/se/lth/control/labcomm/SampleDispatcher.java +++ b/lib/java/se/lth/control/labcomm/SampleDispatcher.java @@ -1,8 +1,10 @@ package se.lth.control.labcomm; -public interface SampleDispatcher { +import java.io.IOException; + +public interface SampleDispatcher <T extends SampleType>{ - public Class getSampleClass(); + public Class<T> getSampleClass(); public String getName(); @@ -11,6 +13,8 @@ public interface SampleDispatcher { public void decodeAndHandle(Decoder decoder, SampleHandler handler) throws Exception; + public void encodeTypeDef(Encoder e, int index) throws IOException; + /** return the tag SAMPLE_DEF or TYPE_DEF, for use * by encoder.register. * TODO: refactor types, moving this to a super-interface