From e1d9b89b7d9ddc08140fb22e52ec627f2a77ff0e Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Fri, 29 May 2015 21:11:22 +0200
Subject: [PATCH] Renaming for C# implemented

---
 lib/csharp/Makefile                           | 10 ++-
 .../control/labcomm2014/AbstractDecoder.cs    | 18 -----
 .../se/lth/control/labcomm2014/Decoder.cs     |  8 +-
 .../control/labcomm2014/RenamingDecoder.cs    | 34 +++++++++
 .../control/labcomm2014/RenamingEncoder.cs    | 60 +++++++++++++++
 .../control/labcomm2014/RenamingRegistry.cs   | 75 +++++++++++++++++++
 .../control/labcomm2014/WrappingDecoder.cs    | 72 ++++++++++++++++++
 .../control/labcomm2014/WrappingEncoder.cs    | 71 ++++++++++++++++++
 test/Makefile                                 | 18 ++++-
 test/relay_gen_cs.py                          | 26 ++++++-
 10 files changed, 362 insertions(+), 30 deletions(-)
 delete mode 100644 lib/csharp/se/lth/control/labcomm2014/AbstractDecoder.cs
 create mode 100644 lib/csharp/se/lth/control/labcomm2014/RenamingDecoder.cs
 create mode 100644 lib/csharp/se/lth/control/labcomm2014/RenamingEncoder.cs
 create mode 100644 lib/csharp/se/lth/control/labcomm2014/RenamingRegistry.cs
 create mode 100644 lib/csharp/se/lth/control/labcomm2014/WrappingDecoder.cs
 create mode 100644 lib/csharp/se/lth/control/labcomm2014/WrappingEncoder.cs

diff --git a/lib/csharp/Makefile b/lib/csharp/Makefile
index 0c67e05..71a5c31 100644
--- a/lib/csharp/Makefile
+++ b/lib/csharp/Makefile
@@ -1,15 +1,19 @@
-MODULES=AbstractDecoder \
-        Constant\
+MODULES=Constant\
 	Decoder \
 	DecoderChannel \
 	DecoderRegistry \
 	Encoder \
 	EncoderChannel \
 	EncoderRegistry \
+	RenamingDecoder \
+	RenamingEncoder \
+	RenamingRegistry \
 	Sample \
 	SampleDispatcher \
 	SampleHandler \
-	SampleType
+	SampleType \
+	WrappingDecoder \
+	WrappingEncoder
 
 .PHONY: all
 all: labcomm2014.dll
