public object Deserialize(
            StreamReader streamReader,
            SerializationContext serializationContext,
            PropertyMetaData propertyMetaData = null)
        {
            int arrayLength;

            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                arrayLength = (int)arraySizeSerializer.Deserialize(streamReader, serializationContext, propertyMetaData);
            }
            else
            {
                arrayLength = propertyMetaData.Options.FixedSizeLength;
            }

            var array = Array.CreateInstance(this.typeSerializer.Type, arrayLength);

            for (var i = 0; i < arrayLength; i++)
            {
                var element = this.typeSerializer.Deserialize(streamReader, serializationContext, propertyMetaData);
                array.SetValue(element, i);
            }

            return(array);
        }
        public Expression SerializerExpression(
            ParameterExpression streamWriterExpression,
            ParameterExpression serializationContextExpression,
            Expression valueExpression,
            PropertyMetaData propertyMetaData)
        {
            if (valueExpression.Type.IsAssignableFrom(this.type) == false)
            {
                valueExpression = Expression.Convert(valueExpression, this.type);
            }

            var expressions = new List <Expression>();

            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var serializeSizeExp =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).SerializerExpression(
                        streamWriterExpression, serializationContextExpression, valueExpression, propertyMetaData);
                expressions.Add(serializeSizeExp);
            }

            var @break      = Expression.Label();
            var arrayLength = Expression.ArrayLength(valueExpression);
            var counter     = Expression.Variable(typeof(int), "i");

            expressions.Add(Expression.Assign(counter, Expression.Constant(0)));
            var element = Expression.Variable(this.typeSerializer.Type, "element");
            var assign  = Expression.Assign(element, Expression.ArrayIndex(valueExpression, counter));
            var ifElse  = Expression.IfThenElse(
                Expression.LessThan(counter, arrayLength),
                Expression.Block(
                    new[] { element },
                    new[]
            {
                assign,
                this.typeSerializer.SerializerExpression(
                    streamWriterExpression, serializationContextExpression, element, propertyMetaData),
                Expression.Assign(counter, Expression.Increment(counter))
            }),
                Expression.Break(@break));

            var forExp = Expression.Loop(ifElse, @break);

            expressions.Add(forExp);

            var block = Expression.Block(new[] { counter }, expressions);

            return(block);
        }
        public object Deserialize(
            StreamReader streamReader,
            SerializationContext serializationContext,
            PropertyMetaData propertyMetaData = null)
        {
            int arrayLength;
            var array = Array.CreateInstance(this.typeSerializer.Type, 0);

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NullTerminated)
            {
                List <object> temp  = new List <object>();
                int           check = 0;
                do
                {
                    check = streamReader.ReadInt32();
                    if (check != 0)
                    {
                        streamReader.Position -= 4;
                        var element = this.typeSerializer.Deserialize(
                            streamReader,
                            serializationContext,
                            propertyMetaData);
                        temp.Add(element);
                    }
                }while (check != 0);
            }
            else
            {
                if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
                {
                    var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                    arrayLength = (int)arraySizeSerializer.Deserialize(streamReader, serializationContext, propertyMetaData);
                }
                else
                {
                    arrayLength = propertyMetaData.Options.FixedSizeLength;
                }

                array = Array.CreateInstance(this.typeSerializer.Type, arrayLength);
                for (var i = 0; i < arrayLength; i++)
                {
                    var element = this.typeSerializer.Deserialize(streamReader, serializationContext, propertyMetaData);
                    array.SetValue(element, i);
                }
            }

            return(array);
        }
Esempio n. 4
0
        public void Serialize(
            StreamWriter streamWriter,
            SerializationContext serializationContext,
            object value,
            PropertyMetaData propertyMetaData = null)
        {
            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                arraySizeSerializer.Serialize(streamWriter, serializationContext, value, propertyMetaData);
            }

            var writeStringParam = propertyMetaData.Options.IsFixedSize
                                       ? (int?)propertyMetaData.Options.FixedSizeLength
                                       : null;

            streamWriter.WriteString((string)value, writeStringParam);
        }
