public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var arraySerializer = new ObjectSerializer(type); var elementType = type/*.GetTypeInfo()*/ .GetMethods() .Where(methodInfo => methodInfo.Name == "Get") .Select(methodInfo => methodInfo.ReturnType) .FirstOrDefault(); var elementSerializer = serializer.GetSerializerByType(elementType); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var arrayRank = type.GetArrayRank(); //TODO: code gen this part ObjectReader reader = CreateReader(preserveObjectReferences, arrayRank, elementType); ObjectWriter writer = (stream, arr, session) => { if (preserveObjectReferences) { session.TrackSerializedObject(arr); } WriteValues((Array)arr, stream, elementType, elementSerializer, session); }; arraySerializer.Initialize(reader, writer); typeMapping.TryAdd(type, arraySerializer); return(arraySerializer); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <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[]; var ctor = owner.GetConstructor(arguments); return(ctor); }; 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); }
private ValueSerializer GetCustomDeserializer([NotNull] Type type) { //do we already have a deserializer for this type? if (_deserializers.TryGetValue(type, out ValueSerializer serializer)) { return(serializer); } //is there a deserializer factory that can handle this type? foreach (var valueSerializerFactory in Options.ValueSerializerFactories) { if (valueSerializerFactory.CanDeserialize(this, type)) { return(valueSerializerFactory.BuildSerializer(this, type, _deserializers)); } } //none of the above, lets create a POCO object deserializer serializer = new ObjectSerializer(type); //add it to the serializer lookup in case of recursive serialization if (!_deserializers.TryAdd(type, serializer)) { return(_deserializers[type]); } //build the serializer IL code CodeGenerator.BuildSerializer(this, (ObjectSerializer)serializer); return(serializer); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <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, CachedReadConcurrentDictionary <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 field = owner.GetField(name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return(field); }; 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, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var res = ConsistentArraySerializer.Instance; typeMapping.TryAdd(type, res); return(res); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <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); serializer.CodeGenerator.BuildSerializer(serializer, objectSerializer); return(fromSurrogateSerializer); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <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) => { var instance = ActivatorUtils.FastCreateInstance(type) as IDictionary <string, object>; if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } var count = stream.ReadInt32(session); for (var i = 0; i < count; i++) { var entry = (KeyValuePair <string, object>)stream.ReadObject(session); instance.Add(entry); } return(instance); }; ObjectWriter writer = (stream, obj, session) => { if (preserveObjectReferences) { session.TrackSerializedObject(obj); } var dict = obj as IDictionary <string, object>; // 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, CachedReadConcurrentDictionary <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 tupleType = typeof(Tuple <,>).GetCachedGenericType(keyType, valueType); var arrType = tupleType.MakeArrayType(); var mapModule = type.Assembly.GetType("Microsoft.FSharp.Collections.MapModule"); var ofArray = mapModule.GetMethod("OfArray"); var ofArrayConcrete = ofArray.MakeGenericMethod(keyType, valueType); var ofArrayCompiled = CompileToDelegate(ofArrayConcrete, arrType); var toArray = mapModule.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, CachedReadConcurrentDictionary <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 parameterTypes = stream.ReadObject(session) as Type[]; var method = owner.GetMethodExt(name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, parameterTypes); if (method.IsGenericMethodDefinition) { var genericTypeArguments = stream.ReadObject(session) as Type[]; method = method.MakeGenericMethod(genericTypeArguments); } return(method); }; ObjectWriter writer = (stream, obj, session) => { var method = (MethodInfo)obj; var name = method.Name; var owner = method.DeclaringType; StringSerializer.WriteValueImpl(stream, name, session); stream.WriteObjectWithManifest(owner, session); var arguments = method.GetParameters().Select(p => p.ParameterType).ToArray(); stream.WriteObjectWithManifest(arguments, session); if (method.IsGenericMethod) { // we use the parameter types to find the method above but, if generic, we need to store the generic type arguments as well // in order to MakeGenericType var genericTypeArguments = method.GetGenericArguments(); stream.WriteObjectWithManifest(genericTypeArguments, session); } }; os.Initialize(reader, writer); return(os); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var os = new ObjectSerializer(type); typeMapping.TryAdd(type, os); ObjectReader reader = (stream, session) => { var raw = stream.ReadString(session); return(new DerivedContainer()); }; ObjectWriter writer = (stream, value, session) => { StringSerializer.WriteValueImpl(stream, "test", session); }; os.Initialize(reader, writer); return(os); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <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 = CompileToDelegate(ofArrayConcrete, arrType); var toArray = listModule.GetMethod("ToArray"); var toArrayConcrete = toArray.MakeGenericMethod(elementType); var toArrayCompiled = CompileToDelegate(toArrayConcrete, type); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; ObjectWriter writer = (stream, o, session) => { var arr = toArrayCompiled(o); var arrSerializer = serializer.GetSerializerByType(arrType); arrSerializer.WriteValue(stream, arr, session); if (preserveObjectReferences) { session.TrackSerializedObject(o); } }; ObjectReader reader = (stream, session) => { var arrSerializer = serializer.GetSerializerByType(arrType); var items = (Array)arrSerializer.ReadValue(stream, session); var res = ofArrayCompiled(items); if (preserveObjectReferences) { session.TrackDeserializedObject(res); } return(res); }; x.Initialize(reader, writer); return(x); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var serializableSerializer = new ObjectSerializer(type); typeMapping.TryAdd(type, serializableSerializer); ObjectReader 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); } var ctor = type.GetConstructor(BindingFlagsEx.All, 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); }; ObjectWriter 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); } stream.WriteObjectWithManifest(dict, session); }; serializableSerializer.Initialize(reader, writer); return(serializableSerializer); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var arraySerializer = new ObjectSerializer(type); var elementType = type.GetElementType(); var elementSerializer = serializer.GetSerializerByType(elementType); var preserveObjectReferences = serializer.Options.PreserveObjectReferences; //TODO: code gen this part ObjectReader reader = (stream, session) => { var length = stream.ReadInt32(session); var array = Array.CreateInstance(elementType, length); //create the array if (preserveObjectReferences) { session.TrackDeserializedObject(array); } ReadValues(length, stream, session, (dynamic)array); return(array); }; ObjectWriter writer = (stream, arr, session) => { if (preserveObjectReferences) { session.TrackSerializedObject(arr); } WriteValues((dynamic)arr, stream, elementType, elementSerializer, session); }; arraySerializer.Initialize(reader, writer); typeMapping.TryAdd(type, arraySerializer); return(arraySerializer); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <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 countProperty = type.GetProperty("Count"); var addMethod = type.GetMethod("Add", BindingFlagsEx.All); var enumerableConstructor = GetEnumerableConstructor(type); Func <object, int> countGetter = o => (int)countProperty.GetValue(o); ObjectReader reader = null; if (HasParameterlessConstructor(type) && addMethod != null) { var add = CompileMethodToDelegate(addMethod, type, elementType); reader = (stream, session) => { var instance = Activator.CreateInstance(type, true); if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } var count = stream.ReadInt32(session); for (var i = 0; i < count; i++) { var value = stream.ReadObject(session); add(instance, value); } return(instance); }; } else if (enumerableConstructor != null) { var construct = CompileCtorToDelegate(enumerableConstructor, elementType.MakeArrayType()); 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 = construct(items); if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } return(instance); }; } ObjectWriter writer = (stream, o, session) => { if (preserveObjectReferences) { session.TrackSerializedObject(o); } Int32Serializer.WriteValueImpl(stream, countGetter(o), session); var enumerable = o as IEnumerable; // ReSharper disable once PossibleNullReferenceException foreach (var value in enumerable) { stream.WriteObject(value, elementType, elementSerializer, preserveObjectReferences, session); } }; x.Initialize(reader, writer); return(x); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var exceptionSerializer = new ObjectSerializer(type); exceptionSerializer.Initialize((stream, session) => { var exception = ActivatorUtils.FastCreateInstance(type); var sessionSerializer = session.Serializer; if (sessionSerializer.Options.PreserveObjectReferences) { session.TrackDeserializedObject(exception); } var fields = s_filedCache.GetOrAdd(type, s_getFieldsFunc); foreach (var(field, getter, setter) in fields) { var fieldType = field.FieldType; object fieldValue; if (!sessionSerializer.Options.VersionTolerance && fieldType.IsHyperionPrimitive()) { var valueSerializer = sessionSerializer.GetSerializerByType(fieldType); fieldValue = valueSerializer.ReadValue(stream, session); } else { var valueType = fieldType; if (fieldType.IsNullableType()) { valueType = Nullable.GetUnderlyingType(fieldType); } var valueSerializer = sessionSerializer.GetSerializerByType(valueType); fieldValue = stream.ReadObject(session); } setter(exception, fieldValue); } return(exception); }, (stream, exception, session) => { var sessionSerializer = session.Serializer; if (sessionSerializer.Options.PreserveObjectReferences) { session.TrackSerializedObject(exception); } var fields = s_filedCache.GetOrAdd(type, s_getFieldsFunc); foreach (var(field, getter, setter) in fields) { var fieldType = field.FieldType; var v = getter(exception); //if the type is one of our special primitives, ignore manifest as the content will always only be of this type if (!sessionSerializer.Options.VersionTolerance && fieldType.IsHyperionPrimitive()) { var valueSerializer = sessionSerializer.GetSerializerByType(fieldType); valueSerializer.WriteValue(stream, v, session); } else { var valueType = fieldType; if (fieldType.IsNullableType()) { valueType = Nullable.GetUnderlyingType(fieldType); } var valueSerializer = sessionSerializer.GetSerializerByType(valueType); stream.WriteObject(v, valueType, valueSerializer, true, session); } } }); typeMapping.TryAdd(type, exceptionSerializer); return(exceptionSerializer); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <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); var createRangeMethodInfo = creatorType != null ? creatorType.GetMethods(BindingFlags.Public | BindingFlags.Static) .First(methodInfo => methodInfo.Name == "CreateRange" && methodInfo.GetParameters().Length == 1) : null; // If the element type is a generic type and the method located to create the collection instance requires more than one generic type parameter // we need to obtain the generic arguments of the element type. var genericTypes = elementType.IsGenericType && createRangeMethodInfo != null && createRangeMethodInfo.GetGenericArguments().Length > 1 ? elementType.GetGenericArguments() : new[] { elementType }; // if creatorType == null it means that type is probably an interface // we propagate null to create mock serializer - it won't be used anyway var stackTypeDef = Type.GetType(ImmutableCollectionsNamespace + ".IImmutableStack`1, " + ImmutableCollectionsAssembly, true); //var stackInterface = stackTypeDef.MakeGenericType(genericTypes[0]); var stackInterface = stackTypeDef.GetCachedGenericType(genericTypes[0]); var isStack = stackInterface.IsAssignableFrom(type); var createRange = createRangeMethodInfo != null ? createRangeMethodInfo.MakeGenericMethod(genericTypes) : null; 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; if (isStack) { // if we are dealing with stack, we need to apply arguments in reverse order 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, count - i - 1); } var instance = createRange.Invoke(null, new object[] { items }); if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } return(instance); }; } else { 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); }
private void AddValueSerializer(ValueSerializer instance, Type type) { _serializers.TryAdd(type, instance); }
public override ValueSerializer BuildSerializer(Serializer serializer, Type type, CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping) { var preserveObjectReferences = serializer.Options.PreserveObjectReferences; var ser = new ObjectSerializer(type); typeMapping.TryAdd(type, ser); var dictionaryTypes = GetKeyValuePairType(type); var elementSerializer = serializer.GetSerializerByType(dictionaryTypes.KeyValuePairType); ObjectReader reader = (stream, session) => { object instance; try { instance = Activator.CreateInstance(type, true); // IDictionary<TKey, TValue> } catch (Exception) { instance = Activator.CreateInstance(type); // IDictionary<TKey, TValue> } if (preserveObjectReferences) { session.TrackDeserializedObject(instance); } var count = stream.ReadInt32(session); for (var i = 0; i < count; i++) { var entry = stream.ReadObject(session); // KeyValuePair<TKey, TValue> // Get entry.Key and entry.Value var key = dictionaryTypes.KeyValuePairType.GetProperty(nameof(KeyValuePair <object, object> .Key)).GetValue(entry, null); var value = dictionaryTypes.KeyValuePairType.GetProperty(nameof(KeyValuePair <object, object> .Value)).GetValue(entry, null); // Same as: instance.Add(key, value) dictionaryTypes.DictionaryInterfaceType .GetMethod(nameof(IDictionary <object, object> .Add), new[] { dictionaryTypes.KeyType, dictionaryTypes.ValueType }) .Invoke(instance, new[] { key, value }); } return(instance); }; void writer(System.IO.Stream stream, object obj, SerializerSession session) { if (preserveObjectReferences) { session.TrackSerializedObject(obj); } var dict = obj as IEnumerable; // IDictionary<T, V> is IEnumerable<KeyValuePair<T, V>> var count = dict.Cast <object>().Count(); // ReSharper disable once PossibleNullReferenceException Int32Serializer.WriteValueImpl(stream, count, session); foreach (var item in dict) { stream.WriteObject(item, dictionaryTypes.KeyValuePairType, elementSerializer, serializer.Options.PreserveObjectReferences, session); } } ser.Initialize(reader, writer); return(ser); }