/// <summary> /// Reads a <see cref="Duality.Serialization.MetaFormat.StructNode"/>, including possible child nodes. /// </summary> /// <param name="node"></param> protected StructNode ReadStruct(bool classType) { // Read struct type string objTypeString = this.reader.GetAttribute("type"); string objIdString = this.reader.GetAttribute("id"); string customString = this.reader.GetAttribute("custom"); string surrogateString = this.reader.GetAttribute("surrogate"); uint objId = objIdString == null ? 0 : XmlConvert.ToUInt32(objIdString); bool custom = customString != null && XmlConvert.ToBoolean(customString); bool surrogate = surrogateString != null && XmlConvert.ToBoolean(surrogateString); StructNode result = new StructNode(classType, objTypeString, objId, custom, surrogate); // Read surrogate constructor data if (surrogate) { custom = true; // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, objId); CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.HeaderElement); customIO.Deserialize(this); if (customIO.Data.Any()) { DummyNode surrogateConstructor = new DummyNode(); surrogateConstructor.Parent = result; foreach (var pair in customIO.Data) { StringNode key = new StringNode(pair.Key); DataNode value = pair.Value as DataNode; key.Parent = surrogateConstructor; value.Parent = surrogateConstructor; } } } // Prepare object reference this.idManager.Inject(result, objId); // Read custom object data if (custom) { CustomSerialIO customIO = new CustomSerialIO(CustomSerialIO.BodyElement); customIO.Deserialize(this); foreach (var pair in customIO.Data) { StringNode key = new StringNode(pair.Key); DataNode value = pair.Value as DataNode; key.Parent = result; value.Parent = result; } } // Red non-custom object data else if (!this.reader.IsEmptyElement) { // Read fields bool scopeChanged; string fieldName; DataNode fieldValue; while (true) { fieldValue = this.ReadObject(out fieldName, out scopeChanged) as DataNode; if (scopeChanged) break; else { fieldValue.Name = fieldName; fieldValue.Parent = result; } } } return result; }
/// <summary> /// Reads a <see cref="Duality.Serialization.MetaFormat.StructNode"/>, including possible child nodes. /// </summary> /// <param name="node"></param> protected StructNode ReadStruct(bool classType) { // Read struct type string objTypeString = this.reader.ReadString(); uint objId = this.reader.ReadUInt32(); bool custom = this.reader.ReadBoolean(); bool surrogate = this.reader.ReadBoolean(); StructNode result = new StructNode(classType, objTypeString, objId, custom, surrogate); // Read surrogate constructor data if (surrogate) { 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); if (customIO.Data.Any()) { DummyNode surrogateConstructor = new DummyNode(); surrogateConstructor.Parent = result; foreach (var pair in customIO.Data) { StringNode key = new StringNode(pair.Key); DataNode value = pair.Value as DataNode; key.Parent = surrogateConstructor; value.Parent = surrogateConstructor; } } } // Prepare object reference this.idManager.Inject(result, objId); if (custom) { CustomSerialIO customIO = new CustomSerialIO(); customIO.Deserialize(this); foreach (var pair in customIO.Data) { StringNode key = new StringNode(pair.Key); DataNode value = pair.Value as DataNode; key.Parent = result; value.Parent = result; } } else { // Determine data layout bool wasThereBefore = this.GetCachedTypeDataLayout(objTypeString) != null; TypeDataLayout layout = this.ReadTypeDataLayout(objTypeString); if (!wasThereBefore) { TypeDataLayoutNode layoutNode = new TypeDataLayoutNode(new TypeDataLayout(layout)); layoutNode.Parent = result; } // Read fields if (this.dataVersion <= 2) { for (int i = 0; i < layout.Fields.Length; i++) { DataNode fieldValue = this.ReadObject() as DataNode; fieldValue.Parent = result; fieldValue.Name = layout.Fields[i].name; } } 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; DataNode fieldValue = this.ReadObject() as DataNode; fieldValue.Parent = result; fieldValue.Name = layout.Fields[i].name; } } } return result; }