Esempio n. 5
0
        public Expression DeserializerExpression(
            ParameterExpression streamReaderExpression,
            ParameterExpression serializationContextExpression,
            Expression assignmentTargetExpression,
            PropertyMetaData propertyMetaData)
        {
            var expressions = new List <Expression>();

            var lengthExpression = Expression.Variable(typeof(int), "length");

            Expression assignLengthExpression;

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NoSerialization)
            {
                assignLengthExpression = Expression.Assign(
                    lengthExpression, Expression.Constant(propertyMetaData.Options.FixedSizeLength, typeof(int)));
            }
            else
            {
                assignLengthExpression =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).DeserializerExpression(
                        streamReaderExpression, serializationContextExpression, lengthExpression, propertyMetaData);
            }

            expressions.Add(assignLengthExpression);

            var readMethodInfo = ReflectionHelper.GetMethodInfo <StreamReader, Func <int, string> >(o => o.ReadString);
            var callReadExp    = Expression.Call(
                streamReaderExpression, readMethodInfo, new Expression[] { lengthExpression });

            Expression setString = assignmentTargetExpression.Type.IsAssignableFrom(this.type)
                                       ? Expression.Assign(assignmentTargetExpression, callReadExp)
                                       : Expression.Assign(
                assignmentTargetExpression,
                Expression.Convert(callReadExp, assignmentTargetExpression.Type));

            expressions.Add(setString);

            var block = Expression.Block(new[] { lengthExpression }, expressions);

            return(block);
        }
        public object Deserialize(
            StreamReader streamReader, 
            SerializationContext serializationContext, 
            PropertyMetaData propertyMetaData = null)
        {
            int length;
            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NoSerialization)
            {
                length = propertyMetaData.Options.FixedSizeLength;
            }
            else
            {
                var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                length =
                    (int)
                    arraySizeSerializer.Deserialize(
                        streamReader, serializationContext, propertyMetaData: propertyMetaData);
            }

            return streamReader.ReadString(length);
        }
        public void Serialize(
            StreamWriter streamWriter,
            SerializationContext serializationContext,
            object value,
            PropertyMetaData propertyMetaData = null)
        {
            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                arraySizeSerializer.Serialize(
                    streamWriter, serializationContext, value, propertyMetaData: propertyMetaData);
            }

            var array = (Array)value;

            for (var i = 0; i < array.Length; i++)
            {
                this.typeSerializer.Serialize(
                    streamWriter, serializationContext, array.GetValue(i), propertyMetaData: propertyMetaData);
            }
        }
Esempio n. 8
0
        public object Deserialize(
            StreamReader streamReader,
            SerializationContext serializationContext,
            PropertyMetaData propertyMetaData = null)
        {
            int length;

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NoSerialization)
            {
                length = propertyMetaData.Options.FixedSizeLength;
            }
            else
            {
                var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                length =
                    (int)
                    arraySizeSerializer.Deserialize(
                        streamReader, serializationContext, propertyMetaData: propertyMetaData);
            }

            return(streamReader.ReadString(length));
        }
