public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var x = new ObjectSerializer(type); typeMapping.TryAdd(type, x); var elementType = GetEnumerableType(type); var arrType = elementType.MakeArrayType(); var listModule = type.Assembly.GetType("Microsoft.FSharp.Collections.ListModule"); var ofArray = listModule.GetMethod("OfArray"); var ofArrayConcrete = ofArray.MakeGenericMethod(elementType); var ofArrayCompiled = CodeGenerator.CompileToDelegate(ofArrayConcrete, arrType); var toArray = listModule.GetMethod("ToArray"); var toArrayConcrete = toArray.MakeGenericMethod(elementType); var toArrayCompiled = CodeGenerator.CompileToDelegate(toArrayConcrete, type); ValueWriter writer = (stream, o, session) => { var arr = toArrayCompiled(o); var arrSerializer = serializer.GetSerializerByType(arrType); arrSerializer.WriteValue(stream,arr,session); }; ValueReader reader = (stream, session) => { var arrSerializer = serializer.GetSerializerByType(arrType); var items = (Array)arrSerializer.ReadValue(stream, session); var res = ofArrayCompiled(items); return res; }; x.Initialize(reader, writer); return x; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var os = new ObjectSerializer(type); typeMapping.TryAdd(type, os); var methodInfoSerializer = serializer.GetSerializerByType(typeof(MethodInfo)); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; ObjectReader reader = (stream, session) => { var target = stream.ReadObject(session); var method = (MethodInfo) stream.ReadObject(session); var del = method.CreateDelegate(type, target); return del; }; ObjectWriter writer = (stream, value, session) => { var d = (Delegate) value; var method = d.GetMethodInfo(); stream.WriteObjectWithManifest(d.Target, session); //less lookups, slightly faster stream.WriteObject(method, type, methodInfoSerializer, preserveObjectReferences, session); }; os.Initialize(reader, writer); return os; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var ser = new ObjectSerializer(type); typeMapping.TryAdd(type, ser); var elementSerializer = serializer.GetSerializerByType(typeof (DictionaryEntry)); ValueReader reader = (stream, session) => { var count = stream.ReadInt32(session); var entries = new DictionaryEntry[count]; for (var i = 0; i < count; i++) { var entry = (DictionaryEntry) stream.ReadObject(session); entries[i] = entry; } return null; }; ValueWriter writer = (stream, obj, session) => { var dict = obj as IDictionary; // ReSharper disable once PossibleNullReferenceException stream.WriteInt32(dict.Count); foreach (var item in dict) { stream.WriteObject(item, typeof (DictionaryEntry), elementSerializer, serializer.Options.PreserveObjectReferences, session); // elementSerializer.WriteValue(stream,item,session); } }; ser.Initialize(reader, writer); return ser; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var os = new ObjectSerializer(type); typeMapping.TryAdd(type, os); ObjectReader reader = (stream, session) => { var owner = stream.ReadObject(session) as Type; var arguments = stream.ReadObject(session) as Type[]; #if NET45 var ctor = owner.GetTypeInfo().GetConstructor(arguments); return ctor; #else return null; #endif }; ObjectWriter writer = (stream, obj, session) => { var ctor = (ConstructorInfo)obj; var owner = ctor.DeclaringType; var arguments = ctor.GetParameters().Select(p => p.ParameterType).ToArray(); stream.WriteObjectWithManifest(owner, session); stream.WriteObjectWithManifest(arguments, session); }; os.Initialize(reader, writer); return os; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var os = new ObjectSerializer(type); typeMapping.TryAdd(type, os); ObjectReader reader = (stream, session) => { var name = stream.ReadString(session); var owner = stream.ReadObject(session) as Type; #if NET45 var field = owner.GetTypeInfo().GetField(name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return field; #else return null; #endif }; ObjectWriter writer = (stream, obj, session) => { var field = (FieldInfo)obj; var name = field.Name; var owner = field.DeclaringType; StringSerializer.WriteValueImpl(stream, name, session); stream.WriteObjectWithManifest(owner, session); }; os.Initialize(reader, writer); return os; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var surrogate = serializer.Options.Surrogates.FirstOrDefault(s => s.From.IsAssignableFrom(type)); ValueSerializer objectSerializer = new ObjectSerializer(surrogate.To); var toSurrogateSerializer = new ToSurrogateSerializer(surrogate.ToSurrogate, surrogate.To, objectSerializer); typeMapping.TryAdd(type, toSurrogateSerializer); CodeGenerator.BuildSerializer(serializer, surrogate.To, (ObjectSerializer) objectSerializer); return toSurrogateSerializer; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var x = new ObjectSerializer(type); typeMapping.TryAdd(type, x); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var elementType = GetEnumerableType(type) ?? typeof (object); var elementSerializer = serializer.GetSerializerByType(elementType); ValueWriter writer = (stream, o, session) => { var enumerable = o as ICollection; // ReSharper disable once PossibleNullReferenceException stream.WriteInt32(enumerable.Count); foreach (var value in enumerable) { stream.WriteObject(value, elementType, elementSerializer, preserveObjectReferences, session); } }; ValueReader reader = (stream, session) => { var count = stream.ReadInt32(session); var items = Array.CreateInstance(elementType, count); for (var i = 0; i < count; i++) { var value = stream.ReadObject(session); items.SetValue(value, i); } //HACK: this needs to be fixed, codegenerated or whatever var instance = Activator.CreateInstance(type); var addRange = type.GetMethod("AddRange"); if (addRange != null) { addRange.Invoke(instance, new object[] {items}); return instance; } var add = type.GetMethod("Add"); if (add != null) { for (var i = 0; i < items.Length; i++) { add.Invoke(instance, new[] {items.GetValue(i)}); } } return instance; }; x.Initialize(reader, writer); return x; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var surrogate = serializer.Options.Surrogates.FirstOrDefault(s => s.To.IsAssignableFrom(type)); var objectSerializer = new ObjectSerializer(type); // ReSharper disable once PossibleNullReferenceException var fromSurrogateSerializer = new FromSurrogateSerializer(surrogate.FromSurrogate, objectSerializer); typeMapping.TryAdd(type, fromSurrogateSerializer); CodeGenerator.BuildSerializer(serializer, type, objectSerializer); return fromSurrogateSerializer; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var ser = new ObjectSerializer(type); typeMapping.TryAdd(type, ser); var elementSerializer = serializer.GetSerializerByType(typeof (DictionaryEntry)); ObjectReader reader = (stream, session) => { throw new NotSupportedException("Generic IDictionary<TKey,TValue> are not yet supported"); #pragma warning disable CS0162 // Unreachable code detected var instance = Activator.CreateInstance(type); #pragma warning restore CS0162 // Unreachable code detected if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } var count = stream.ReadInt32(session); var entries = new DictionaryEntry[count]; for (var i = 0; i < count; i++) { var entry = (DictionaryEntry) stream.ReadObject(session); entries[i] = entry; } //TODO: populate dictionary return instance; }; ObjectWriter writer = (stream, obj, session) => { if (preserveObjectReferences) { session.TrackSerializedObject(obj); } var dict = obj as IDictionary; // ReSharper disable once PossibleNullReferenceException Int32Serializer.WriteValueImpl(stream,dict.Count,session); foreach (var item in dict) { stream.WriteObject(item, typeof (DictionaryEntry), elementSerializer, serializer.Options.PreserveObjectReferences, session); // elementSerializer.WriteValue(stream,item,session); } }; ser.Initialize(reader, writer); return ser; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var surrogate = serializer .Options .Surrogates .FirstOrDefault(s => s.IsSurrogateFor(type)); // ReSharper disable once PossibleNullReferenceException var objectSerializer = new ObjectSerializer(surrogate.To); var toSurrogateSerializer = new ToSurrogateSerializer(surrogate.ToSurrogate); typeMapping.TryAdd(type, toSurrogateSerializer); serializer.CodeGenerator.BuildSerializer(serializer, objectSerializer); return toSurrogateSerializer; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var serializableSerializer = new ObjectSerializer(type); typeMapping.TryAdd(type, serializableSerializer); ValueReader reader = (stream, session) => { var dict = stream.ReadObject(session) as Dictionary<string, object>; var info = new SerializationInfo(type, new FormatterConverter()); // ReSharper disable once PossibleNullReferenceException foreach (var item in dict) { info.AddValue(item.Key, item.Value); } // protected Dictionary(SerializationInfo info, StreamingContext context); var flags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Default; var ctor = type.GetConstructor(flags, null, new[] {typeof (SerializationInfo), typeof (StreamingContext)}, null); var instance = ctor.Invoke(new object[] {info, new StreamingContext()}); var deserializationCallback = instance as IDeserializationCallback; deserializationCallback?.OnDeserialization(this); return instance; }; ValueWriter writer = (stream, o, session) => { var info = new SerializationInfo(type, new FormatterConverter()); var serializable = o as ISerializable; // ReSharper disable once PossibleNullReferenceException serializable.GetObjectData(info, new StreamingContext()); var dict = new Dictionary<string, object>(); foreach (var item in info) { dict.Add(item.Name, item.Value); } var dictSerializer = serializer.GetSerializerByType(typeof (Dictionary<string, object>)); stream.WriteObject(dict, typeof (Dictionary<string, object>), dictSerializer, serializer.Options.PreserveObjectReferences, session); }; serializableSerializer.Initialize(reader, writer); return serializableSerializer; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var ser = new ObjectSerializer(type); typeMapping.TryAdd(type, ser); var elementSerializer = serializer.GetSerializerByType(typeof (DictionaryEntry)); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; ObjectReader reader = (stream, session) => { var count = stream.ReadInt32(session); var instance = (IDictionary) Activator.CreateInstance(type, count); if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } for (var i = 0; i < count; i++) { var entry = (DictionaryEntry) stream.ReadObject(session); instance.Add(entry.Key, entry.Value); } return instance; }; ObjectWriter writer = (stream, obj, session) => { if (preserveObjectReferences) { session.TrackSerializedObject(obj); } var dict = obj as IDictionary; // ReSharper disable once PossibleNullReferenceException Int32Serializer.WriteValueImpl(stream,dict.Count,session); foreach (DictionaryEntry item in dict) { stream.WriteObject(item, typeof (DictionaryEntry), elementSerializer, serializer.Options.PreserveObjectReferences, session); // elementSerializer.WriteValue(stream,item,session); } }; ser.Initialize(reader, writer); return ser; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var x = new ObjectSerializer(type); typeMapping.TryAdd(type, x); var keyType = GetKeyType(type); var valueType = GetValyeType(type); var tupleType = typeof(Tuple<,>).MakeGenericType(keyType, valueType); var arrType = tupleType.MakeArrayType(); var mapModule = type.GetTypeInfo().Assembly.GetType("Microsoft.FSharp.Collections.MapModule"); var ofArray = mapModule.GetTypeInfo().GetMethod("OfArray"); var ofArrayConcrete = ofArray.MakeGenericMethod(keyType,valueType); var ofArrayCompiled = CompileToDelegate(ofArrayConcrete, arrType); var toArray = mapModule.GetTypeInfo().GetMethod("ToArray"); var toArrayConcrete = toArray.MakeGenericMethod(keyType,valueType); var toArrayCompiled = CompileToDelegate(toArrayConcrete, type); var arrSerializer = serializer.GetSerializerByType(arrType); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; ObjectWriter writer = (stream, o, session) => { var arr = toArrayCompiled(o); arrSerializer.WriteValue(stream, arr, session); if (preserveObjectReferences) { session.TrackSerializedObject(o); } }; ObjectReader reader = (stream, session) => { var arr = arrSerializer.ReadValue(stream, session); var res = ofArrayCompiled(arr); return res; }; x.Initialize(reader, writer); return x; }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var os = new ObjectSerializer(type); typeMapping.TryAdd(type, os); ObjectReader reader = (stream, session) => { var name = stream.ReadString(session); var owner = stream.ReadObject(session) as Type; var arguments = stream.ReadObject(session) as Type[]; #if NET45 var method = owner.GetTypeInfo().GetMethod( name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, arguments, null); return method; #else return null; #endif }; ObjectWriter writer = (stream, obj, session) => { var method = (MethodInfo) obj; var name = method.Name; var owner = method.DeclaringType; var arguments = method.GetParameters().Select(p => p.ParameterType).ToArray(); StringSerializer.WriteValueImpl(stream,name,session); stream.WriteObjectWithManifest(owner, session); stream.WriteObjectWithManifest(arguments, session); }; os.Initialize(reader, writer); return os; }
public static void BuildSerializer(Serializer serializer, Type type, ObjectSerializer generatedSerializer) { if (serializer == null) throw new ArgumentNullException(nameof(serializer)); if (type == null) throw new ArgumentNullException(nameof(type)); if (generatedSerializer == null) throw new ArgumentNullException(nameof(generatedSerializer)); var fields = GetFieldInfosForType(type); var fieldWriters = new List<Action<Stream, object, SerializerSession>>(); var fieldReaders = new List<Action<Stream, object, SerializerSession>>(); var fieldNames = new List<byte[]>(); foreach (var field in fields) { var fieldName = Encoding.UTF8.GetBytes(field.Name); fieldNames.Add(fieldName); fieldWriters.Add(GenerateFieldInfoSerializer(serializer, field)); fieldReaders.Add(GenerateFieldInfoDeserializer(serializer, type, field)); } //concat all fieldNames including their length encoding and field count as header var versionTolerantHeader = fieldNames.Aggregate(Enumerable.Repeat((byte) fieldNames.Count, 1), (current, fieldName) => current.Concat(BitConverter.GetBytes(fieldName.Length)).Concat(fieldName)) .ToArray(); Action<Stream, object, SerializerSession> writeallFields = null; if (fieldWriters.Any()) { writeallFields = GenerateWriteAllFieldsDelegate(fieldWriters); } else { writeallFields = (_1, _2, _3) => { }; } if (Debugger.IsAttached) { var tmp = writeallFields; writeallFields = (stream, o, session) => { try { tmp(stream, o, session); } catch (Exception x) { throw new Exception($"Unable to write all fields of {type.Name}", x); } }; } var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var versiontolerance = serializer.Options.VersionTolerance; Action<Stream, object, SerializerSession> writer = (stream, o, session) => { if (versiontolerance) { //write field count - cached stream.Write(versionTolerantHeader); } if (preserveObjectReferences) { session.TrackSerializedObject(o); } writeallFields(stream, o, session); }; var reader = MakeReader(serializer, type, preserveObjectReferences, fields, fieldNames, fieldReaders); generatedSerializer.Initialize(reader, writer); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var x = new ObjectSerializer(type); typeMapping.TryAdd(type, x); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var elementType = GetEnumerableType(type) ?? typeof (object); var elementSerializer = serializer.GetSerializerByType(elementType); var typeName = type.Name; var genericSufixIdx = typeName.IndexOf('`'); typeName = genericSufixIdx != -1 ? typeName.Substring(0, genericSufixIdx) : typeName; var creatorType = Type.GetType( ImmutableCollectionsNamespace + "." + typeName + ", " + ImmutableCollectionsAssembly, true); var genericTypes = elementType.GetTypeInfo().IsGenericType ? elementType.GetTypeInfo().GetGenericArguments() : new[] { elementType }; var createRange = creatorType.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Static) .First(methodInfo => methodInfo.Name == "CreateRange" && methodInfo.GetParameters().Length == 1) .MakeGenericMethod(genericTypes); ObjectWriter writer = (stream, o, session) => { var enumerable = o as ICollection; if (enumerable == null) { // object can be IEnumerable but not ICollection i.e. ImmutableQueue var e = (IEnumerable) o; var list = e.Cast<object>().ToList();// enumerable = list; } Int32Serializer.WriteValueImpl(stream,enumerable.Count,session); foreach (var value in enumerable) { stream.WriteObject(value, elementType, elementSerializer, preserveObjectReferences, session); } if (preserveObjectReferences) { session.TrackSerializedObject(o); } }; ObjectReader reader = (stream, session) => { var count = stream.ReadInt32(session); var items = Array.CreateInstance(elementType, count); for (var i = 0; i < count; i++) { var value = stream.ReadObject(session); items.SetValue(value, i); } var instance = createRange.Invoke(null, new object[] {items}); if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } return instance; }; x.Initialize(reader, writer); return x; }
public static void BuildSerializer(Serializer serializer, Type type, ObjectSerializer result) { var fields = GetFieldsForType(type); var fieldWriters = new List<Action<Stream, object, SerializerSession>>(); var fieldReaders = new List<Action<Stream, object, SerializerSession>>(); var fieldNames = new List<byte[]>(); foreach (var field in fields) { var fieldName = Encoding.UTF8.GetBytes(field.Name); fieldNames.Add(fieldName); fieldWriters.Add(GenerateFieldSerializer(serializer, type, field)); fieldReaders.Add(GenerateFieldDeserializer(serializer,type, field)); } //concat all fieldNames including their length encoding and field count as header var versionTolerantHeader = fieldNames.Aggregate(Enumerable.Repeat((byte) fieldNames.Count, 1), (current, fieldName) => current.Concat(BitConverter.GetBytes(fieldName.Length)).Concat(fieldName)) .ToArray(); Action<Stream, object, SerializerSession> writeallFields = null; if (fieldWriters.Any()) { writeallFields = GenerateWriteAllFieldsDelegate(fieldWriters); } else { writeallFields = (_1, _2, _3) => { }; } Action<Stream, object, SerializerSession> writer = (stream, o, session) => { if (serializer.Options.VersionTolerance) { //write field count - cached stream.Write(versionTolerantHeader); } writeallFields(stream, o, session); }; //avoid one level of invocation if (serializer.Options.VersionTolerance == false) { writer = writeallFields; } // var readAllFieldsVersionIntolerant = GenerateReadAllFieldsVersionIntolerant(fieldReaders); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; Func<Stream, SerializerSession, object> reader = (stream, session) => { //create instance without calling constructor var instance = FormatterServices.GetUninitializedObject(type); if (preserveObjectReferences) { session.ObjectById.Add(session.NextObjectId, instance); session.NextObjectId++; } var fieldsToRead = fields.Length; if (serializer.Options.VersionTolerance) { var storedFieldCount = stream.ReadByte(); if (storedFieldCount != fieldsToRead) { //TODO: } for (var i = 0; i < storedFieldCount; i++) { var fieldName = stream.ReadLengthEncodedByteArray(session); if (!UnsafeCompare(fieldName, fieldNames[i])) { //TODO } } // writeallFields(stream, instance, session); for (var i = 0; i < storedFieldCount; i++) { var fieldReader = fieldReaders[i]; fieldReader(stream, instance, session); } } else { // writeallFields(stream, instance, session); for (var i = 0; i < fieldsToRead; i++) { var fieldReader = fieldReaders[i]; fieldReader(stream, instance, session); } } return instance; }; result._writer = writer; result._reader = reader; }
public KnownTypeObjectSerializer(ObjectSerializer serializer, ushort typeIdentifier) { _serializer = serializer; _typeIdentifier = typeIdentifier; _typeIdentifierBytes = BitConverter.GetBytes(typeIdentifier); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, ConcurrentDictionary<Type, ValueSerializer> typeMapping) { var x = new ObjectSerializer(type); typeMapping.TryAdd(type, x); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var elementType = GetEnumerableType(type) ?? typeof (object); var elementSerializer = serializer.GetSerializerByType(elementType); ValueWriter writer = (stream, o, session) => { var enumerable = o as ICollection; if (enumerable == null) { // object can be IEnumerable but not ICollection i.e. ImmutableQueue var e = (IEnumerable) o; var list = new ArrayList(); foreach (var element in e) list.Add(element); enumerable = list; } stream.WriteInt32(enumerable.Count); foreach (var value in enumerable) { stream.WriteObject(value, elementType, elementSerializer, preserveObjectReferences, session); } }; ValueReader reader = (stream, session) => { var count = stream.ReadInt32(session); var items = Array.CreateInstance(elementType, count); for (var i = 0; i < count; i++) { var value = stream.ReadObject(session); items.SetValue(value, i); } //HACK: this needs to be fixed, codegenerated or whatever if (type.Namespace != null && type.Namespace.Equals(ImmutableCollectionsNamespace)) { var typeName = type.Name; var genericSufixIdx = typeName.IndexOf('`'); typeName = genericSufixIdx != -1 ? typeName.Substring(0, genericSufixIdx) : typeName; var creatorType = Type.GetType( ImmutableCollectionsNamespace + "." + typeName + ", " + ImmutableCollectionsAssembly, true); var genericTypes = elementType.IsGenericType ? elementType.GetGenericArguments() : new[] {elementType}; var createRange = creatorType.GetMethods(BindingFlags.Public | BindingFlags.Static) .First(methodInfo => methodInfo.Name == "CreateRange" && methodInfo.GetParameters().Length == 1) .MakeGenericMethod(genericTypes); var instance = createRange.Invoke(null, new object[] {items}); return instance; } else { var instance = Activator.CreateInstance(type); var addRange = type.GetMethod("AddRange"); if (addRange != null) { addRange.Invoke(instance, new object[] {items}); return instance; } var add = type.GetMethod("Add"); if (add != null) { for (var i = 0; i < items.Length; i++) { add.Invoke(instance, new[] {items.GetValue(i)}); } } return instance; } }; x.Initialize(reader, writer); return x; }