diff --git a/lib/csharp/se/lth/control/labcomm2014/AbstractDecoder.cs b/lib/csharp/se/lth/control/labcomm2014/AbstractDecoder.cs
deleted file mode 100644
index 4ea8760..0000000
--- a/lib/csharp/se/lth/control/labcomm2014/AbstractDecoder.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-
-namespace se.lth.control.labcomm2014 {
-
-  public interface AbstractDecoder {
-
-    void runOne();
-
-    void run();
-
-    void register(SampleDispatcher dispatcher, 
-		  SampleHandler handler);
-
-    void registerSampleRef(SampleDispatcher dispatcher);
-
-  }
-
-} 
diff --git a/lib/csharp/se/lth/control/labcomm2014/Decoder.cs b/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
index 0d79bca..f295fb4 100644
--- a/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
@@ -2,7 +2,13 @@ using System;
 
 namespace se.lth.control.labcomm2014 {
 
-  public interface Decoder : AbstractDecoder {
+  public interface Decoder {
+
+    void runOne();
+    void run();
+    void register(SampleDispatcher dispatcher,
+		  SampleHandler handler);
+    void registerSampleRef(SampleDispatcher dispatcher);
 
     bool decodeBoolean();
     byte decodeByte();
diff --git a/lib/csharp/se/lth/control/labcomm2014/RenamingDecoder.cs b/lib/csharp/se/lth/control/labcomm2014/RenamingDecoder.cs
new file mode 100644
index 0000000..0ed4ac6
--- /dev/null
+++ b/lib/csharp/se/lth/control/labcomm2014/RenamingDecoder.cs
@@ -0,0 +1,34 @@
+namespace se.lth.control.labcomm2014 {
+
+  using System;
+
+  public class RenamingDecoder : WrappingDecoder {
+
+    private Decoder decoder;
+    private RenamingRegistry registry;
+    private Func<String,String> rename;
+    
+    public RenamingDecoder(Decoder decoder,
+                           RenamingRegistry registry,
+                           Func<String,String> rename)
+    : base(decoder) {
+      this.decoder = decoder;
+      this.registry = registry;
+      this.rename = rename;
+    }
+
+    public override void register(SampleDispatcher dispatcher, 
+			 SampleHandler handler) {
+      decoder.register(registry.add(
+        dispatcher, rename(dispatcher.getName())), handler);
+    }
+
+    public override void registerSampleRef(SampleDispatcher dispatcher) {
+      decoder.registerSampleRef(registry.add(
+        dispatcher, rename(dispatcher.getName())));
+    }
+
+
+  }
+
+} 
diff --git a/lib/csharp/se/lth/control/labcomm2014/RenamingEncoder.cs b/lib/csharp/se/lth/control/labcomm2014/RenamingEncoder.cs
new file mode 100644
index 0000000..cfafe48
--- /dev/null
+++ b/lib/csharp/se/lth/control/labcomm2014/RenamingEncoder.cs
@@ -0,0 +1,60 @@
+namespace se.lth.control.labcomm2014 {
+
+  using System;
+  using System.Collections.Generic;
+
+  public class RenamingEncoder : WrappingEncoder {
+
+    private Encoder encoder;
+    private RenamingRegistry registry;
+    private Func<String,String> rename;
+    private Dictionary<SampleDispatcher, SampleDispatcher> alias;
+
+    public RenamingEncoder(Encoder encoder,
+                           RenamingRegistry registry,
+                           Func<String,String> rename)
+    : base(encoder) {
+      this.encoder = encoder;
+      this.registry = registry;
+      this.rename = rename;
+      alias = new Dictionary<SampleDispatcher, SampleDispatcher>();
+    }
+
+    private SampleDispatcher add(SampleDispatcher identity) {
+      SampleDispatcher renamed;
+      lock(this) {
+        if (! alias.TryGetValue(identity, out renamed)) {
+          renamed = registry.add(identity, rename(identity.getName()));
+          alias.Add(identity, renamed);
+        }
+      }
+      get(identity);
+      return renamed;
+    }
+
+    private SampleDispatcher get(SampleDispatcher identity) {
+      SampleDispatcher renamed;
+      lock(this) {
+        alias.TryGetValue(identity, out renamed);
+      }
+      return renamed;
+    }
+    public override void register(SampleDispatcher identity) {
+      encoder.register(add(identity));
+    }
+
+    public override void registerSampleRef(SampleDispatcher identity) {
+      encoder.registerSampleRef(add(identity));
+    }
+
+    public override void begin(SampleDispatcher identity) {
+      base.begin(get(identity));
+    }
+
+    public override void end(SampleDispatcher identity) {
+      base.end(get(identity));
+    }
+
+  }
+
+} 
diff --git a/lib/csharp/se/lth/control/labcomm2014/RenamingRegistry.cs b/lib/csharp/se/lth/control/labcomm2014/RenamingRegistry.cs
new file mode 100644
index 0000000..654ef33
--- /dev/null
+++ b/lib/csharp/se/lth/control/labcomm2014/RenamingRegistry.cs
@@ -0,0 +1,75 @@
+namespace se.lth.control.labcomm2014 {
+
+  using System;
+  using System.Collections.Generic;
+
+  public class RenamingRegistry {
+
+    public class Dispatcher : SampleDispatcher, IEquatable<Dispatcher> {
+
+      private SampleDispatcher dispatcher;
+      private String name;
+      
+      public Dispatcher(SampleDispatcher dispatcher,
+                        String name) {
+        this.dispatcher = dispatcher;
+        this.name = name;
+      }
+
+      public SampleDispatcher getSampleIdentity() {
+        return this;
+      }
+    
+      public String getName() {
+        return name;
+      }
+    
+      public byte[] getSignature() {
+        return dispatcher.getSignature();
+      }
+
+      public void decodeAndHandle(Decoder decoder,
+  			   SampleHandler handler) {
+        dispatcher.decodeAndHandle(decoder, handler);
+      }
+
+      public bool Equals(Dispatcher obj) {
+        Dispatcher other = obj as Dispatcher;
+        return (other != null &&
+                dispatcher == other.dispatcher &&
+                name.Equals(other.name));
+      }
+
+      public override int GetHashCode() {
+        return dispatcher.GetHashCode() ^ name.GetHashCode();
+      }
+      
+      public override string ToString() {
+        return "RenamingRegistry.Dispatcher(" + name + ")";
+      }
+
+    }
+
+    private Dictionary<Dispatcher, Dispatcher> registry;
+
+    public RenamingRegistry() {
+      registry = new Dictionary<Dispatcher, Dispatcher>();
+    }
+    
+    public SampleDispatcher add(SampleDispatcher dispatcher,
+                                String newName) {
+      Dispatcher result;
+      Dispatcher tmp = new Dispatcher(dispatcher, newName);
+      lock(this) {
+        registry.TryGetValue(tmp, out result);
+	if (result == null) {
+          registry.Add(tmp, tmp);
+          result = tmp;
+        }
+      }
+      return result;
+    }
+
+  }
+
+}
diff --git a/lib/csharp/se/lth/control/labcomm2014/WrappingDecoder.cs b/lib/csharp/se/lth/control/labcomm2014/WrappingDecoder.cs
new file mode 100644
index 0000000..12d0b5a
--- /dev/null
+++ b/lib/csharp/se/lth/control/labcomm2014/WrappingDecoder.cs
@@ -0,0 +1,72 @@
+using System;
+
+namespace se.lth.control.labcomm2014 {
+
+  public class WrappingDecoder: Decoder {
+
+    private Decoder decoder;
+
+    public WrappingDecoder(Decoder decoder) {
+      this.decoder = decoder;
+    }
+
+    public virtual void runOne() {
+      decoder.runOne();
+    }
+
+    public virtual void run() {
+      decoder.run();
+    }    
+
+    public virtual void register(SampleDispatcher dispatcher, 
+		  SampleHandler handler) {
+      decoder.register(dispatcher, handler);
+    }
+                  
+    public virtual void registerSampleRef(SampleDispatcher dispatcher) {
+      decoder.registerSampleRef(dispatcher);
+    }
+
+    public virtual bool decodeBoolean() {
+      return decoder.decodeBoolean();
+    }
+    
+    public virtual byte decodeByte() {
+      return decoder.decodeByte();
+    }
+    
+    public virtual short decodeShort() {
+      return decoder.decodeShort();
+    }
+    
+    public virtual int decodeInt() {
+      return decoder.decodeInt();
+    }
+    
+    public virtual long decodeLong() {
+      return decoder.decodeLong();
+    }
+    
+    public virtual float decodeFloat() {
+      return decoder.decodeFloat();
+    }
+    
+    public virtual double decodeDouble() {
+      return decoder.decodeDouble();
+    }
+    
+    public virtual String decodeString() {
+      return decoder.decodeString();
+    }
+    
+    public virtual int decodePacked32() {
+      return decoder.decodePacked32();
+    }
+    
+    public virtual SampleDispatcher decodeSampleRef() {
+      return decoder.decodeSampleRef();
+    }
+    
+  }
+
+} 
diff --git a/lib/csharp/se/lth/control/labcomm2014/WrappingEncoder.cs b/lib/csharp/se/lth/control/labcomm2014/WrappingEncoder.cs
new file mode 100644
index 0000000..5a0dc3c
--- /dev/null
+++ b/lib/csharp/se/lth/control/labcomm2014/WrappingEncoder.cs
@@ -0,0 +1,71 @@
+namespace se.lth.control.labcomm2014 {
+
+  using System;
+
+  public class WrappingEncoder : Encoder {
+    
+    private Encoder encoder;
+
+    public WrappingEncoder(Encoder encoder) {
+      this.encoder = encoder;
+    }
+
+    public virtual void register(SampleDispatcher dispatcher) {
+      encoder.register(dispatcher);
+    }
+
+    public virtual void registerSampleRef(SampleDispatcher dispatcher) {
+      encoder.registerSampleRef(dispatcher);
+    }
+    
+    public virtual void begin(SampleDispatcher dispatcher) {
+      encoder.begin(dispatcher);
+    }
+    
+    public virtual void end(SampleDispatcher dispatcher) {
+      encoder.end(dispatcher);
+    }
+
+    public virtual void encodeBoolean(bool value) {
+      encoder.encodeBoolean(value);
+    }
+    
+    public virtual void encodeByte(byte value) {
+      encoder.encodeByte(value);
+    }
+    
+    public virtual void encodeShort(short value) {
+      encoder.encodeShort(value);
+    }
+    
+    public virtual void encodeInt(int value) {
+      encoder.encodeInt(value);
+    }
+    
+    public virtual void encodeLong(long value) {
+      encoder.encodeLong(value);
+    }
+    
+    public virtual void encodeFloat(float value) {
+      encoder.encodeFloat(value);
+    }
+    
+    public virtual void encodeDouble(double value) {
+      encoder.encodeDouble(value);
+    }
+    
+    public virtual void encodeString(String value) {
+      encoder.encodeString(value);
+    }
+    
+    public virtual void encodePacked32(Int64 value) {
+      encoder.encodePacked32(value);
+    }
+    
+    public virtual void encodeSampleRef(SampleDispatcher value) {
+      encoder.encodeSampleRef(value);
+    }
+    
+  }
+
+}
diff --git a/test/Makefile b/test/Makefile
index 456cc4e..055df04 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -35,17 +35,18 @@ test_%: gen/%/signatures.py \
 .PHONY: test_renaming_%
 test_renaming_%: gen/%/signatures.py \
 		gen/%/c_renaming_relay \
-		gen/%/cs_relay.exe \
+		gen/%/cs_renaming_relay.exe \
 		gen/%/java_relay.class \
 		gen/%/java_code
 	PYTHONPATH=$(PYTHONPATH) MONO_PATH=$(MONO_PATH) \
-		./test_renaming_encoder_decoder.py \
+	    ./test_renaming_encoder_decoder.py \
 		--signatures=gen/$*/signatures.py \
 		--test tee gen/$*/testdata.renamed \
 		--test $(shell echo $(VALGRIND) | sed -e 's/[-][-]/\\\\--/g') \
-		       gen/$*/c_renaming_relay /dev/stdin /dev/stdout
+		       gen/$*/c_renaming_relay /dev/stdin /dev/stdout \
+		--test mono gen/$*/cs_renaming_relay.exe \
+		       /dev/stdin /dev/stdout
 	echo \
-		--test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \
 		--test java \\-cp gen/$*:../lib/java/labcomm2014.jar \
 		       java_relay /dev/stdin /dev/stdout
 
@@ -111,6 +112,15 @@ gen/%/cs_relay.cs:  gen/%/typeinfo relay_gen_cs.py Makefile
 gen/%/cs_relay.exe: gen/%/cs_relay.cs gen/%/cs_code.cs Makefile
 	mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm2014
 
+.PRECIOUS: gen/%/cs_renaming_relay.cs
+gen/%/cs_renaming_relay.cs:  gen/%/typeinfo relay_gen_cs.py Makefile
+	./relay_gen_cs.py --renaming $< > $@
+
+.PRECIOUS: gen/%/cs_renaming_relay.exe
+gen/%/cs_renaming_relay.exe: gen/%/cs_renaming_relay.cs \
+			     gen/%/cs_code.cs Makefile
+	mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm2014
+
 # Java relay test rules
 .PRECIOUS: gen/%/java_code
 gen/%/java_code: %.lc | gen/%/.dir
diff --git a/test/relay_gen_cs.py b/test/relay_gen_cs.py
index e5698aa..b2bfffe 100755
--- a/test/relay_gen_cs.py
+++ b/test/relay_gen_cs.py
@@ -1,5 +1,6 @@
 #!/usr/bin/python
 
+import argparse
 import re
 import sys
 import random
@@ -18,7 +19,13 @@ def shuffle(l):
     return result
 
 if __name__ == '__main__':
-    f = open(sys.argv[1])
+    parser = argparse.ArgumentParser(description='Generate C test relay.')
+    parser.add_argument('--renaming', action='store_true')
+    parser.add_argument('typeinfo', help='typeinfo file')
+
+    options = parser.parse_args(sys.argv[1:])
+
+    f = open(options.typeinfo)
     sample = []
     for l in map(lambda s: s.strip(), f):
         lang,kind,func,arg,dummy = l[1:].split(l[0])
@@ -40,7 +47,9 @@ if __name__ == '__main__':
     result.append('  %s.Handler' % sample[-1][0])
     result.extend(split_match('^[^|]*\|(.*)$', """
       |{
-      |  EncoderChannel encoder;
+      |  Encoder encoder;
+      |  Decoder decoder;
+      |
     """))
     for func,arg in sample:
         if arg == 'void':
@@ -63,13 +72,22 @@ if __name__ == '__main__':
       |    FileStream InFile = new FileStream(InName,
       |                                       FileMode.Open,
       |                                       FileAccess.Read);
-      |    DecoderChannel decoder = new DecoderChannel(InFile);
+      |    decoder = new DecoderChannel(InFile);
       |    FileStream OutFile = new FileStream(OutName,
       |                                        FileMode.OpenOrCreate,
       |                                        FileAccess.Write);
       |    encoder = new EncoderChannel(OutFile);
-      |
     """))
+    if options.renaming:
+        result.extend(split_match('^[^|]*\|(.*)$', """
+        |    RenamingRegistry registry = new RenamingRegistry();
+        |    decoder = new RenamingDecoder(
+        |        decoder, registry, s => "prefix:" + s + ":suffix");
+        |    encoder = new RenamingEncoder(
+        |        encoder, registry, s => "prefix:" + s + ":suffix");
+        """))
+
+
     for func,arg in shuffle(sample):
         result.append('    %s.register(decoder, this);' % func)
         pass
-- 
GitLab