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); }
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(); } } }
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)); }