Пример #1
0
        private byte[] GetNodeData(XElement node, byte nodeType, XmlType xmlType, int count)
        {
            if (nodeType == XmlType.StrType)
            {
                if (count != 1)
                {
                    throw new FormatException("String value cannot have a count != 1.");
                }

                byte[] res = BinEncoding.GetBytes(node.Value.Trim());
                Array.Resize(ref res, res.Length + 1);
                res[res.Length - 1] = 0;
                return(res);
            }
            else if (nodeType == XmlType.BinType)
            {
                string val = node.Value;
                if ((val.Length % 2) != 0)
                {
                    throw new ArgumentException("Hex string needs to consist of pairs of two chars.");
                }

                byte[] res = new byte[val.Length / 2];
                for (int i = 0, j = 0; i < val.Length; i += 2, ++j)
                {
                    res[j] = Convert.ToByte(val.Substring(i, 2), 16);
                }

                return(res);
            }
            else
            {
                string[] parts = node.Value.Split(' ');
                if (parts.Length != count * xmlType.Count)
                {
                    throw new ArgumentException("Node value does not have required amount of fields.", "node");
                }

                byte[] res = new byte[xmlType.Size * count];
                for (int i = 0; i < count; ++i)
                {
                    Buffer.BlockCopy(xmlType.KFromString(parts, i * xmlType.Count), 0, res, xmlType.Size * i, xmlType.Size);
                }

                return(res);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }