private void ParseNodes() { uint dataSize = dataBuf.TakeU32(); XElement fakeroot = new XElement("fakeroot"); XElement node = fakeroot; bool nodesLeft = true; while (nodesLeft && !nodeBuf.AtEnd) { while (nodeBuf[nodeBuf.Offset] == 0) { nodeBuf.Offset += 1; } byte nodeType = nodeBuf.TakeU8(); bool isArray = (nodeType & 64) != 0; nodeType = (byte)(nodeType & ~64); string name = GetNodeName(nodeType); XmlType xmlType = null; bool startNode = false; switch (nodeType) { case XmlType.AttrType: string attrVal = dataBuf.TakeString(BinEncoding); dataBuf.RealignReads(); node.SetAttributeValue(name, attrVal); break; case XmlType.NodeEndType: node = node.Parent; break; case XmlType.SectionEndType: nodesLeft = false; break; case XmlType.VoidType: startNode = true; break; default: xmlType = XmlType.GetByType(nodeType); break; } if (xmlType == null && !startNode) { continue; } XElement child = new XElement(name); node.Add(child); node = child; if (startNode) { continue; } node.SetAttributeValue("__type", xmlType.Name); SetNodeValue(node, nodeType, xmlType, isArray); } Document = new XDocument(fakeroot.FirstNode); }
private void GenerateNode(XElement node) { if (NodeIsMixed(node)) { throw new ArgumentException("Nodes with mixed elements/text are not supported.", "node"); } XAttribute nodeTypeXAttr = node.Attribute("__type"); byte nodeType; XmlType xmlType = null; if (nodeTypeXAttr != null) { nodeType = XmlType.GetIdByName(nodeTypeXAttr.Value.ToLower()); xmlType = XmlType.GetByType(nodeType); } else { if (node.IsEmpty || node.HasElements) { nodeType = XmlType.VoidType; } else { nodeType = XmlType.StrType; } } bool isArray = false; int count = 1; XAttribute countXAttr = node.Attribute("__count"); if (countXAttr != null) { count = Convert.ToInt32(countXAttr.Value); isArray = true; } nodeBuf.AddU8((byte)(nodeType | (isArray ? 64 : 0))); AddNodeName(node.Name.LocalName); if (nodeType != XmlType.VoidType) { byte[] data = GetNodeData(node, nodeType, xmlType, count); if (isArray || xmlType.Count < 0) { dataBuf.AddS32(data.Length); dataBuf.AddBytesAligned(data); } else { dataBuf.AddBytesSubAligned(data); } } foreach (XAttribute attr in node.Attributes()) { if (attr.Name.LocalName == "__type" || attr.Name.LocalName == "__size" || attr.Name.LocalName == "__count") { continue; } nodeBuf.AddU8(XmlType.AttrType); AddNodeName(attr.Name.LocalName); dataBuf.AddString(attr.Value, BinEncoding); dataBuf.RealignWrites(); } foreach (XElement child in node.Elements()) { GenerateNode(child); } nodeBuf.AddU8(XmlType.NodeEndType | 64); }