From da70c12111b55bb620ec5c7a3ad896c8c25d7c53 Mon Sep 17 00:00:00 2001 From: Sinan Date: Wed, 26 Sep 2018 16:12:24 +0200 Subject: [PATCH 2/7] Implement the default converters --- rsb-cil-test/Program.cs | 73 +++++++++++++++++++++++- rsb-cil/Rsb/Converter/BoolConverter.cs | 14 +++-- rsb-cil/Rsb/Converter/ByteConverter.cs | 28 +++++++++ rsb-cil/Rsb/Converter/ConverterSignature.cs | 63 ++++++++++++++++++++ rsb-cil/Rsb/Converter/DoubleConverter.cs | 32 +++++++++++ rsb-cil/Rsb/Converter/FloatConverter.cs | 32 +++++++++++ rsb-cil/Rsb/Converter/IConverter.cs | 2 + rsb-cil/Rsb/Converter/Int32Converter.cs | 32 +++++++++++ rsb-cil/Rsb/Converter/Int64Converter.cs | 32 +++++++++++ rsb-cil/Rsb/Converter/NullConverter.cs | 51 +++++++++++++++++ rsb-cil/Rsb/Converter/ProtocolBufferConverter.cs | 34 ++++++----- rsb-cil/Rsb/Converter/StringConverter.cs | 43 ++++++++++++++ rsb-cil/Rsb/Converter/UInt32Converter.cs | 32 +++++++++++ rsb-cil/Rsb/Converter/UInt64Converter.cs | 32 +++++++++++ rsb-cil/rsb-cil.csproj | 10 ++++ 15 files changed, 491 insertions(+), 19 deletions(-) create mode 100644 rsb-cil/Rsb/Converter/ByteConverter.cs create mode 100644 rsb-cil/Rsb/Converter/ConverterSignature.cs create mode 100644 rsb-cil/Rsb/Converter/DoubleConverter.cs create mode 100644 rsb-cil/Rsb/Converter/FloatConverter.cs create mode 100644 rsb-cil/Rsb/Converter/Int32Converter.cs create mode 100644 rsb-cil/Rsb/Converter/Int64Converter.cs create mode 100644 rsb-cil/Rsb/Converter/NullConverter.cs create mode 100644 rsb-cil/Rsb/Converter/StringConverter.cs create mode 100644 rsb-cil/Rsb/Converter/UInt32Converter.cs create mode 100644 rsb-cil/Rsb/Converter/UInt64Converter.cs diff --git a/rsb-cil-test/Program.cs b/rsb-cil-test/Program.cs index 313e9cd..6547f9b 100644 --- a/rsb-cil-test/Program.cs +++ b/rsb-cil-test/Program.cs @@ -79,7 +79,78 @@ namespace rsbciltest listener.Deactivate(); - } + Console.WriteLine("\nConverter test:"); + + var defaultInConverters = buildConverterSelection(new List> { + new Tuple("ascii-string", new StringConverter(false) ), + new Tuple("utf-8-string", new StringConverter(true) ), + new Tuple("int32", new Int32Converter() ), + new Tuple("int64", new Int64Converter() ), + new Tuple("uint32", new UInt32Converter() ), + new Tuple("uint64", new UInt64Converter() ), + new Tuple("float", new FloatConverter() ), + new Tuple("double", new DoubleConverter() ), + new Tuple("bool", new BoolConverter() ), + new Tuple("bytes", new ByteConverter() ), + new Tuple("void", new NullConverter() ), + new Tuple("." + JointAngles.Descriptor.FullName, new ProtocolBufferConverter(JointAngles.Descriptor)) + }); + + var defaultOutConverters = buildConverterSelection(new List> { + new Tuple(typeof(string), new StringConverter(true) ), + new Tuple(typeof(int), new Int32Converter() ), + new Tuple(typeof(long), new Int64Converter() ), + new Tuple(typeof(uint), new UInt32Converter() ), + new Tuple(typeof(ulong), new UInt64Converter() ), + new Tuple(typeof(float), new FloatConverter() ), + new Tuple(typeof(double), new DoubleConverter() ), + new Tuple(typeof(bool), new BoolConverter() ), + new Tuple(typeof(byte[]), new ByteConverter() ), + new Tuple(typeof(Null), new NullConverter() ), + new Tuple(typeof(JointAngles), new ProtocolBufferConverter(JointAngles.Descriptor)) + }); + + Informer repoInformer = new Informer("/test/repo", new OutConnector(new BusClientConnection(host, port), defaultOutConverters)); + Listener repoListener = new Listener(new InPushConnector(new BusClientConnection(host, port), new Scope("/"), defaultInConverters)); + repoListener.EventReceived += (e) => { + Console.WriteLine("Event: {0}\nData: {1}", e, e.Data); + }; + repoListener.Activate(); + repoInformer.Activate(); + + //test string + repoInformer.Send("Teest"); + //test bool + repoInformer.Send(true); + //test int + repoInformer.Send(42); + //test long (int64 + repoInformer.Send((long)42); + //test for uint32 + repoInformer.Send((uint)4242); + //test for uint64 + repoInformer.Send((ulong)4242); + //test double + repoInformer.Send(4.2); + //test float + repoInformer.Send((float)4.2); + //test byte[] + byte[] test = { 12, 13, 14, 255 }; + repoInformer.Send(test); + //test void + repoInformer.Send(Null.Instance); + // protobuf type + var jointAngles = new JointAngles(); + for (int i = 0; i < 5; i++) + { + jointAngles.Angles.Add(i); + repoInformer.Send(jointAngles); + } + + repoInformer.Deactivate(); + Console.ReadKey(); + repoListener.Deactivate(); + } } } diff --git a/rsb-cil/Rsb/Converter/BoolConverter.cs b/rsb-cil/Rsb/Converter/BoolConverter.cs index 291bcfe..7b4de1f 100644 --- a/rsb-cil/Rsb/Converter/BoolConverter.cs +++ b/rsb-cil/Rsb/Converter/BoolConverter.cs @@ -4,11 +4,11 @@ namespace Rsb.Converter public class BoolConverter: IConverter { - private static readonly string WIRE_SCHEMA = "bool"; + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("bool", typeof(bool)); public object Deserialize(Tuple data) { - if (data.Item1 != WIRE_SCHEMA) + if (data.Item1 != SIGNATURE.Schema) { throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); } @@ -19,10 +19,16 @@ namespace Rsb.Converter return data.Item2[0] != 0; } - public Tuple Serialize(object data) + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) { - return new Tuple(WIRE_SCHEMA, ((bool)data) ? new byte[] { 1 } : new byte[] { 0 }); + return new Tuple(SIGNATURE.Schema, ((bool)data) ? new byte[] { 1 } : new byte[] { 0 }); } + } } diff --git a/rsb-cil/Rsb/Converter/ByteConverter.cs b/rsb-cil/Rsb/Converter/ByteConverter.cs new file mode 100644 index 0000000..9a3210f --- /dev/null +++ b/rsb-cil/Rsb/Converter/ByteConverter.cs @@ -0,0 +1,28 @@ +using System; + +namespace Rsb.Converter +{ + public class ByteConverter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("bytes", typeof(byte[])); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + return data.Item2; + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, (byte[]) data); + } + } +} diff --git a/rsb-cil/Rsb/Converter/ConverterSignature.cs b/rsb-cil/Rsb/Converter/ConverterSignature.cs new file mode 100644 index 0000000..c0ebbe1 --- /dev/null +++ b/rsb-cil/Rsb/Converter/ConverterSignature.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rsb.Converter +{ + public class ConverterSignature + { + private String schema; + private Type dataType; + + public String Schema { get => schema; } + public Type DataType { get => dataType; } + + public ConverterSignature(String schema, Type dataType) + { + this.schema = schema; + this.dataType = dataType; + } + + public override int GetHashCode() + { + int prime = 31; + int result = 1; + result = prime * result + this.dataType.GetHashCode(); + result = prime * result + this.schema.GetHashCode(); + return result; + } + + public override bool Equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + ConverterSignature rhs = obj as ConverterSignature; + if (rhs == null) { + return false; + } + if (!this.dataType.Equals(rhs.dataType)) + { + return false; + } + if (!this.schema.Equals(rhs.schema)) + { + return false; + } + return true; + } + + public override String ToString() + { + return "ConverterSignature [schema=" + this.schema + ", datatype=" + + this.dataType + "]"; + } + } +} diff --git a/rsb-cil/Rsb/Converter/DoubleConverter.cs b/rsb-cil/Rsb/Converter/DoubleConverter.cs new file mode 100644 index 0000000..16ed139 --- /dev/null +++ b/rsb-cil/Rsb/Converter/DoubleConverter.cs @@ -0,0 +1,32 @@ +using System; + +namespace Rsb.Converter +{ + public class DoubleConverter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("double", typeof(double)); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + if (data.Item2.Length != 8) + { + throw new ConversionException("Data of type double must have length 8. Received: " + data.Item2.Length); + } + return BitConverter.ToDouble(data.Item2, 0); + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, BitConverter.GetBytes((double)data)); + } + } +} diff --git a/rsb-cil/Rsb/Converter/FloatConverter.cs b/rsb-cil/Rsb/Converter/FloatConverter.cs new file mode 100644 index 0000000..724370b --- /dev/null +++ b/rsb-cil/Rsb/Converter/FloatConverter.cs @@ -0,0 +1,32 @@ +using System; + +namespace Rsb.Converter +{ + public class FloatConverter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("float", typeof(float)); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + if (data.Item2.Length != 4) + { + throw new ConversionException("Data of type float must have length 4. Received: " + data.Item2.Length); + } + return BitConverter.ToSingle(data.Item2, 0); + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, BitConverter.GetBytes((float)data)); + } + } +} diff --git a/rsb-cil/Rsb/Converter/IConverter.cs b/rsb-cil/Rsb/Converter/IConverter.cs index 1933d95..59aa225 100644 --- a/rsb-cil/Rsb/Converter/IConverter.cs +++ b/rsb-cil/Rsb/Converter/IConverter.cs @@ -8,5 +8,7 @@ namespace Rsb.Converter object Deserialize(Tuple data); + ConverterSignature GetSignature(); + } } diff --git a/rsb-cil/Rsb/Converter/Int32Converter.cs b/rsb-cil/Rsb/Converter/Int32Converter.cs new file mode 100644 index 0000000..5d0ad1a --- /dev/null +++ b/rsb-cil/Rsb/Converter/Int32Converter.cs @@ -0,0 +1,32 @@ +using System; + +namespace Rsb.Converter +{ + public class Int32Converter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("int32", typeof(int)); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + if (data.Item2.Length != 4) + { + throw new ConversionException("Data of type int32 must have length 4. Received: " + data.Item2.Length); + } + return BitConverter.ToInt32(data.Item2,0); + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, BitConverter.GetBytes((int) data)); + } + } +} diff --git a/rsb-cil/Rsb/Converter/Int64Converter.cs b/rsb-cil/Rsb/Converter/Int64Converter.cs new file mode 100644 index 0000000..1e1ee7a --- /dev/null +++ b/rsb-cil/Rsb/Converter/Int64Converter.cs @@ -0,0 +1,32 @@ +using System; + +namespace Rsb.Converter +{ + public class Int64Converter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("int64", typeof(long)); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + if (data.Item2.Length != 8) + { + throw new ConversionException("Data of type int64 must have length 8. Received: " + data.Item2.Length); + } + return BitConverter.ToInt64(data.Item2, 0); + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, BitConverter.GetBytes((long)data)); + } + } +} diff --git a/rsb-cil/Rsb/Converter/NullConverter.cs b/rsb-cil/Rsb/Converter/NullConverter.cs new file mode 100644 index 0000000..5649647 --- /dev/null +++ b/rsb-cil/Rsb/Converter/NullConverter.cs @@ -0,0 +1,51 @@ +using System; + +namespace Rsb.Converter +{ + public class NullConverter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("void", typeof(Null)); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + return null; + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, new byte[0]); + } + } + + public sealed class Null { + private static readonly Null instance = new Null(); + + // Explicit static constructor to tell C# compiler + // not to mark type as beforefieldinit + static Null() + { + } + + private Null() + { + } + + public static Null Instance + { + get + { + return instance; + } + } + } + +} diff --git a/rsb-cil/Rsb/Converter/ProtocolBufferConverter.cs b/rsb-cil/Rsb/Converter/ProtocolBufferConverter.cs index 747433e..7679c91 100644 --- a/rsb-cil/Rsb/Converter/ProtocolBufferConverter.cs +++ b/rsb-cil/Rsb/Converter/ProtocolBufferConverter.cs @@ -3,23 +3,24 @@ using Google.Protobuf; using Google.Protobuf.Reflection; namespace Rsb.Converter { - public class ProtocolBufferConverter: IConverter - { + public class ProtocolBufferConverter : IConverter + { + private ConverterSignature SIGNATURE; - private MessageDescriptor descriptor; - private string wireSchema; - - public ProtocolBufferConverter(MessageDescriptor descriptor) - { - this.wireSchema = "." + descriptor.FullName; - this.descriptor = descriptor; - } + private MessageDescriptor descriptor; + + public ProtocolBufferConverter(MessageDescriptor descriptor) + { + SIGNATURE = new ConverterSignature("." + descriptor.FullName, descriptor.ClrType); + + this.descriptor = descriptor; + } public object Deserialize(Tuple data) { - if (data.Item1 != this.wireSchema) + if (data.Item1 != SIGNATURE.Schema) { - throw new ConversionException("Cannot deserialize data of type " + data.Item1 + ". Expecting " + wireSchema); + throw new ConversionException("Cannot deserialize data of type " + data.Item1 + ". Expecting " + SIGNATURE.Schema); } return this.descriptor.Parser.ParseFrom(data.Item2); @@ -28,7 +29,12 @@ namespace Rsb.Converter public Tuple Serialize(object data) { IMessage message = (Google.Protobuf.IMessage)data; - return new Tuple(this.wireSchema, message.ToByteArray()); + return new Tuple(SIGNATURE.Schema, message.ToByteArray()); } - } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + } } diff --git a/rsb-cil/Rsb/Converter/StringConverter.cs b/rsb-cil/Rsb/Converter/StringConverter.cs new file mode 100644 index 0000000..a124d27 --- /dev/null +++ b/rsb-cil/Rsb/Converter/StringConverter.cs @@ -0,0 +1,43 @@ +using System; + +namespace Rsb.Converter +{ + public class StringConverter : IConverter + { + + private System.Text.Encoding Encoding; + + private ConverterSignature SIGNATURE; + + public StringConverter(bool utf8 = true) { + if (utf8) + { + Encoding = new System.Text.UTF8Encoding(); + SIGNATURE = new ConverterSignature("utf-8-string", typeof(string)); + } + else { + Encoding = new System.Text.ASCIIEncoding(); + SIGNATURE = new ConverterSignature("ascii-string", typeof(string)); + } + } + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + return Encoding.GetString(data.Item2); + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, Encoding.GetBytes(data.ToString())); + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + } +} diff --git a/rsb-cil/Rsb/Converter/UInt32Converter.cs b/rsb-cil/Rsb/Converter/UInt32Converter.cs new file mode 100644 index 0000000..6083fcd --- /dev/null +++ b/rsb-cil/Rsb/Converter/UInt32Converter.cs @@ -0,0 +1,32 @@ +using System; + +namespace Rsb.Converter +{ + public class UInt32Converter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("uint32", typeof(uint)); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + if (data.Item2.Length != 4) + { + throw new ConversionException("Data of type uint32 must have length 4. Received: " + data.Item2.Length); + } + return BitConverter.ToUInt32(data.Item2, 0); + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, BitConverter.GetBytes((uint)data)); + } + } +} diff --git a/rsb-cil/Rsb/Converter/UInt64Converter.cs b/rsb-cil/Rsb/Converter/UInt64Converter.cs new file mode 100644 index 0000000..bbb2fc2 --- /dev/null +++ b/rsb-cil/Rsb/Converter/UInt64Converter.cs @@ -0,0 +1,32 @@ +using System; + +namespace Rsb.Converter +{ + public class UInt64Converter : IConverter + { + private static readonly ConverterSignature SIGNATURE = new ConverterSignature("uint64", typeof(ulong)); + + public object Deserialize(Tuple data) + { + if (data.Item1 != SIGNATURE.Schema) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + if (data.Item2.Length != 8) + { + throw new ConversionException("Data of type uint64 must have length 8. Received: " + data.Item2.Length); + } + return BitConverter.ToUInt64(data.Item2, 0); + } + + public ConverterSignature GetSignature() + { + return SIGNATURE; + } + + public Tuple Serialize(object data) + { + return new Tuple(SIGNATURE.Schema, BitConverter.GetBytes((ulong)data)); + } + } +} diff --git a/rsb-cil/rsb-cil.csproj b/rsb-cil/rsb-cil.csproj index 041d042..916d69b 100644 --- a/rsb-cil/rsb-cil.csproj +++ b/rsb-cil/rsb-cil.csproj @@ -40,6 +40,16 @@ + + + + + + + + + + -- 2.14.2.windows.1