private object ReadStruct(XElement element, ObjectHeader header) { // Read struct type string customString = element.GetAttributeValue("custom"); string surrogateString = element.GetAttributeValue("surrogate"); bool custom = customString != null && XmlConvert.ToBoolean(customString); bool surrogate = surrogateString != null && XmlConvert.ToBoolean(surrogateString); // Retrieve surrogate if requested ISerializeSurrogate objSurrogate = null; if (surrogate && header.ObjectType != null) { objSurrogate = GetSurrogateFor(header.ObjectType); } // Construct object object obj = null; if (header.ObjectType != null) { if (objSurrogate != null) { custom = true; // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, header.ObjectId); CustomSerialIO customIO = new CustomSerialIO(); XElement customHeaderElement = element.Element(CustomSerialIO.HeaderElement) ?? element.Elements().FirstOrDefault(); if (customHeaderElement != null) { customIO.Deserialize(this, customHeaderElement); } try { obj = objSurrogate.ConstructObject(customIO, 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(); XElement customBodyElement = element.Element(CustomSerialIO.BodyElement) ?? element.Elements().ElementAtOrDefault(1); if (customBodyElement != null) { customIO.Deserialize(this, customBodyElement); } 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, Log.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 if (!element.IsEmpty) { // Read fields object fieldValue; foreach (XElement fieldElement in element.Elements()) { fieldValue = this.ReadObjectData(fieldElement); this.AssignValueToField(header.SerializeType, obj, GetCodeElementName(fieldElement.Name.LocalName), 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.ObjectType != null) { objSurrogate = GetSurrogateFor(header.ObjectType); } // Construct object object obj = null; if (header.ObjectType != null) { if (objSurrogate != null) { custom = true; // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, header.ObjectId); CustomSerialIO customIO = new CustomSerialIO(); customIO.Deserialize(this); try { obj = objSurrogate.ConstructObject(customIO, 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, Log.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 if (this.dataVersion <= 2) { for (int i = 0; i < layout.Fields.Length; i++) { object fieldValue = this.ReadObjectData(); this.AssignValueToField(header.SerializeType, 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(header.SerializeType, obj, layout.Fields[i].name, fieldValue); } } } return(obj); }