From 3ca451b198e9651ec00dc12fad8435fa127dfd72 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Tue, 18 Nov 2014 18:13:53 +0100
Subject: [PATCH] References working for Java.

---
 compiler/Java_CodeGen.jrag                    | 16 +++++--
 .../se/lth/control/labcomm/DecoderChannel.cs  |  8 ++--
 lib/java/se/lth/control/labcomm/Constant.java |  5 +-
 lib/java/se/lth/control/labcomm/Decoder.java  |  4 +-
 .../lth/control/labcomm/DecoderChannel.java   | 47 +++++++++++++------
 lib/java/se/lth/control/labcomm/Encoder.java  |  5 +-
 .../lth/control/labcomm/EncoderChannel.java   | 38 ++++++++++-----
 test/relay_gen_java.py                        | 21 +++++++--
 8 files changed, 99 insertions(+), 45 deletions(-)

diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag
index 7c00bc3..478a0ac 100644
--- a/compiler/Java_CodeGen.jrag
+++ b/compiler/Java_CodeGen.jrag
@@ -332,15 +332,18 @@ aspect Java_Class {
     env.println("register(e, true);");
     env.unindent();
     env.println("}");
-
     env.println();
     env.println("public static void register(Encoder e, boolean sendMetaData) throws IOException {");
     env.indent();
-
     Java_emitUserTypeDeps(env, null, true);
     env.println("e.register(dispatcher);");
     env.unindent();
     env.println("}");
+    env.println("public static void registerSampleRef(Encoder e) throws IOException{");
+    env.indent();
+    env.println("e.registerSampleRef(dispatcher);");
+    env.unindent();
+    env.println("}");
     env.println();
   }
 
