using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading; namespace ScreenConnect; public class TypeSerializer { private class EnumSerializer : TypeSerializerBase, IInitializeItem { private ITypeSerializer underlyingSerializer; public void InitializeItem(ITypeSerializer underlyingSerializer) { if (this.underlyingSerializer == null) { this.underlyingSerializer = underlyingSerializer as ITypeSerializer; } } public override int? GetFixedSize() { return underlyingSerializer.GetFixedSize(); } public override void SerializeType(BinaryWriter writer, TEnum obj, Constraint constraint = default(Constraint)) { underlyingSerializer.SerializeType(writer, (TUnderlying)Convert.ChangeType(obj, typeof(TUnderlying), null), constraint); } public override TEnum DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return (TEnum)underlyingSerializer.Deserialize(reader, constraint); } } private class ArraySerializer : TypeSerializerBase, IInitializeItem { private ITypeSerializer elementSerializer; public void InitializeItem(ITypeSerializer elementSerializer) { if (this.elementSerializer == null) { this.elementSerializer = elementSerializer as ITypeSerializer; } } public override void SerializeType(BinaryWriter writer, TElement[] obj, Constraint constraint = default(Constraint)) { int num = ((obj != null) ? obj.Length : 0); constraint.AssertSizeValid(num); writer.Write7BitEncodedInt(num); for (int i = 0; i < num; i++) { elementSerializer.SerializeType(writer, obj[i], constraint); } } public override TElement[] DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { int num = reader.Read7BitEncodedInt(); constraint.AssertSizeValid(num); TElement[] array = new TElement[num]; for (int i = 0; i < num; i++) { array[i] = elementSerializer.DeserializeType(reader, constraint); } return array; } } private class DictionarySerializer : TypeSerializerBase>, IInitializeItem where TKey : notnull { private ITypeSerializer keySerializer; private ITypeSerializer valueSerializer; public void InitializeItem(ITypeSerializer serializer) { if (keySerializer == null) { keySerializer = serializer as ITypeSerializer; } if (valueSerializer == null) { valueSerializer = serializer as ITypeSerializer; } } public override void SerializeType(BinaryWriter writer, IDictionary obj, Constraint constraint = default(Constraint)) { if (obj == null) { writer.Write7BitEncodedInt(0); return; } writer.Write7BitEncodedInt(obj.Count); foreach (var (obj2, obj3) in obj) { keySerializer.SerializeType(writer, obj2, constraint); valueSerializer.SerializeType(writer, obj3, constraint); } } public override IDictionary DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { int num = reader.Read7BitEncodedInt(); OrderedDictionary orderedDictionary = new OrderedDictionary(num); for (int i = 0; i < num; i++) { orderedDictionary.Add(keySerializer.DeserializeType(reader, constraint), valueSerializer.DeserializeType(reader, constraint)); } return orderedDictionary; } } private class ComplexSerializer : TypeSerializerBase, IInitializeItem>, IInitializeItem where T : new() { private IList propertySerializers; private Constraint constraint; public void InitializeItem(IList propertySerializers) { this.propertySerializers = propertySerializers; } public void InitializeItem(Constraint constraint) { this.constraint = constraint; } public override int? GetFixedSize() { return TypeSerializer.GetFixedSize((IEnumerable)propertySerializers); } public override void SerializeType(BinaryWriter writer, T obj, Constraint constraint = default(Constraint)) { SerializeProperties(writer, propertySerializers, obj, Constraint.Combine(constraint, this.constraint)); } public override T DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { T val = new T(); DeserializeProperties(reader, propertySerializers, val, Constraint.Combine(constraint, this.constraint)); return val; } } private abstract class TypeSerializerBase : ITypeSerializer, ITypeSerializer { public virtual int? GetFixedSize() { return null; } public abstract void SerializeType(BinaryWriter writer, T obj, Constraint constraint = default(Constraint)); public abstract T DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)); public void Serialize(BinaryWriter writer, object obj, Constraint constraint = default(Constraint)) { SerializeType(writer, (T)obj, constraint); } public object Deserialize(BinaryReader reader, Constraint constraint = default(Constraint)) { return DeserializeType(reader, constraint); } } private class Int32Serializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, int obj, Constraint constraint = default(Constraint)) { writer.Write7BitEncodedInt(obj); } public override int DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return reader.Read7BitEncodedInt(); } } private class Int64Serializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, long obj, Constraint constraint = default(Constraint)) { writer.Write7BitEncodedLong(obj); } public override long DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return reader.Read7BitEncodedLong(); } } private class DoubleSerializer : TypeSerializerBase { public override int? GetFixedSize() { return 8; } public override void SerializeType(BinaryWriter writer, double obj, Constraint constraint = default(Constraint)) { writer.Write(obj); } public override double DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return reader.ReadDouble(); } } private class BooleanSerializer : TypeSerializerBase { public override int? GetFixedSize() { return 1; } public override void SerializeType(BinaryWriter writer, bool obj, Constraint constraint = default(Constraint)) { writer.Write(obj); } public override bool DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return reader.ReadBoolean(); } } private class ByteSerializer : TypeSerializerBase { public override int? GetFixedSize() { return 1; } public override void SerializeType(BinaryWriter writer, byte obj, Constraint constraint = default(Constraint)) { writer.Write(obj); } public override byte DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return reader.ReadByte(); } } private class CharacterSerializer : TypeSerializerBase { public override int? GetFixedSize() { return 2; } public override void SerializeType(BinaryWriter writer, char obj, Constraint constraint = default(Constraint)) { writer.Write((byte)(0xFF & ((int)obj >> 8))); writer.Write((byte)(0xFF & obj)); } public override char DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return (char)((reader.ReadByte() << 8) | (reader.ReadByte() & 0xFF)); } } private class GuidSerializer : TypeSerializerBase { public override int? GetFixedSize() { return ReflectionExtensions.SizeOfType(); } public override void SerializeType(BinaryWriter writer, Guid obj, Constraint constraint = default(Constraint)) { writer.Write(obj.ToByteArray()); } public override Guid DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return new Guid(reader.ReadBytes(16)); } } private class CorePointSerializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, CorePoint obj, Constraint constraint = default(Constraint)) { writer.Write7BitEncodedInt(obj.X); writer.Write7BitEncodedInt(obj.Y); } public override CorePoint DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return new CorePoint { X = reader.Read7BitEncodedInt(), Y = reader.Read7BitEncodedInt() }; } } private class CoreSizeSerializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, CoreSize obj, Constraint constraint = default(Constraint)) { writer.Write7BitEncodedInt(obj.Width); writer.Write7BitEncodedInt(obj.Height); } public override CoreSize DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return new CoreSize { Width = reader.Read7BitEncodedInt(), Height = reader.Read7BitEncodedInt() }; } } private class CoreRectSerializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, CoreRect obj, Constraint constraint = default(Constraint)) { writer.Write7BitEncodedInt(obj.X); writer.Write7BitEncodedInt(obj.Y); writer.Write7BitEncodedInt(obj.Width); writer.Write7BitEncodedInt(obj.Height); } public override CoreRect DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return new CoreRect { X = reader.Read7BitEncodedInt(), Y = reader.Read7BitEncodedInt(), Width = reader.Read7BitEncodedInt(), Height = reader.Read7BitEncodedInt() }; } } private class CoreVersionSerializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, CoreVersion obj, Constraint constraint = default(Constraint)) { writer.Write7BitEncodedInt(obj?.Major ?? 0); writer.Write7BitEncodedInt(obj?.Minor ?? 0); writer.Write7BitEncodedInt(obj?.Build ?? 0); writer.Write7BitEncodedInt(obj?.Revision ?? 0); } public override CoreVersion DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return DataObject.GetVersion((ushort)reader.Read7BitEncodedInt(), (ushort)reader.Read7BitEncodedInt(), (ushort)reader.Read7BitEncodedInt(), (ushort)reader.Read7BitEncodedInt()); } } private class StringSerializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, string obj, Constraint constraint = default(Constraint)) { if (obj == null) { writer.Write((byte)0); return; } constraint.AssertSizeValid(obj.Length); byte[] bytes = Constants.UTF8EncodingWithoutPreamble.GetBytes(obj); writer.Write7BitEncodedInt(bytes.Length); writer.Write(bytes); } public override string DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { int num = reader.Read7BitEncodedInt(); constraint.AssertSizeValid(num); byte[] bytes = reader.ReadBytes(num); return Constants.UTF8EncodingWithoutPreamble.GetString(bytes, 0, num); } } private class ByteArraySerializer : TypeSerializerBase { public override void SerializeType(BinaryWriter writer, byte[] obj, Constraint constraint = default(Constraint)) { constraint.AssertSizeValid((obj != null) ? obj.Length : 0); writer.Write7BitEncodedInt((obj != null) ? obj.Length : 0); if (obj != null && obj.Length != 0) { writer.Write(obj, 0, obj.Length); } } public override byte[] DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { int num = reader.Read7BitEncodedInt(); constraint.AssertSizeValid(num); if (num != 0) { return reader.ReadBytes(num); } return Extensions.EmptyArray(); } } private class ByteArraySegmentSerializer : TypeSerializerBase> { public override void SerializeType(BinaryWriter writer, ArraySegment obj, Constraint constraint = default(Constraint)) { constraint.AssertSizeValid(obj.Count); writer.Write7BitEncodedInt(obj.Count); if (obj.Count > 0) { writer.Write(obj.Array, obj.Offset, obj.Count); } } public override ArraySegment DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { int num = reader.Read7BitEncodedInt(); constraint.AssertSizeValid(num); ArraySegment result = new ArraySegment(new byte[num]); if (num > 0) { reader.ReadFully(result.Array, result.Offset, result.Count); } return result; } } private class DateTimeSerializer : TypeSerializerBase { public override int? GetFixedSize() { return 8; } public override void SerializeType(BinaryWriter writer, DateTime obj, Constraint constraint = default(Constraint)) { writer.Write((obj == default(DateTime)) ? 0 : obj.ToBinary()); } public override DateTime DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { long num = reader.ReadInt64(); if (num != 0L) { return DateTime.FromBinary(num); } return default(DateTime); } } private class TimeSpanSerializer : TypeSerializerBase { public override int? GetFixedSize() { return 4; } public override void SerializeType(BinaryWriter writer, TimeSpan obj, Constraint constraint = default(Constraint)) { writer.Write((int)(obj.Ticks / 10000)); } public override TimeSpan DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return new TimeSpan((long)reader.ReadInt32() * 10000L); } } private class TransientStringSerializer : TypeSerializerBase, IInitializeItem> { private ITypeSerializer characterSerializer; public void InitializeItem(ITypeSerializer characterSerializer) { this.characterSerializer = characterSerializer; } public override void SerializeType(BinaryWriter writer, TransientString obj, Constraint constraint = default(Constraint)) { if (obj == null) { writer.Write7BitEncodedInt(0); return; } try { writer.Write7BitEncodedInt(obj.Characters.Length); char[] characters = obj.Characters; foreach (char obj2 in characters) { characterSerializer.SerializeType(writer, obj2, constraint); } } finally { obj.Dispose(); } } public override TransientString DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { int num = reader.Read7BitEncodedInt(); char[] array = new char[num]; for (int i = 0; i < num; i++) { array[i] = characterSerializer.DeserializeType(reader, constraint); } return TransientString.TryCreateInstance(array); } } private class Utf8StringSerializer : TypeSerializerBase, IInitializeItem> { private ITypeSerializer byteArraySerializer; public void InitializeItem(ITypeSerializer characterSerializer) { byteArraySerializer = characterSerializer; } public override void SerializeType(BinaryWriter writer, Utf8String obj, Constraint constraint = default(Constraint)) { byteArraySerializer.SerializeType(writer, obj.Buffer, constraint); } public override Utf8String DeserializeType(BinaryReader reader, Constraint constraint = default(Constraint)) { return Utf8String.FromBuffer(byteArraySerializer.DeserializeType(reader, constraint)); } } private static TypeSerializer? instance; private ReaderWriterLock typeSerializerMapLock = new ReaderWriterLock(); private Dictionary typeSerializerMap; public static TypeSerializer Instance { get { if (instance == null) { lock (typeof(TypeSerializer)) { if (instance == null) { instance = new TypeSerializer(); } } } return instance; } } public TypeSerializer() { List<(Type Type, ITypeSerializer Serializer, List InitializeItemInterfaces)> list = (from it in (from it in GetType().GetNestedTypes(BindingFlags.NonPublic) where !it.IsAbstractX() where !it.IsGenericTypeX() select (SerializerType: it, Interfaces: it.GetInterfacesX())).Select(delegate((Type SerializerType, IEnumerable Interfaces) it) { Type item = it.SerializerType; IEnumerable item2 = it.Interfaces; Type? type = it.Interfaces.FirstOrDefault((Type interfaceType) => interfaceType.IsGenericTypeX() && (object)interfaceType.GetGenericTypeDefinition() == typeof(ITypeSerializer<>)); return (SerializerType: item, Interfaces: item2, Type: ((object)type != null) ? type.GetGenericArgumentsX()[0] : null); }) where (object)it.Type != null select (Type: it.Type, Serializer: (ITypeSerializer)Activator.CreateInstance(it.SerializerType), InitializeItemInterfaces: it.Interfaces.Where((Type interfaceType) => interfaceType.IsGenericTypeX() && (object)interfaceType.GetGenericTypeDefinition() == typeof(IInitializeItem<>)).ToList())).ToList(); Dictionary dictionary = list.ToDictionary<(Type, ITypeSerializer, List), Type, ITypeSerializer>(((Type Type, ITypeSerializer Serializer, List InitializeItemInterfaces) it) => it.Type, ((Type Type, ITypeSerializer Serializer, List InitializeItemInterfaces) it) => it.Serializer); foreach (var item3 in list) { foreach (Type item4 in item3.InitializeItemInterfaces) { item3.Serializer.GetType().GetMethod("InitializeItem", item4.GetGenericArgumentsX()).Invoke(item3.Serializer, new object[1] { dictionary[item4.GetGenericArgumentsX()[0].GetGenericArgumentsX()[0]] }); } } typeSerializerMap = dictionary; } public ITypeSerializer GetSerializer() { return (ITypeSerializer)GetSerializer(typeof(T)); } public ITypeSerializer GetSerializer(Type type) { return typeSerializerMapLock.WithReaderLockAndIfDefaultThenWriterLock((bool isWriterLock) => GetSerializerInternal(type, isWriterLock)); } private ITypeSerializer? GetSerializerInternal(Type type, bool shouldCreateIfNotExists) { ITypeSerializer typeSerializer = typeSerializerMap.TryGetValue(type); if (typeSerializer != null) { return typeSerializer; } if (!shouldCreateIfNotExists) { return null; } if (type.IsEnumX()) { Type underlyingType = Enum.GetUnderlyingType(type); return CreateAndAdd(typeof(EnumSerializer<, >).MakeGenericType(type, underlyingType), new Type[1] { underlyingType }); } if (type.IsArray) { Type elementType = type.GetElementType(); return CreateAndAdd(typeof(ArraySerializer<>).MakeGenericType(elementType), new Type[1] { elementType }); } if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(IDictionary<, >)) { Type[] genericArguments = type.GetGenericArguments(); return CreateAndAdd(typeof(DictionarySerializer<, >).MakeGenericType(genericArguments), genericArguments); } ITypeSerializer typeSerializer2 = CreateAndAdd(typeof(ComplexSerializer<>).MakeGenericType(type), new Type[0]); ((IInitializeItem>)typeSerializer2).InitializeItem(GetPropertySerializersInternal(type, (Type it) => GetSerializerInternal(it, shouldCreateIfNotExists: true))); ((IInitializeItem)typeSerializer2).InitializeItem(GetConstraint(type.GetCustomAttribute())); return typeSerializer2; ITypeSerializer CreateAndAdd(Type serializerType, Type[] initializeItemTypes) { ITypeSerializer typeSerializer3 = (ITypeSerializer)Activator.CreateInstance(serializerType); typeSerializerMap[type] = typeSerializer3; foreach (Type type2 in initializeItemTypes) { typeSerializer3.To>().InitializeItem(GetSerializerInternal(type2, shouldCreateIfNotExists: true)); } return typeSerializer3; } } public static IList GetPropertySerializers(Type type) { return GetPropertySerializersInternal(type, (Type it) => Instance.GetSerializer(it)); } private static IList GetPropertySerializersInternal(Type type, Func getSerializerFunc) { return (from propertyInfo in type.GetPropertiesX() where propertyInfo.GetCustomAttribute() == null select new PropertySerializer((object obj) => propertyInfo.GetGetMethodX().Invoke(obj, null), delegate(object obj, object value) { propertyInfo.GetSetMethodX().Invoke(obj, new object[1] { value }); }, propertyInfo.PropertyType, GetConstraint(propertyInfo.GetCustomAttribute()), getSerializerFunc(propertyInfo.PropertyType))).ToList(); } public static Constraint GetConstraint(PropertyConstraintAttribute? propertyConstraintAttribute) { return propertyConstraintAttribute?.CreateConstraint() ?? default(Constraint); } public static int? GetFixedSize(IEnumerable propertySerializers) { int num = 0; foreach (PropertySerializer propertySerializer in propertySerializers) { int? fixedSize = propertySerializer.TypeSerializer.GetFixedSize(); if (!fixedSize.HasValue) { return null; } num += fixedSize.Value; } return num; } public static object GetPropertyValue(PropertySerializer propertySerializer, object obj) { if (obj != null) { return propertySerializer.GetFunc(obj); } return propertySerializer.PropertyType.GetDefaultValue(); } public static void SetPropertyValue(PropertySerializer propertySerializer, object obj, object value) { propertySerializer.SetProc(obj, value); } public static void SerializeProperties(BinaryWriter writer, IEnumerable propertySerializers, object obj, Constraint constraint) { foreach (PropertySerializer propertySerializer in propertySerializers) { propertySerializer.TypeSerializer.Serialize(writer, GetPropertyValue(propertySerializer, obj), Constraint.Combine(constraint, propertySerializer.Constraint)); } } public static void DeserializeProperties(BinaryReader reader, IEnumerable propertySerializers, object obj, Constraint constraint) { foreach (PropertySerializer propertySerializer in propertySerializers) { SetPropertyValue(propertySerializer, obj, propertySerializer.TypeSerializer.Deserialize(reader, Constraint.Combine(constraint, propertySerializer.Constraint))); } } }