Inheritance: ValueSerializer
        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;
        }
Example #15
0
        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;
        }
Example #17
0
        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;
        }
Example #18
0
 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;
        }
 public KnownTypeObjectSerializer(ObjectSerializer serializer, ushort typeIdentifier)
 {
     _serializer = serializer;
     _typeIdentifier = typeIdentifier;
     _typeIdentifierBytes = BitConverter.GetBytes(typeIdentifier);
 }