Пример #1
0
        public override TObject Deserialize(Stream stream)
        {
            var  theObject = Activator.CreateInstance <TObject>();
            Type enumerableType;

            foreach (var property in _properties)
            {
                if (TypesInfo.SystemTypes.Contains(property.PropertyType))
                {
                    ReadObjectProperty(stream, property, theObject);
                }
                else if (TypesInfo.IsNullable(property.PropertyType))
                {
                    ReadObjectNullableProperty(stream, property, theObject);
                }
                else if (TypesInfo.IsSupportedCollectionType(property.PropertyType, out enumerableType))
                {
                    var lengthBytes = new byte[sizeof(int)];
                    stream.Read(lengthBytes, 0, lengthBytes.Length);
                    var arrayLength = BitConverter.ToInt32(lengthBytes, 0);
                    if (arrayLength > NullBytesCout)
                    {
                        var elementType = enumerableType == typeof(Array)
                            ? property.PropertyType.GetElementType()
                            : enumerableType.GetGenericArguments()[0];

                        var array = Array.CreateInstance(elementType, arrayLength);
                        for (var i = 0; i < arrayLength; i++)
                        {
                            var element = ReadValue(stream, elementType);
                            array.SetValue(element, i);
                        }

                        if (enumerableType == typeof(Array))
                        {
                            property.SetValue(theObject, array);
                        }
                        else
                        {
                            var ctor       = property.PropertyType.GetConstructor(new [] { enumerableType });
                            var enumerable = ctor.Invoke(new [] { array });
                            property.SetValue(theObject, enumerable);
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            return(theObject);
        }
Пример #2
0
        public override void Serialize(TObject theObject, Stream stream)
        {
            // properties
            foreach (var property in _properties)
            {
                Type enumerableType;
                if (TypesInfo.SystemTypes.Contains(property.PropertyType))
                {
                    WriteObjectProperty(stream, property, theObject);
                }
                else if (TypesInfo.IsNullable(property.PropertyType))
                {
                    WriteObjectNullableProperty(stream, property, theObject);
                }
                else if (TypesInfo.IsSupportedCollectionType(property.PropertyType, out enumerableType))
                {
                    var elementType = enumerableType == typeof(Array)
                        ? property.PropertyType.GetElementType()
                        : enumerableType.GetGenericArguments()[0];
                    var array = enumerableType == typeof(Array)
                        ? (Array)property.GetValue(theObject)
                        : (Array)EnumerablesInfo
                                .GetToArrayMethod(enumerableType)
                                .Invoke(null, new object[] { property.GetValue(theObject) });
                    if (array != null)
                    {
                        var arrayLengthBytes = BitConverter.GetBytes(array.Length);
                        stream.Write(arrayLengthBytes, 0, arrayLengthBytes.Length);

                        for (var i = 0; i < array.Length; i++)
                        {
                            var arrayValue = array.GetValue(i);
                            WriteValueBytes(stream, arrayValue, elementType);
                        }
                    }
                    else
                    {
                        var arrayLengthBytes = BitConverter.GetBytes(NullBytesCout);
                        stream.Write(arrayLengthBytes, 0, arrayLengthBytes.Length);
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
Пример #3
0
        public static EmitSerializer <TObject> Generate <TObject>()
            where TObject : class, new()
        {
            var propertiesWriter = new DynamicMethod(
                "WriteProperties",
                null,
                new Type[] { typeof(Stream), typeof(TObject) },
                typeof(EmitSerializer <TObject>));
            var writerIlGenerator = propertiesWriter.GetILGenerator();
            var writerEmitter     = new CodeEmitter(writerIlGenerator);

            var propertiesReader = new DynamicMethod(
                "ReadProperties",
                null,
                new Type[] { typeof(Stream), typeof(TObject) },
                typeof(EmitSerializer <TObject>));
            var readerIlGenerator = propertiesReader.GetILGenerator();
            var readerEmitter     = new CodeEmitter(readerIlGenerator);

            var properties = typeof(TObject).GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(byte))
                {
                    writerEmitter.EmitWriteBytePropertyCode(property);
                    readerEmitter.EmitReadBytePropertyCode(property);
                }
                else if (TypesInfo.PrimitiveTypes.Contains(property.PropertyType))
                {
                    writerEmitter.EmitWritePrimitiveTypePropertyCode(property);
                    readerEmitter.EmitReadPrimitiveTypePropertyCode(property);
                }
                else if (property.PropertyType == typeof(Guid))
                {
                    writerEmitter.EmitWriteGuidPropertyCode(property);
                    readerEmitter.EmitReadGuidPropertyCode(property);
                }
                else if (property.PropertyType == typeof(DateTime))
                {
                    writerEmitter.EmitWriteDateTimePropertyCode(property);
                    readerEmitter.EmitReadDateTimePropertyCode(property);
                }
                else if (property.PropertyType == typeof(DateTimeOffset))
                {
                    writerEmitter.EmitWriteDateTimeOffsetPropertyCode(property);
                    readerEmitter.EmitReadDateTimeOffsetPropertyCode(property);
                }
                else if (property.PropertyType == typeof(string))
                {
                    writerEmitter.EmitWriteStringPropertyCode(property);
                    readerEmitter.EmitReadStringPropertyCode(property);
                }
                else if (property.PropertyType.IsArray)
                {
                    writerEmitter.EmitWriteArrayPropertyCode(property);
                    readerEmitter.EmitReadArrayPropertyCode(property);
                }
                else if (GenericCollectionInfo.IsICollectionType(property.PropertyType))
                {
                    writerEmitter.EmitWriteCollectionPropertyCode(property);
                    readerEmitter.EmitReadCollectionPropertyCode(property);
                }
                else if (TypesInfo.IsNullable(property.PropertyType))
                {
                    writerEmitter.EmitWriteNullablePropertyCode(property);
                    readerEmitter.EmitReadNullablePropertyCode(property);
                }
                else
                {
                    throw new NotImplementedException(
                              "Not supported property: " + property.PropertyType.ToString() + " " + property.Name);
                }
            }

            writerEmitter.EmitMethodReturn();
            readerEmitter.EmitMethodReturn();

            var writePropertiesDelegate = (Action <Stream, TObject>)propertiesWriter.CreateDelegate(typeof(Action <Stream, TObject>));
            var readPropertiesDelegate  = (Action <Stream, TObject>)propertiesReader.CreateDelegate(typeof(Action <Stream, TObject>));

            return(new EmitSerializer <TObject>(writePropertiesDelegate, readPropertiesDelegate));
        }