From d4c13c73a964f784ef0c6df2f638477c8144e297 Mon Sep 17 00:00:00 2001 From: Sinan Date: Tue, 18 Sep 2018 17:03:54 +0200 Subject: [PATCH 3/4] Add converter repository Implements all default converter. A registration of new types (Protobuf IMessage types) is missing and has to be implemented yet! --- rsb-cil/Rsb/Converter/ByteConverter.cs | 24 ++++++ .../Rsb/Converter/DefaultConverterRepository.cs | 87 ++++++++++++++++++++++ rsb-cil/Rsb/Converter/DoubleConverter.cs | 27 +++++++ rsb-cil/Rsb/Converter/FloatConverter.cs | 27 +++++++ rsb-cil/Rsb/Converter/Int32Converter.cs | 28 +++++++ rsb-cil/Rsb/Converter/Int64Converter.cs | 27 +++++++ rsb-cil/Rsb/Converter/NullConverter.cs | 46 ++++++++++++ rsb-cil/Rsb/Converter/StringConverter.cs | 41 ++++++++++ rsb-cil/Rsb/Converter/UInt32Converter.cs | 27 +++++++ rsb-cil/Rsb/Converter/UInt64Converter.cs | 27 +++++++ rsb-cil/rsb-cil.csproj | 10 +++ 11 files changed, 371 insertions(+) create mode 100644 rsb-cil/Rsb/Converter/ByteConverter.cs create mode 100644 rsb-cil/Rsb/Converter/DefaultConverterRepository.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/Rsb/Converter/ByteConverter.cs b/rsb-cil/Rsb/Converter/ByteConverter.cs new file mode 100644 index 0000000..ec54d46 --- /dev/null +++ b/rsb-cil/Rsb/Converter/ByteConverter.cs @@ -0,0 +1,24 @@ +using System; + +namespace Rsb.Converter +{ + internal class ByteConverter : IConverter + { + + private static readonly string WIRE_SCHEMA = "bytes"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_SCHEMA) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + return data.Item2; + } + + public Tuple Serialize(object data) + { + return new Tuple(WIRE_SCHEMA, (byte[]) data); + } + } +} diff --git a/rsb-cil/Rsb/Converter/DefaultConverterRepository.cs b/rsb-cil/Rsb/Converter/DefaultConverterRepository.cs new file mode 100644 index 0000000..55a08e0 --- /dev/null +++ b/rsb-cil/Rsb/Converter/DefaultConverterRepository.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +namespace Rsb.Converter +{ + public class DefaultConverterRepository + { + private static readonly DefaultConverterRepository instance = new DefaultConverterRepository(); + + private List.Predicate, IConverter>> listenerConverterList = new List.Predicate, IConverter>>(); + private PredicateConverterSelection listenerConverterSelector = null; + + public PredicateConverterSelection ListenerConverterSelector { get => listenerConverterSelector; } + + private List.Predicate, IConverter>> informerConverterList = new List.Predicate, IConverter>>(); + private PredicateConverterSelection informerConverterSelector = null; + + public PredicateConverterSelection InformerConverterSelector { get => informerConverterSelector; } + + private readonly Tuple[] defaultConverter = { + new Tuple("void", new NullConverter()), + new Tuple("double", new DoubleConverter()), + new Tuple("float", new FloatConverter()), + new Tuple("int32", new Int32Converter()), + new Tuple("int64", new Int64Converter()), + new Tuple("uint32", new UInt32Converter()), + new Tuple("uint64", new UInt64Converter()), + new Tuple("bool", new BoolConverter()), + new Tuple("ascii-string", new StringConverter(false)), + new Tuple("utf-8-string", new StringConverter()), + new Tuple("bytes", new ByteConverter()), + //new Tuple("scope", new NullConverter()), + }; + + private readonly Dictionary defaultTypeNames = new Dictionary + { + {"void", typeof(Null)}, + {"double", typeof(double)}, + {"float", typeof(float)}, + {"int32", typeof(int)}, + {"int64", typeof(long)}, + {"uint32", typeof(uint)}, + {"uint64", typeof(ulong)}, + { "bool", typeof(bool)}, + {"utf-8-string", typeof(string)}, + {"bytes", typeof(byte[])}, + {"scope", typeof(Scope)} + }; + + // Explicit static constructor to tell C# compiler + // not to mark type as beforefieldinit + static DefaultConverterRepository() + { + } + + private DefaultConverterRepository() + { + foreach (var type in defaultConverter) { + listenerConverterList.Add( + new Tuple.Predicate, IConverter>( + new IsExactMatch(type.Item1), + type.Item2 + )); + // will just send utf8 + if (type.Item1.Equals("ascii-string")) { + continue; + } + informerConverterList.Add( + new Tuple.Predicate, IConverter>( + new IsExactMatch(defaultTypeNames[type.Item1]), + type.Item2 + )); + } + + listenerConverterSelector = new PredicateConverterSelection(listenerConverterList); + informerConverterSelector = new PredicateConverterSelection(informerConverterList); + } + + public static DefaultConverterRepository Instance + { + get + { + return instance; + } + } + } +} diff --git a/rsb-cil/Rsb/Converter/DoubleConverter.cs b/rsb-cil/Rsb/Converter/DoubleConverter.cs new file mode 100644 index 0000000..d676587 --- /dev/null +++ b/rsb-cil/Rsb/Converter/DoubleConverter.cs @@ -0,0 +1,27 @@ +using System; + +namespace Rsb.Converter +{ + internal class DoubleConverter : IConverter + { + private static readonly string WIRE_SCHEMA = "double"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_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 Tuple Serialize(object data) + { + return new Tuple(WIRE_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..d0c9098 --- /dev/null +++ b/rsb-cil/Rsb/Converter/FloatConverter.cs @@ -0,0 +1,27 @@ +using System; + +namespace Rsb.Converter +{ + internal class FloatConverter : IConverter + { + private static readonly string WIRE_SCHEMA = "float"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_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 Tuple Serialize(object data) + { + return new Tuple(WIRE_SCHEMA, BitConverter.GetBytes((float)data)); + } + } +} diff --git a/rsb-cil/Rsb/Converter/Int32Converter.cs b/rsb-cil/Rsb/Converter/Int32Converter.cs new file mode 100644 index 0000000..4539457 --- /dev/null +++ b/rsb-cil/Rsb/Converter/Int32Converter.cs @@ -0,0 +1,28 @@ +using System; + +namespace Rsb.Converter +{ + internal class Int32Converter : IConverter + { + + private static readonly string WIRE_SCHEMA = "int32"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_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 Tuple Serialize(object data) + { + return new Tuple(WIRE_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..fbaa82f --- /dev/null +++ b/rsb-cil/Rsb/Converter/Int64Converter.cs @@ -0,0 +1,27 @@ +using System; + +namespace Rsb.Converter +{ + internal class Int64Converter : IConverter + { + private static readonly string WIRE_SCHEMA = "int64"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_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 Tuple Serialize(object data) + { + return new Tuple(WIRE_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..498e987 --- /dev/null +++ b/rsb-cil/Rsb/Converter/NullConverter.cs @@ -0,0 +1,46 @@ +using System; + +namespace Rsb.Converter +{ + internal class NullConverter : IConverter + { + private static readonly string WIRE_SCHEMA = "void"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_SCHEMA) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + return null; + } + + public Tuple Serialize(object data) + { + return new Tuple(WIRE_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/StringConverter.cs b/rsb-cil/Rsb/Converter/StringConverter.cs new file mode 100644 index 0000000..e400cea --- /dev/null +++ b/rsb-cil/Rsb/Converter/StringConverter.cs @@ -0,0 +1,41 @@ +using System; + +namespace Rsb.Converter +{ + internal class StringConverter : IConverter + { + + private System.Text.Encoding Encoding; + private bool isUTF8; + + private static readonly string WIRE_SCHEMA_UTF8 = "utf-8-string"; + private static readonly string WIRE_SCHEMA_ASCII = "ascii-string"; + + public StringConverter(bool utf8 = true) { + this.isUTF8 = utf8; + if (utf8) + { + Encoding = new System.Text.UTF8Encoding(); + } + else { + Encoding = new System.Text.ASCIIEncoding(); + } + } + + public object Deserialize(Tuple data) + { + if ( + (isUTF8 && data.Item1 != WIRE_SCHEMA_UTF8) || + (!isUTF8 && data.Item1 != WIRE_SCHEMA_ASCII) ) + { + throw new ConversionException("Unexpected wire schema for deserialization: " + data.Item1); + } + return Encoding.GetString(data.Item2); + } + + public Tuple Serialize(object data) + { + return new Tuple(isUTF8 ? WIRE_SCHEMA_UTF8 : WIRE_SCHEMA_ASCII, Encoding.GetBytes(data.ToString())); + } + } +} diff --git a/rsb-cil/Rsb/Converter/UInt32Converter.cs b/rsb-cil/Rsb/Converter/UInt32Converter.cs new file mode 100644 index 0000000..ec432cb --- /dev/null +++ b/rsb-cil/Rsb/Converter/UInt32Converter.cs @@ -0,0 +1,27 @@ +using System; + +namespace Rsb.Converter +{ + internal class UInt32Converter : IConverter + { + private static readonly string WIRE_SCHEMA = "uint32"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_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 Tuple Serialize(object data) + { + return new Tuple(WIRE_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..5df468f --- /dev/null +++ b/rsb-cil/Rsb/Converter/UInt64Converter.cs @@ -0,0 +1,27 @@ +using System; + +namespace Rsb.Converter +{ + internal class UInt64Converter : IConverter + { + private static readonly string WIRE_SCHEMA = "uint64"; + + public object Deserialize(Tuple data) + { + if (data.Item1 != WIRE_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 Tuple Serialize(object data) + { + return new Tuple(WIRE_SCHEMA, BitConverter.GetBytes((ulong)data)); + } + } +} diff --git a/rsb-cil/rsb-cil.csproj b/rsb-cil/rsb-cil.csproj index 7dfdb85..b219832 100644 --- a/rsb-cil/rsb-cil.csproj +++ b/rsb-cil/rsb-cil.csproj @@ -39,6 +39,16 @@ + + + + + + + + + + -- 2.14.2.windows.1