private void WriteTypeDataLayout(TypeDataLayout layout, string typeString) { this.typeDataLayout[typeString] = layout; this.writer.Write(-1L); this.typeDataLayoutMap[typeString] = this.writer.BaseStream.Position; layout.Write(this.writer); }
private void WriteTypeDataLayout(string typeString) { if (this.typeDataLayout.ContainsKey(typeString)) { long backRef = this.typeDataLayoutMap[typeString]; this.writer.Write(backRef); return; } Type resolved = this.ResolveType(typeString); SerializeType cached = GetSerializeType(resolved); TypeDataLayout layout = cached != null ? new TypeDataLayout(cached) : null; this.WriteTypeDataLayout(layout, typeString); }
/// <summary> /// Reads a structural object, including referenced objects. /// </summary> /// <returns>The object that has been read.</returns> protected object ReadStruct() { // Read struct type string objTypeString = this.reader.ReadString(); uint objId = this.reader.ReadUInt32(); bool custom = this.reader.ReadBoolean(); bool surrogate = this.reader.ReadBoolean(); Type objType = this.ResolveType(objTypeString, objId); SerializeType objSerializeType = null; if (objType != null) { objSerializeType = objType.GetSerializeType(); } // Retrieve surrogate if requested ISurrogate objSurrogate = null; if (surrogate && objType != null) { objSurrogate = this.GetSurrogateFor(objType); } // Construct object object obj = null; if (objType != null) { if (objSurrogate != null) { custom = true; // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, objId); CustomSerialIO customIO = new CustomSerialIO(); customIO.Deserialize(this); try { obj = objSurrogate.ConstructObject(customIO, objType); } catch (Exception e) { this.LogCustomDeserializationError(objId, objType, e); } } if (obj == null) { obj = objType.CreateInstanceOf(); } if (obj == null) { obj = objType.CreateInstanceOf(true); } } // Prepare object reference this.idManager.Inject(obj, objId); // Read custom object data if (custom) { CustomSerialIO customIO = new CustomSerialIO(); customIO.Deserialize(this); ISerializable objAsCustom; if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; } else { objAsCustom = obj as ISerializable; } if (objAsCustom != null) { try { objAsCustom.ReadData(customIO); } catch (Exception e) { this.LogCustomDeserializationError(objId, objType, e); } } else if (obj != null && objType != null) { this.SerializationLog.WriteWarning( "Object data (Id {0}) is flagged for custom deserialization, yet the objects Type ('{1}') does not support it. Guessing associated fields...", objId, Log.Type(objType)); this.SerializationLog.PushIndent(); foreach (var pair in customIO.Data) { this.AssignValueToField(objSerializeType, obj, pair.Key, pair.Value); } this.SerializationLog.PopIndent(); } } // Red non-custom object data else { // Determine data layout TypeDataLayout layout = this.ReadTypeDataLayout(objTypeString); // Read fields if (this.dataVersion <= 2) { for (int i = 0; i < layout.Fields.Length; i++) { object fieldValue = this.ReadObjectData(); this.AssignValueToField(objSerializeType, obj, layout.Fields[i].name, fieldValue); } } else if (this.dataVersion >= 3) { bool[] fieldOmitted = new bool[layout.Fields.Length]; this.ReadArrayData(fieldOmitted); for (int i = 0; i < layout.Fields.Length; i++) { if (fieldOmitted[i]) { continue; } object fieldValue = this.ReadObjectData(); this.AssignValueToField(objSerializeType, obj, layout.Fields[i].name, fieldValue); } } } return(obj); }
private object ReadStruct(ObjectHeader header) { // Read struct type bool custom = this.reader.ReadBoolean(); bool surrogate = this.reader.ReadBoolean(); // Retrieve surrogate if requested ISerializeSurrogate objSurrogate = null; if (surrogate && header.SerializeType != null) { custom = true; objSurrogate = header.SerializeType.Surrogate; if (objSurrogate == null) { this.LocalLog.WriteError( "Object type '{0}' was serialized using a surrogate, but no such surrogate was found for deserialization.", LogFormat.Type(header.SerializeType.Type)); } } // If the object was serialized as a surrogate, deserialize its header first CustomSerialIO surrogateHeader = null; if (surrogate) { // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, header.ObjectId); surrogateHeader = new CustomSerialIO(); surrogateHeader.Deserialize(this); } // Construct object object obj = null; if (header.ObjectType != null) { if (objSurrogate != null) { try { obj = objSurrogate.ConstructObject(surrogateHeader, header.ObjectType); } catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); } } if (obj == null) { obj = header.ObjectType.CreateInstanceOf(); } } // Prepare object reference this.idManager.Inject(obj, header.ObjectId); // Read custom object data if (custom) { CustomSerialIO customIO = new CustomSerialIO(); customIO.Deserialize(this); ISerializeExplicit objAsCustom; if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; } else { objAsCustom = obj as ISerializeExplicit; } if (objAsCustom != null) { try { objAsCustom.ReadData(customIO); } catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); } } else if (obj != null && header.ObjectType != null) { this.LocalLog.WriteWarning( "Object data (Id {0}) is flagged for custom deserialization, yet the objects Type ('{1}') does not support it. Guessing associated fields...", header.ObjectId, LogFormat.Type(header.ObjectType)); this.LocalLog.PushIndent(); foreach (var pair in customIO.Data) { this.AssignValueToField(header.SerializeType, obj, pair.Key, pair.Value); } this.LocalLog.PopIndent(); } } // Red non-custom object data else { // Determine data layout TypeDataLayout layout = this.ReadTypeDataLayout(header.TypeString); // Read fields bool[] fieldOmitted = new bool[layout.Fields.Length]; this.ReadArrayData(fieldOmitted); for (int i = 0; i < layout.Fields.Length; i++) { if (fieldOmitted[i]) { continue; } object fieldValue = this.ReadObjectData(); this.AssignValueToField(header.SerializeType, obj, layout.Fields[i].name, fieldValue); } } return(obj); }
/// <summary> /// Initializes a TypeDataLayout by cloning an existing TypeDataLayout. /// </summary> /// <param name="t">The source layout</param> public TypeDataLayout(TypeDataLayout t) { this.fields = t.fields != null ? t.fields.Clone() as FieldDataInfo[] : null; }
/// <summary> /// Initializes a TypeDataLayout by cloning an existing TypeDataLayout. /// </summary> /// <param name="t">The source layout</param> public TypeDataLayout(TypeDataLayout t) { this.fields = t.fields != null?t.fields.Clone() as FieldDataInfo[] : null; }