private static void WriteObject(XmlWriter writer, Interface.Object o) { writer.WriteElementString("name", o.Name); writer.WriteElementString("type", o.Type); writer.WriteStartElement("baseline"); foreach (var kv in o.Baseline.Properties) { writer.WriteStartElement("property"); WriteProperty(writer, kv); writer.WriteEndElement(); // property } writer.WriteEndElement(); // baseline writer.WriteStartElement("overrides"); foreach (var resolution in o.Overrides) { writer.WriteStartElement("resolution"); writer.WriteElementString("name", resolution.Key); foreach (var kv in resolution.Value.Properties) { writer.WriteStartElement("property"); WriteProperty(writer, kv); writer.WriteEndElement(); // property } writer.WriteEndElement(); // resolution } writer.WriteEndElement(); // overrides writer.WriteStartElement("children"); foreach (Interface.Object child in o.Children) { writer.WriteStartElement("object"); WriteObject(writer, child); writer.WriteEndElement(); // object } writer.WriteEndElement(); // children }
public void Deserialize(Stream input) { var magic = input.ReadValueU32(Endian.Little); if (magic != Signature && magic.Swap() != Signature) { throw new FormatException(); } var endian = magic == Signature ? Endian.Little : Endian.Big; var nameIndex = input.ReadValueS32(endian); var version = input.ReadValueU16(endian); var animationTime = input.ReadValueF32(endian); var metadataCount = input.ReadValueU32(endian); var criticalResourceCount = input.ReadValueU32(endian); var stringTableOffset = input.ReadValueU32(endian); var elementCount = input.ReadValueU16(endian); var animationCount = input.ReadValueU16(endian); if (version != 1 && version != 2) { throw new FormatException(); } if (stringTableOffset >= input.Length) { throw new FormatException(); } var position = input.Position; input.Seek(stringTableOffset, SeekOrigin.Begin); var strings = new Interface.StringTable(); strings.Deserialize(input, endian); input.Seek(position, SeekOrigin.Begin); if (nameIndex != 0) { throw new FormatException(); } var fileName = strings.ReadString(nameIndex); var criticalResources = new Interface.CriticalResource[criticalResourceCount]; for (uint i = 0; i < criticalResourceCount; i++) { var type = input.ReadValueEnum <Interface.CriticalResourceType>(); if (type != Interface.CriticalResourceType.Peg && type != Interface.CriticalResourceType.Document) { throw new FormatException(); } var name = strings.ReadString(input, endian); var autoload = this._Version >= 2 && input.ReadValueB8() == true; if (autoload == true && type != Interface.CriticalResourceType.Peg) { throw new FormatException(); } criticalResources[i] = new Interface.CriticalResource() { Type = type, Name = name, Autoload = autoload, }; } var metadatas = new Interface.Metadata[metadataCount]; for (uint i = 0; i < metadataCount; i++) { var name = strings.ReadString(input, endian); var value = strings.ReadString(input, endian); metadatas[i] = new Interface.Metadata(name, value); } var elements = new Interface.Object[elementCount]; for (ushort i = 0; i < elementCount; i++) { var element = new Interface.Object(); element.Deserialize(input, endian, strings); elements[i] = element; } var animations = new Interface.Object[animationCount]; for (ushort i = 0; i < animationCount; i++) { var animation = new Interface.Object(); animation.Deserialize(input, endian, strings); animations[i] = animation; } if (input.Position != stringTableOffset) { throw new FormatException(); } this._Endian = endian; this._Name = fileName; this._Version = version; this._AnimationTime = animationTime; this._CriticalResources.Clear(); this._CriticalResources.AddRange(criticalResources); this._Metadata.Clear(); this._Metadata.AddRange(metadatas); this._Elements.Clear(); this._Elements.AddRange(elements); this._Animations.Clear(); this._Animations.AddRange(animations); }