using Google.Protobuf; using Newtonsoft.Json; using Newtonsoft.Json.Bson; using Newtonsoft.Json.Serialization; using ProtoBuf; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.Bson; using Tango.PMR; using Tango.PMR.Common; using Tango.PMR.Integration; namespace Tango.Transport { public static class GenericMessageSerializer { private static JsonSerializer _serializer; static GenericMessageSerializer() { _serializer = new BsonUtcSerializer(); ProtoBuf.Meta.RuntimeTypeModel.Default.AutoAddMissingTypes = true; ProtoBuf.Meta.RuntimeTypeModel.Default.AutoAddProtoContractTypesOnly = false; ProtoBuf.Meta.RuntimeTypeModel.Default.InferTagFromNameDefault = true; ProtoBuf.Meta.RuntimeTypeModel.Default.UseImplicitZeroDefaults = true; } public static object Deserialize(Type type, byte[] array, GenericMessageProtocol mode) { if (mode == GenericMessageProtocol.Json) { return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(array), type); } else if (mode == GenericMessageProtocol.Bson) { return DeserializeFromBson(array, type); } else { AutoProtobuf.Build(type); using (MemoryStream ms = new MemoryStream(array)) { return Serializer.Deserialize(type, ms); } } } public static object DeserializeFromByteString(Type type, ByteString byteString, GenericMessageProtocol mode) { if (mode == GenericMessageProtocol.Json) { return JsonConvert.DeserializeObject(byteString.ToStringUtf8(), type); } else if (mode == GenericMessageProtocol.Bson) { return DeserializeFromBson(byteString.ToByteArray(), type); } else { AutoProtobuf.Build(type); return Deserialize(type, byteString.ToByteArray(), mode); } } //--------------------------------------------------------------------- public static byte[] Serialize(T message, GenericMessageProtocol mode) { if (mode == GenericMessageProtocol.Json) { return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)); } else if (mode == GenericMessageProtocol.Bson) { return SerializeToBson(message); } else { AutoProtobuf.Build(); using (MemoryStream ms = new MemoryStream()) { Serializer.Serialize(ms, message); return ms.ToArray(); } } } public static T Deserialize(byte[] array, GenericMessageProtocol mode) { if (mode == GenericMessageProtocol.Json) { return (T)Deserialize(typeof(T), array, mode); } else if (mode == GenericMessageProtocol.Bson) { return DeserializeFromBson(array); } else { AutoProtobuf.Build(); using (MemoryStream ms = new MemoryStream(array)) { return Serializer.Deserialize(ms); } } } public static ByteString SerializeToByteString(T message, GenericMessageProtocol mode) { if (mode == GenericMessageProtocol.Json) { var byteString = ByteString.CopyFromUtf8(JsonConvert.SerializeObject(message)); return byteString; } else if (mode == GenericMessageProtocol.Bson) { var byteString = ByteString.CopyFrom(SerializeToBson(message)); return byteString; } else { AutoProtobuf.Build(); return ByteString.CopyFrom(Serialize(message, mode)); } } public static T DeserializeFromByteString(ByteString byteString, GenericMessageProtocol mode) { if (mode == GenericMessageProtocol.Json) { return JsonConvert.DeserializeObject(byteString.ToStringUtf8()); } else if (mode == GenericMessageProtocol.Bson) { return DeserializeFromBson(byteString.ToByteArray()); } else { AutoProtobuf.Build(); return Deserialize(byteString.ToByteArray(), mode); } } public static T ExtractGenericRequestFromContainer(MessageContainer container, GenericMessageProtocol mode) where T : class { var message = MessageFactory.ExtractMessageFromContainer(container); var genericType = Type.GetType((message as GenericRequest).Type); var innerMessage = DeserializeFromByteString(genericType, (message as GenericRequest).Data, mode); return innerMessage as T; } private static byte[] SerializeToBson(Object obj) { MemoryStream ms = new MemoryStream(); using (BsonWriter writer = new BsonWriter(ms)) { _serializer.Serialize(writer, obj); return ms.ToArray(); } } private static Object DeserializeFromBson(byte[] data, Type type) { MemoryStream ms = new MemoryStream(data); using (BsonReader reader = new BsonReader(ms)) { Object obj = _serializer.Deserialize(reader, type); return obj; } } private static T DeserializeFromBson(byte[] data) { MemoryStream ms = new MemoryStream(data); using (BsonReader reader = new BsonReader(ms)) { T obj = _serializer.Deserialize(reader); return obj; } } } }