Esempio n. 9
0
        public Expression SerializerExpression(
            ParameterExpression streamWriterExpression,
            ParameterExpression serializationContextExpression,
            Expression valueExpression,
            PropertyMetaData propertyMetaData)
        {
            if (valueExpression.Type.IsAssignableFrom(this.type) == false)
            {
                valueExpression = Expression.Convert(valueExpression, this.type);
            }

            var expressions = new List <Expression>();

            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var serializeSizeExp =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).SerializerExpression(
                        streamWriterExpression, serializationContextExpression, valueExpression, propertyMetaData);
                expressions.Add(serializeSizeExp);
            }

            var writeMethodInfo = ReflectionHelper.GetMethodInfo <StreamWriter, Action <string, int?> >(o => o.WriteString);

            Expression writeStringParam = propertyMetaData.Options.IsFixedSize
                                              ? Expression.Constant(
                propertyMetaData.Options.FixedSizeLength, typeof(int?))
                                              : Expression.Constant(null, typeof(int?));

            var callWriteExp = Expression.Call(
                streamWriterExpression,
                writeMethodInfo,
                new[] { Expression.Convert(valueExpression, this.type), writeStringParam });

            expressions.Add(callWriteExp);
            var block = Expression.Block(expressions);

            return(block);
        }
        public void Serialize(
            StreamWriter streamWriter,
            SerializationContext serializationContext,
            object value,
            PropertyMetaData propertyMetaData = null)
        {
            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                arraySizeSerializer.Serialize(
                    streamWriter, serializationContext, value, propertyMetaData: propertyMetaData);
            }

            var array = (Array)value;
            for (var i = 0; i < array.Length; i++)
            {
                this.typeSerializer.Serialize(
                    streamWriter, serializationContext, array.GetValue(i), propertyMetaData: propertyMetaData);
            }
        }
        public Expression DeserializerExpression(
            ParameterExpression streamReaderExpression, 
            ParameterExpression serializationContextExpression, 
            Expression assignmentTargetExpression, 
            PropertyMetaData propertyMetaData)
        {
            var expressions = new List<Expression>();

            var lengthExpression = Expression.Variable(typeof(int), "length");

            Expression assignLengthExpression;

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NoSerialization)
            {
                assignLengthExpression = Expression.Assign(
                    lengthExpression, Expression.Constant(propertyMetaData.Options.FixedSizeLength, typeof(int)));
            }
            else
            {
                assignLengthExpression =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).DeserializerExpression(
                        streamReaderExpression, serializationContextExpression, lengthExpression, propertyMetaData);
            }

            expressions.Add(assignLengthExpression);

            var readMethodInfo = ReflectionHelper.GetMethodInfo<StreamReader, Func<int, string>>(o => o.ReadString);
            var callReadExp = Expression.Call(
                streamReaderExpression, readMethodInfo, new Expression[] { lengthExpression });

            Expression setString = assignmentTargetExpression.Type.IsAssignableFrom(this.type)
                                       ? Expression.Assign(assignmentTargetExpression, callReadExp)
                                       : Expression.Assign(
                                           assignmentTargetExpression, 
                                           Expression.Convert(callReadExp, assignmentTargetExpression.Type));

            expressions.Add(setString);

            var block = Expression.Block(new[] { lengthExpression }, expressions);
            return block;
        }
        public Expression SerializerExpression(
            ParameterExpression streamWriterExpression, 
            ParameterExpression serializationContextExpression, 
            Expression valueExpression, 
            PropertyMetaData propertyMetaData)
        {
            if (valueExpression.Type.IsAssignableFrom(this.type) == false)
            {
                valueExpression = Expression.Convert(valueExpression, this.type);
            }

            var expressions = new List<Expression>();
            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var serializeSizeExp =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).SerializerExpression(
                        streamWriterExpression, serializationContextExpression, valueExpression, propertyMetaData);
                expressions.Add(serializeSizeExp);
            }

            var writeMethodInfo = ReflectionHelper.GetMethodInfo<StreamWriter, Action<string, int?>>(o => o.WriteString);

            Expression writeStringParam = propertyMetaData.Options.IsFixedSize
                                              ? Expression.Constant(
                                                  propertyMetaData.Options.FixedSizeLength, typeof(int?))
                                              : Expression.Constant(null, typeof(int?));

            var callWriteExp = Expression.Call(
                streamWriterExpression, 
                writeMethodInfo, 
                new[] { Expression.Convert(valueExpression, this.type), writeStringParam });
            expressions.Add(callWriteExp);
            var block = Expression.Block(expressions);
            return block;
        }
        public void Serialize(
            StreamWriter streamWriter, 
            SerializationContext serializationContext, 
            object value, 
            PropertyMetaData propertyMetaData = null)
        {
            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                arraySizeSerializer.Serialize(streamWriter, serializationContext, value, propertyMetaData);
            }

            var writeStringParam = propertyMetaData.Options.IsFixedSize
                                       ? (int?)propertyMetaData.Options.FixedSizeLength
                                       : null;
            streamWriter.WriteString((string)value, writeStringParam);
        }
        public object Deserialize(
            StreamReader streamReader,
            SerializationContext serializationContext,
            PropertyMetaData propertyMetaData = null)
        {
            int arrayLength;
            var array = Array.CreateInstance(this.typeSerializer.Type, 0);
            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NullTerminated)
            {
                List<object> temp = new List<object>();
                int check = 0;
                do
                {
                    check = streamReader.ReadInt32();
                    if (check != 0)
                    {
                        streamReader.Position -= 4;
                        var element = this.typeSerializer.Deserialize(
                            streamReader,
                            serializationContext,
                            propertyMetaData);
                        temp.Add(element);
                    }
                }
                while (check != 0);
            }
            else
            {
                if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
                {
                    var arraySizeSerializer = new ArraySizeSerializer(propertyMetaData.Options.SerializeSize);
                    arrayLength = (int)arraySizeSerializer.Deserialize(streamReader, serializationContext, propertyMetaData);
                }
                else
                {
                    arrayLength = propertyMetaData.Options.FixedSizeLength;
                }

                array = Array.CreateInstance(this.typeSerializer.Type, arrayLength);
                for (var i = 0; i < arrayLength; i++)
                {
                    var element = this.typeSerializer.Deserialize(streamReader, serializationContext, propertyMetaData);
                    array.SetValue(element, i);
                }
            }

            return array;
        }
        public Expression SerializerExpression(
            ParameterExpression streamWriterExpression,
            ParameterExpression serializationContextExpression,
            Expression valueExpression,
            PropertyMetaData propertyMetaData)
        {
            if (valueExpression.Type.IsAssignableFrom(this.type) == false)
            {
                valueExpression = Expression.Convert(valueExpression, this.type);
            }

            var expressions = new List<Expression>();
            if ((propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization) && (propertyMetaData.Options.SerializeSize != ArraySizeType.NullTerminated))
            {
                var serializeSizeExp =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).SerializerExpression(
                        streamWriterExpression, serializationContextExpression, valueExpression, propertyMetaData);
                expressions.Add(serializeSizeExp);
            }

            var @break = Expression.Label();
            var arrayLength = Expression.ArrayLength(valueExpression);
            var counter = Expression.Variable(typeof(int), "i");
            expressions.Add(Expression.Assign(counter, Expression.Constant(0)));
            var element = Expression.Variable(this.typeSerializer.Type, "element");
            var assign = Expression.Assign(element, Expression.ArrayIndex(valueExpression, counter));
            var ifElse = Expression.IfThenElse(
                Expression.LessThan(counter, arrayLength),
                Expression.Block(
                    new[] { element },
                    new[]
                        {
                            assign, 
                            this.typeSerializer.SerializerExpression(
                                streamWriterExpression, serializationContextExpression, element, propertyMetaData), 
                            Expression.Assign(counter, Expression.Increment(counter))
                        }),
                Expression.Break(@break));

            var forExp = Expression.Loop(ifElse, @break);
            expressions.Add(forExp);

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NullTerminated)
            {
                MethodInfo writeCloser = null;
                if ((propertyMetaData.Type == typeof(string)) || (propertyMetaData.Type == typeof(byte)))
                {
                    writeCloser = ReflectionHelper.GetMethodInfo<StreamWriter, Action<byte>>(o => o.WriteByte);
                }
                else if (propertyMetaData.Type == typeof(short))
                {
                    writeCloser = ReflectionHelper.GetMethodInfo<StreamWriter, Action<short>>(o => o.WriteInt16);
                }
                else
                {
                    writeCloser = ReflectionHelper.GetMethodInfo<StreamWriter, Action<Int32>>(o => o.WriteInt32);
                }

                Expression sernull = Expression.Call(
                    streamWriterExpression,
                    writeCloser,
                    new[] { Expression.Constant(0) });
                expressions.Add(sernull);
            }

            var block = Expression.Block(new[] { counter }, expressions);
            return block;
        }
        public Expression DeserializerExpression(
            ParameterExpression streamReaderExpression,
            ParameterExpression serializationContextExpression,
            Expression assignmentTargetExpression,
            PropertyMetaData propertyMetaData)
        {
            var expressions = new List <Expression>();

            var arrayLength = Expression.Variable(typeof(int), "size");
            var newArray    = Expression.Parameter(this.type, "newArray");
            var counter     = Expression.Variable(typeof(int), "i");
            var element     = Expression.Variable(this.typeSerializer.Type, "element");
            var @break      = Expression.Label();

            Expression setArrayLength;

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NullTerminated)
            {
                var           xt1               = typeof(List <>).MakeGenericType(this.typeSerializer.Type);
                var           tempList          = Expression.Variable(xt1, "xt1");
                NewExpression newListExpression = Expression.New(xt1);

                // Create temporary List<T>

                expressions.Add(Expression.Assign(tempList, newListExpression));


                var readint      = Expression.Assign(arrayLength, Expression.Call(streamReaderExpression, ReflectionHelper.GetMethodInfo <StreamReader, Func <int> >(o => o.ReadInt32)));
                var positionProp = Expression.PropertyOrField(streamReaderExpression, "Position");

                var innerBlock = Expression.Block(
                    new[] { element },
                    new[]
                {
                    Expression.SubtractAssign(positionProp, Expression.Constant((long)4)),
                    this.typeSerializer.DeserializerExpression(
                        streamReaderExpression,
                        serializationContextExpression,
                        element,
                        propertyMetaData),
                    Expression.Call(
                        tempList,
                        typeof(List <>).MakeGenericType(this.typeSerializer.Type).GetMethod("Add"),
                        new[] { element })
                });


                var ifElse3 = Expression.Block(
                    new[] { arrayLength },
                    new Expression[]
                    { readint,
                      Expression.IfThenElse(
                          Expression.NotEqual(arrayLength, Expression.Constant(0)),
                          innerBlock,
                          Expression.Break(@break)) });
                expressions.Add(Expression.Assign(arrayLength, Expression.Constant(1)));


                expressions.Add(Expression.Loop(ifElse3, @break));
                expressions.Add(Expression.Assign(newArray, Expression.Call(tempList, typeof(List <>).MakeGenericType(this.typeSerializer.Type).GetMethod("ToArray"))));

                var assignExp = Expression.Assign(assignmentTargetExpression, Expression.Convert(newArray, this.type));
                expressions.Add(assignExp);

                var block = Expression.Block(new[] { tempList, arrayLength, newArray, counter }, expressions);
                return(block);
            }
            else
            {
                if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
                {
                    setArrayLength =
                        new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).DeserializerExpression(
                            streamReaderExpression, serializationContextExpression, arrayLength, propertyMetaData);
                }
                else
                {
                    setArrayLength = Expression.Assign(
                        arrayLength, Expression.Constant(propertyMetaData.Options.FixedSizeLength, typeof(int)));
                }

                expressions.Add(setArrayLength);

                var createNewArray = Expression.NewArrayBounds(this.typeSerializer.Type, arrayLength);
                expressions.Add(Expression.Assign(newArray, createNewArray));

                expressions.Add(Expression.Assign(counter, Expression.Constant(0)));
                var assign = Expression.Assign(Expression.ArrayAccess(newArray, counter), element);
                var ifElse = Expression.IfThenElse(
                    Expression.LessThan(counter, arrayLength),
                    Expression.Block(
                        new[] { element },
                        new[]
                {
                    this.typeSerializer.DeserializerExpression(
                        streamReaderExpression, serializationContextExpression, element, propertyMetaData),
                    assign, Expression.Assign(counter, Expression.Increment(counter))
                }),
                    Expression.Break(@break));

                var forExp = Expression.Loop(ifElse, @break);
                expressions.Add(forExp);

                var assignExp = Expression.Assign(assignmentTargetExpression, Expression.Convert(newArray, this.type));
                expressions.Add(assignExp);

                var block = Expression.Block(new[] { arrayLength, newArray, counter }, expressions);
                return(block);
            }
        }
        public Expression SerializerExpression(
            ParameterExpression streamWriterExpression,
            ParameterExpression serializationContextExpression,
            Expression valueExpression,
            PropertyMetaData propertyMetaData)
        {
            if (valueExpression.Type.IsAssignableFrom(this.type) == false)
            {
                valueExpression = Expression.Convert(valueExpression, this.type);
            }

            var expressions = new List <Expression>();

            if ((propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization) && (propertyMetaData.Options.SerializeSize != ArraySizeType.NullTerminated))
            {
                var serializeSizeExp =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).SerializerExpression(
                        streamWriterExpression, serializationContextExpression, valueExpression, propertyMetaData);
                expressions.Add(serializeSizeExp);
            }

            var @break      = Expression.Label();
            var arrayLength = Expression.ArrayLength(valueExpression);
            var counter     = Expression.Variable(typeof(int), "i");

            expressions.Add(Expression.Assign(counter, Expression.Constant(0)));
            var element = Expression.Variable(this.typeSerializer.Type, "element");
            var assign  = Expression.Assign(element, Expression.ArrayIndex(valueExpression, counter));
            var ifElse  = Expression.IfThenElse(
                Expression.LessThan(counter, arrayLength),
                Expression.Block(
                    new[] { element },
                    new[]
            {
                assign,
                this.typeSerializer.SerializerExpression(
                    streamWriterExpression, serializationContextExpression, element, propertyMetaData),
                Expression.Assign(counter, Expression.Increment(counter))
            }),
                Expression.Break(@break));

            var forExp = Expression.Loop(ifElse, @break);

            expressions.Add(forExp);

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NullTerminated)
            {
                MethodInfo writeCloser = null;
                if ((propertyMetaData.Type == typeof(string)) || (propertyMetaData.Type == typeof(byte)))
                {
                    writeCloser = ReflectionHelper.GetMethodInfo <StreamWriter, Action <byte> >(o => o.WriteByte);
                }
                else if (propertyMetaData.Type == typeof(short))
                {
                    writeCloser = ReflectionHelper.GetMethodInfo <StreamWriter, Action <short> >(o => o.WriteInt16);
                }
                else
                {
                    writeCloser = ReflectionHelper.GetMethodInfo <StreamWriter, Action <Int32> >(o => o.WriteInt32);
                }

                Expression sernull = Expression.Call(
                    streamWriterExpression,
                    writeCloser,
                    new[] { Expression.Constant(0) });
                expressions.Add(sernull);
            }

            var block = Expression.Block(new[] { counter }, expressions);

            return(block);
        }
        public Expression DeserializerExpression(
            ParameterExpression streamReaderExpression,
            ParameterExpression serializationContextExpression,
            Expression assignmentTargetExpression,
            PropertyMetaData propertyMetaData)
        {
            var expressions = new List <Expression>();

            var arrayLength = Expression.Variable(typeof(int), "size");

            Expression setArrayLength;

            if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
            {
                setArrayLength =
                    new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).DeserializerExpression(
                        streamReaderExpression, serializationContextExpression, arrayLength, propertyMetaData);
            }
            else
            {
                setArrayLength = Expression.Assign(
                    arrayLength, Expression.Constant(propertyMetaData.Options.FixedSizeLength, typeof(int)));
            }

            expressions.Add(setArrayLength);

            var createNewArray = Expression.NewArrayBounds(this.typeSerializer.Type, arrayLength);
            var newArray       = Expression.Parameter(this.type, "newArray");

            expressions.Add(Expression.Assign(newArray, createNewArray));

            var @break  = Expression.Label();
            var counter = Expression.Variable(typeof(int), "i");

            expressions.Add(Expression.Assign(counter, Expression.Constant(0)));
            var element = Expression.Variable(this.typeSerializer.Type, "element");
            var assign  = Expression.Assign(Expression.ArrayAccess(newArray, counter), element);
            var ifElse  = Expression.IfThenElse(
                Expression.LessThan(counter, arrayLength),
                Expression.Block(
                    new[] { element },
                    new[]
            {
                this.typeSerializer.DeserializerExpression(
                    streamReaderExpression, serializationContextExpression, element, propertyMetaData),
                assign, Expression.Assign(counter, Expression.Increment(counter))
            }),
                Expression.Break(@break));

            var forExp = Expression.Loop(ifElse, @break);

            expressions.Add(forExp);

            var assignExp = Expression.Assign(assignmentTargetExpression, Expression.Convert(newArray, this.type));

            expressions.Add(assignExp);

            var block = Expression.Block(new[] { arrayLength, newArray, counter }, expressions);

            return(block);
        }
        public Expression DeserializerExpression(
            ParameterExpression streamReaderExpression,
            ParameterExpression serializationContextExpression,
            Expression assignmentTargetExpression,
            PropertyMetaData propertyMetaData)
        {
            var expressions = new List<Expression>();

            var arrayLength = Expression.Variable(typeof(int), "size");
            var newArray = Expression.Parameter(this.type, "newArray");
            var counter = Expression.Variable(typeof(int), "i");
            var element = Expression.Variable(this.typeSerializer.Type, "element");
            var @break = Expression.Label();

            Expression setArrayLength;

            if (propertyMetaData.Options.SerializeSize == ArraySizeType.NullTerminated)
            {

                var xt1 = typeof(List<>).MakeGenericType(this.typeSerializer.Type);
                var tempList = Expression.Variable(xt1, "xt1");
                NewExpression newListExpression = Expression.New(xt1);

                // Create temporary List<T>

                expressions.Add(Expression.Assign(tempList, newListExpression));


                var readint = Expression.Assign(arrayLength, Expression.Call(streamReaderExpression, ReflectionHelper.GetMethodInfo<StreamReader, Func<int>>(o => o.ReadInt32)));
                var positionProp = Expression.PropertyOrField(streamReaderExpression, "Position");

                var innerBlock = Expression.Block(
                    new[] { element },
                    new[]
                    {
                        Expression.SubtractAssign(positionProp, Expression.Constant((long)4)),
                        this.typeSerializer.DeserializerExpression(
                            streamReaderExpression,
                            serializationContextExpression,
                            element,
                            propertyMetaData),
                        Expression.Call(
                            tempList,
                            typeof(List<>).MakeGenericType(this.typeSerializer.Type).GetMethod("Add"),
                            new[] { element })
                    });


                var ifElse3 = Expression.Block(
                    new[] { arrayLength },
                    new Expression[]
                    {readint,
                        Expression.IfThenElse(
                            Expression.NotEqual(arrayLength, Expression.Constant(0)),
                            innerBlock,
                            Expression.Break(@break))
                    });
                expressions.Add(Expression.Assign(arrayLength, Expression.Constant(1)));


                expressions.Add(Expression.Loop(ifElse3, @break));
                expressions.Add(Expression.Assign(newArray, Expression.Call(tempList, typeof(List<>).MakeGenericType(this.typeSerializer.Type).GetMethod("ToArray"))));

                var assignExp = Expression.Assign(assignmentTargetExpression, Expression.Convert(newArray, this.type));
                expressions.Add(assignExp);

                var block = Expression.Block(new[] { tempList, arrayLength, newArray, counter }, expressions);
                return block;
            }
            else
            {
                if (propertyMetaData.Options.SerializeSize != ArraySizeType.NoSerialization)
                {
                    setArrayLength =
                        new ArraySizeSerializer(propertyMetaData.Options.SerializeSize).DeserializerExpression(
                            streamReaderExpression, serializationContextExpression, arrayLength, propertyMetaData);
                }
                else
                {
                    setArrayLength = Expression.Assign(
                        arrayLength, Expression.Constant(propertyMetaData.Options.FixedSizeLength, typeof(int)));
                }

                expressions.Add(setArrayLength);

                var createNewArray = Expression.NewArrayBounds(this.typeSerializer.Type, arrayLength);
                expressions.Add(Expression.Assign(newArray, createNewArray));

                expressions.Add(Expression.Assign(counter, Expression.Constant(0)));
                var assign = Expression.Assign(Expression.ArrayAccess(newArray, counter), element);
                var ifElse = Expression.IfThenElse(
                    Expression.LessThan(counter, arrayLength),
                    Expression.Block(
                        new[] { element },
                        new[]
                        {
                            this.typeSerializer.DeserializerExpression(
                                streamReaderExpression, serializationContextExpression, element, propertyMetaData), 
                            assign, Expression.Assign(counter, Expression.Increment(counter))
                        }),
                    Expression.Break(@break));

                var forExp = Expression.Loop(ifElse, @break);
                expressions.Add(forExp);

                var assignExp = Expression.Assign(assignmentTargetExpression, Expression.Convert(newArray, this.type));
                expressions.Add(assignExp);

                var block = Expression.Block(new[] { arrayLength, newArray, counter }, expressions);
                return block;
            }
        }