private object InternalDeserializeInstance(BinaryReader reader, object o, Type t) { object ret = null; if (o != null) { //This allows PrepareForDeserialize to subclass the expected type if appropriate t = o.GetType(); //Debug.WriteLine("Deserializing instance " + t.Name); } switch (TypeExtensions.GetTypeCode(t)) { case TypeExtensions.TypeCode.Boolean: ret = reader.ReadBoolean(); break; case TypeExtensions.TypeCode.Char: ret = reader.ReadChar(); break; case TypeExtensions.TypeCode.SByte: ret = reader.ReadSByte(); break; case TypeExtensions.TypeCode.Byte: ret = reader.ReadByte(); break; case TypeExtensions.TypeCode.Int16: ret = reader.ReadInt16(); break; case TypeExtensions.TypeCode.UInt16: ret = reader.ReadUInt16(); break; case TypeExtensions.TypeCode.Int32: ret = reader.ReadInt32(); break; case TypeExtensions.TypeCode.UInt32: ret = reader.ReadUInt32(); break; case TypeExtensions.TypeCode.Int64: ret = reader.ReadInt64(); break; case TypeExtensions.TypeCode.UInt64: ret = reader.ReadUInt64(); break; case TypeExtensions.TypeCode.Single: if (Capabilities.FloatingPoint) { ret = reader.ReadSingle(); } else { ret = (float)reader.ReadInt32() / 1024; } break; case TypeExtensions.TypeCode.Double: if (Capabilities.FloatingPoint) { ret = reader.ReadDouble(); } else { ret = (double)reader.ReadInt64() / 65536; } break; case TypeExtensions.TypeCode.String: int num = reader.ReadInt32(); byte[] buf = reader.ReadBytes(num); ret = Encoding.UTF8.GetString(buf, 0, num); break; default: if (t.IsArray) { Array arr = (Array)o; for (int i = 0; i < arr.Length; i++) { object objValue = arr.GetValue(i); //if(reader.BaseStream.Position >= reader.BaseStream.Length) //{ // Debug.WriteLine("######################################################"); // Debug.WriteLine("################ trying to read after end of stream "); //} objValue = InternalDeserializeInstance(reader, objValue, t.GetElementType()); arr.SetValue(objValue, i); } ret = o; } else if (t.GetRuntimeProperties().FirstOrDefault(n => n.Name == "Count") != null) { // type implements Count property so it's a list // cast to IList IList list = (IList)o; // go through each list item and deserialize it for (int i = 0; i < list.Count; i++) { list[i] = InternalDeserializeInstance(reader, list[i], list[i].GetType()); } // done here, return the de-serialized list ret = list; } else if (t.GetTypeInfo().IsValueType || t.GetTypeInfo().IsClass) { if (o != null) { if (o.GetType() != t) { throw new SerializationException(); } } else { o = Activator.CreateInstance(t); } InternalDeserializeFields(reader, o); ret = o; } else { throw new SerializationException(); } break; } return(ret); }
private void InternalSerializeInstance(BinaryWriter writer, object o) { Type t = o.GetType(); switch (TypeExtensions.GetTypeCode(t)) { case TypeExtensions.TypeCode.Boolean: writer.Write((bool)o); break; case TypeExtensions.TypeCode.Char: writer.Write((char)o); break; case TypeExtensions.TypeCode.SByte: writer.Write((sbyte)o); break; case TypeExtensions.TypeCode.Byte: writer.Write((byte)o); break; case TypeExtensions.TypeCode.Int16: writer.Write((short)o); break; case TypeExtensions.TypeCode.UInt16: writer.Write((ushort)o); break; case TypeExtensions.TypeCode.Int32: writer.Write((int)o); break; case TypeExtensions.TypeCode.UInt32: writer.Write((uint)o); break; case TypeExtensions.TypeCode.Int64: writer.Write((long)o); break; case TypeExtensions.TypeCode.UInt64: writer.Write((ulong)o); break; case TypeExtensions.TypeCode.Single: if (Capabilities.FloatingPoint) { writer.Write((float)o); } else { writer.Write((int)((float)o * 1024)); } break; case TypeExtensions.TypeCode.Double: if (Capabilities.FloatingPoint) { writer.Write((double)o); } else { writer.Write((long)((double)o * 65536)); } break; case TypeExtensions.TypeCode.String: byte[] buf = Encoding.UTF8.GetBytes((string)o); writer.Write(buf.Length); writer.Write(buf); break; default: if (t == typeof(void)) { } else if (t.IsArray) { Array arr = (Array)o; foreach (object arrItem in arr) { InternalSerializeInstance(writer, arrItem); } } else if (t.GetRuntimeProperties().FirstOrDefault(n => n.Name == "Count") != null) { // type implements Count property so it's a list // cast to IList IList list = (IList)o; // go through each list item and serialize it foreach (object arrItem in list) { InternalSerializeInstance(writer, arrItem); } } else if (t.GetTypeInfo().IsValueType || t.GetTypeInfo().IsClass) { InternalSerializeFields(writer, o); } else { throw new SerializationException(); } break; } }