@@ -432,6 +435,11 @@ aspect Java_Class {
     env.println("d.register(dispatcher, h);");
     env.unindent();
     env.println("}");
+    env.println("public static void registerSampleRef(Decoder d) throws IOException {");
+    env.indent();
+    env.println("d.registerSampleRef(dispatcher);");
+    env.unindent();
+    env.println("}");
     env.println();
 
 
@@ -820,7 +828,7 @@ aspect Java_Class {
   public void PrimType.Java_emitTypePrefix(Java_env env) {
     switch (getToken()) {
       case LABCOMM_STRING: { env.print("String"); } break;
-      case LABCOMM_SAMPLE: { env.print("Sample"); } break;
+      case LABCOMM_SAMPLE: { env.print("Class"); } break;
       default: { env.print(getName()); } break;
     }
   }
@@ -947,7 +955,7 @@ aspect Java_Class {
   public void PrimType.Java_emitType(Java_env env) {
     switch (getToken()) {
       case LABCOMM_STRING: { env.print("String"); } break;
-      case LABCOMM_SAMPLE: { env.print("Sample"); } break;
+      case LABCOMM_SAMPLE: { env.print("Class"); } break;
       default: { env.print(getName()); } break;
     }
   }
diff --git a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs b/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs
index 1185e28..aa86621 100644
--- a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs
@@ -162,12 +162,14 @@ namespace se.lth.control.labcomm {
 
     public Type decodeSampleRef() {
       int index = (int)ReadInt(4);
-      DecoderRegistry.Entry e = ref_registry.get(index);
-      if (e != null) {
+      try {
+        DecoderRegistry.Entry e = ref_registry.get(index);
         return e.getSampleDispatcher().getSampleClass();
-      } else {
+      } catch (NullReferenceException) {
         return null;
       }
     }
+
   }
+
 } 
diff --git a/lib/java/se/lth/control/labcomm/Constant.java b/lib/java/se/lth/control/labcomm/Constant.java
index c5a580a..fc52a28 100644
--- a/lib/java/se/lth/control/labcomm/Constant.java
+++ b/lib/java/se/lth/control/labcomm/Constant.java
@@ -12,8 +12,9 @@ public class Constant {
    */
   public static final int VERSION          = 0x01;
   public static final int SAMPLE_DEF       = 0x02;
-  public static final int TYPE_DEF         = 0x03;
-  public static final int TYPE_BINDING     = 0x04;
+  public static final int SAMPLE_REF       = 0x03;
+  public static final int TYPE_DEF         = 0x04;
+  public static final int TYPE_BINDING     = 0x05;
   public static final int PRAGMA           = 0x3f;
   public static final int FIRST_USER_INDEX = 0x40; /* ..0xffffffff */
 
diff --git a/lib/java/se/lth/control/labcomm/Decoder.java b/lib/java/se/lth/control/labcomm/Decoder.java
index 317133d..ae68446 100644
--- a/lib/java/se/lth/control/labcomm/Decoder.java
+++ b/lib/java/se/lth/control/labcomm/Decoder.java
@@ -6,6 +6,8 @@ public interface Decoder {
   
   public void register(SampleDispatcher dispatcher, 
 		       SampleHandler handler) throws IOException;
+  public void registerSampleRef(SampleDispatcher dispatcher) throws IOException;
+
   public boolean decodeBoolean() throws IOException;
   public byte decodeByte() throws IOException;
   public short decodeShort() throws IOException;
@@ -15,6 +17,6 @@ public interface Decoder {
   public double decodeDouble() throws IOException;
   public String decodeString() throws IOException;
   public int decodePacked32() throws IOException;
-  public Sample decodeSampleRef() throws IOException;
+  public Class decodeSampleRef() throws IOException;
 
 }
diff --git a/lib/java/se/lth/control/labcomm/DecoderChannel.java b/lib/java/se/lth/control/labcomm/DecoderChannel.java
index 276716d..dc25d23 100644
--- a/lib/java/se/lth/control/labcomm/DecoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/DecoderChannel.java
@@ -9,14 +9,11 @@ import java.io.EOFException;
 public class DecoderChannel implements Decoder {
 
   private DataInputStream in;
-  private DecoderRegistry registry;
+  private DecoderRegistry def_registry = new DecoderRegistry();
+  private DecoderRegistry ref_registry = new DecoderRegistry();
 
-  private DecoderChannel(InputStream in, DecoderRegistry reg) throws IOException {
-    this.in = new DataInputStream(in);
-    registry = reg;
-  }
   public DecoderChannel(InputStream in) throws IOException {
-    this(in, new DecoderRegistry());
+    this.in = new DataInputStream(in);
   }
 
   private void processSampleDef() throws IOException {
@@ -25,26 +22,34 @@ public class DecoderChannel implements Decoder {
     int signature_length = decodePacked32();
     byte[] signature = new byte[signature_length];
     ReadBytes(signature, signature_length);
-    registry.add(index, name, signature);
+    def_registry.add(index, name, signature);
   }	   
 
+  private void processSampleRef() throws IOException {
+    int index = decodePacked32();
+    String name = decodeString();
+    int signature_length = decodePacked32();
+    byte[] signature = new byte[signature_length];
+    ReadBytes(signature, signature_length);
+    ref_registry.add(index, name, signature);
+  }	   
 
   private void processTypeDef(int len) throws IOException {
-       System.out.println("Got TypeDef: skipping "+len+" bytes"); 
+       System.err.println("Got TypeDef: skipping "+len+" bytes"); 
        for(int i=0; i<len; i++) {
            decodeByte();		  
        }
   }
 
   private void processTypeBinding(int len) throws IOException {
-       System.out.println("Got TypeBinding: skipping "+len+" bytes"); 
+       System.err.println("Got TypeBinding: skipping "+len+" bytes"); 
        for(int i=0; i<len; i++) {
            decodeByte();		  
        }
   }
 
   private void processPragma(int len) throws IOException {
-       System.out.println("Got Pragma: skipping "+len+" bytes"); 
+       System.err.println("Got Pragma: skipping "+len+" bytes"); 
        for(int i=0; i<len; i++) {
            decodeByte();		  
        }
@@ -66,6 +71,9 @@ public class DecoderChannel implements Decoder {
 	case Constant.SAMPLE_DEF: {
           processSampleDef();
 	} break;
+	case Constant.SAMPLE_REF: {
+          processSampleRef();
+	} break;
 	case Constant.TYPE_DEF: {
           processTypeDef(length);
 	} break;
@@ -76,7 +84,7 @@ public class DecoderChannel implements Decoder {
           processPragma(length);
 	} break;
 	default: {
-	  DecoderRegistry.Entry e = registry.get(tag);
+	  DecoderRegistry.Entry e = def_registry.get(tag);
 	  if (e == null) {
 	    throw new IOException("Unhandled tag " + tag);
 	  }
@@ -103,7 +111,11 @@ public class DecoderChannel implements Decoder {
 
   public void register(SampleDispatcher dispatcher, 
                        SampleHandler handler) throws IOException {
-    registry.add(dispatcher, handler);
+    def_registry.add(dispatcher, handler);
+  }
+
+  public void registerSampleRef(SampleDispatcher dispatcher) throws IOException {
+    ref_registry.add(dispatcher, null);
   }
 
   private void ReadBytes(byte[] result, int length) throws IOException {
@@ -173,10 +185,15 @@ public class DecoderChannel implements Decoder {
     return (int) (res & 0xffffffff);
   }
 
-  public Sample decodeSampleRef() throws IOException {
+  public Class decodeSampleRef() throws IOException {
     int index = in.readInt();
-    throw new IOException("IMPLEMENT");
-//    return null;
+    try {
+      DecoderRegistry.Entry e = ref_registry.get(index);
+      return e.getDispatcher().getSampleClass();
+    } catch (NullPointerException e) {
+      return null;
+    }
+
   }
     
 }
diff --git a/lib/java/se/lth/control/labcomm/Encoder.java b/lib/java/se/lth/control/labcomm/Encoder.java
index 957447e..203366e 100644
--- a/lib/java/se/lth/control/labcomm/Encoder.java
+++ b/lib/java/se/lth/control/labcomm/Encoder.java
@@ -5,9 +5,10 @@ import java.io.IOException;
 public interface Encoder {
 
   public void register(SampleDispatcher dispatcher) throws IOException;
-  public void registerSampleRef(Sample sample) 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 encodeBoolean(boolean value) throws IOException;
   public void encodeByte(byte value) throws IOException;
   public void encodeShort(short value) throws IOException;
@@ -17,6 +18,6 @@ public interface Encoder {
   public void encodeDouble(double value) throws IOException;
   public void encodeString(String value) throws IOException;
   public void encodePacked32(long value) throws IOException;
-  public void encodeSampleRef(Sample value) throws IOException;
+  public void encodeSampleRef(Class value) throws IOException;
 
 }
diff --git a/lib/java/se/lth/control/labcomm/EncoderChannel.java b/lib/java/se/lth/control/labcomm/EncoderChannel.java
index aeeee47..5949b1a 100644
--- a/lib/java/se/lth/control/labcomm/EncoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/EncoderChannel.java
@@ -8,16 +8,14 @@ import java.io.OutputStream;
 public class EncoderChannel implements Encoder {
 
   private Writer writer;
-  private ByteArrayOutputStream bytes;
-  private DataOutputStream data;
-  private EncoderRegistry registry;
+  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; 
 
   public EncoderChannel(Writer writer) throws IOException {
     this.writer = writer;
-    bytes = new ByteArrayOutputStream();
-    data = new DataOutputStream(bytes);
-    registry = new EncoderRegistry();
 
     begin(Constant.VERSION);
     encodeString(Constant.CURRENT_VERSION);
@@ -29,7 +27,7 @@ public class EncoderChannel implements Encoder {
   }
 
   public void register(SampleDispatcher dispatcher) throws IOException {
-    int index = registry.add(dispatcher);
+    int index = def_registry.add(dispatcher);
     begin(Constant.SAMPLE_DEF);
     encodePacked32(index);
     encodeString(dispatcher.getName());
@@ -41,7 +39,18 @@ public class EncoderChannel implements Encoder {
     end(null);
   }
 
-  public void registerSampleRef(Sample sample) throws IOException {
+  public void registerSampleRef(SampleDispatcher dispatcher) throws IOException {
+    System.err.println(dispatcher);
+    int index = ref_registry.add(dispatcher);
+    begin(Constant.SAMPLE_REF);
+    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);
   }
 
   private void begin(int tag) {
@@ -50,7 +59,7 @@ public class EncoderChannel implements Encoder {
   }
 
   public void begin(Class<? extends Sample> c) throws IOException {
-    begin(registry.getTag(c));
+    begin(def_registry.getTag(c));
   }
 
   public void end(Class<? extends Sample> c) throws IOException {
@@ -135,11 +144,14 @@ public class EncoderChannel implements Encoder {
     }
   }
 
-  public void encodeSampleRef(Sample value) throws IOException {
-    data.writeInt(0);
-    throw new IOException("IMPLEMENT");
+  public void encodeSampleRef(Class value) throws IOException {
+    int index = 0;
+    try {
+      index = ref_registry.getTag(value);
+    } catch (NullPointerException e) {
+    }
+    data.writeInt(index);
   }
-    
 
 }
 
diff --git a/test/relay_gen_java.py b/test/relay_gen_java.py
index 757dc01..a4a3b88 100755
--- a/test/relay_gen_java.py
+++ b/test/relay_gen_java.py
@@ -2,6 +2,7 @@
 
 import re
 import sys
+import random
 
 def split_match(pattern, multiline):
     def match(s):
@@ -11,6 +12,10 @@ def split_match(pattern, multiline):
         pass
     return filter(lambda s: s != None, map(match, multiline.split('\n')))
    
+def shuffle(l):
+    result = list(l)
+    random.shuffle(result)
+    return result
 
 if __name__ == '__main__':
     f = open(sys.argv[1])
@@ -59,20 +64,26 @@ if __name__ == '__main__':
     result.extend(split_match('^[^|]*\|(.*)$', """
       |  public java_relay(String InName, String OutName) throws Exception {
       |    FileInputStream InFile = new FileInputStream(InName);
-      |    DecoderChannel d = new DecoderChannel(InFile);
+      |    DecoderChannel decoder = new DecoderChannel(InFile);
       |    FileOutputStream OutFile = new FileOutputStream(OutName);
       |    encoder = new EncoderChannel(OutFile);
       |
     """))
-    for func,arg in sample:
-        result.append('    %s.register(d, this);' % func)
+    for func,arg in shuffle(sample):
+        result.append('    %s.register(decoder, this);' % func)
         pass
-    for func,arg in sample:
+    for func,arg in shuffle(sample):
+        result.append('    %s.registerSampleRef(decoder);' % func)
+        pass
+    for func,arg in shuffle(sample):
         result.append('    %s.register(encoder);' % func)
         pass
+    for func,arg in shuffle(sample):
+        result.append('    %s.registerSampleRef(encoder);' % func)
+        pass
     result.extend(split_match('^[^|]*\|(.*)$', """
       |    try {
-      |      d.run();
+      |      decoder.run();
       |    } catch (java.io.EOFException e) {
       |    }
       |  }
-- 
GitLab