示例#1
0
        /// <summary>
        /// Reads all nodes in the binary XML.
        /// </summary>
        /// <returns>Returns the XML document.</returns>
        public XmlDocument Read()
        {
            while (true)
            {
                var nodeType = _nodeBuffer.ReadU8();

                //Array flag is on the second bit
                var array = (nodeType & 64) > 0;
                nodeType = (byte)(nodeType & ~64);
                NodeType propertyType;

                if (Enum.IsDefined(typeof(ControlType), nodeType))
                {
                    switch ((ControlType)nodeType)
                    {
                    case ControlType.NodeStart:
                        var newElement = _xmlDocument.CreateElement
                                             (_nodeBuffer.ReadString(), null);

                        if (_currentElement != null)
                        {
                            _currentElement.AppendChild(newElement);
                        }
                        else
                        {
                            _xmlDocument.AppendChild(newElement);
                        }

                        _currentElement = newElement;
                        break;

                    case ControlType.Attribute:
                        var value = _dataBuffer.ReadString(_dataBuffer.ReadS32());
                        _currentElement.SetAttribute(_nodeBuffer.ReadString(), value);
                        break;

                    case ControlType.NodeEnd:
                        if (_currentElement.ParentNode is XmlDocument)
                        {
                            return(_xmlDocument);
                        }

                        _currentElement = (XmlElement)_currentElement.ParentNode;
                        break;

                    case ControlType.FileEnd:
                        return(_xmlDocument);
                    }
                }
                else if (TypeDictionary.TypeMap.TryGetValue(nodeType, out propertyType))
                {
                    var elementName = _nodeBuffer.ReadString();
                    _currentElement = (XmlElement)_currentElement.AppendChild(_xmlDocument.CreateElement(elementName));

                    var attribute = _xmlDocument.CreateAttribute("__type");
                    attribute.Value = propertyType.Name;
                    _currentElement.Attributes.Append(attribute);

                    var arraySize = propertyType.Size * propertyType.Count;
                    if (array || propertyType.Name == "str" || propertyType.Name == "bin")
                    {
                        arraySize = _dataBuffer.ReadS32(); //Total size.
                    }
                    if (propertyType.Name == "str")
                    {
                        _currentElement.InnerText = _dataBuffer.ReadString(arraySize);
                    }
                    else if (propertyType.Name == "bin")
                    {
                        _currentElement.InnerText = _dataBuffer.ReadBinary(arraySize);
                        _currentElement.SetAttribute("__size", arraySize.ToString());
                    }
                    else
                    {
                        if (array)
                        {
                            var size = (arraySize / (propertyType.Size * propertyType.Count)).ToString();
                            _currentElement.SetAttribute("__count", size);
                        }
                        var buffer = _dataBuffer.ReadBytes(arraySize);
                        var result = new List <string>();

                        for (var i = 0; i < arraySize / propertyType.Size; i++)
                        {
                            result.Add(propertyType.ToString(buffer.Skip(i * propertyType.Size)
                                                             .Take(propertyType.Size).ToArray()));
                        }
                        _currentElement.InnerText = string.Join(" ", result);
                    }
                }
                else
                {
                    throw new KbinException($"Unknown node type: {nodeType}");
                }
            }
        }
示例#2
0
        public byte[] ReadXmlByte()
        {
            string holdValue = null;

            while (true)
            {
                var nodeType = _nodeBuffer.ReadU8();

                //Array flag is on the second bit
                var array = (nodeType & 0x40) > 0;
                nodeType = (byte)(nodeType & ~0x40);
                NodeType propertyType;

                if (_controlTypes.Contains(nodeType))
                {
                    switch ((ControlType)nodeType)
                    {
                    case ControlType.NodeStart:
                        if (holdValue != null)
                        {
                            _xmlWriter.WriteString(holdValue);
                            holdValue = null;
                        }

                        var elementName = _nodeBuffer.ReadString();
                        _xmlWriter.WriteStartElement(elementName);
                        break;

                    case ControlType.Attribute:
                        var attr  = _nodeBuffer.ReadString();
                        var value = _dataBuffer.ReadString(_dataBuffer.ReadS32());
                        _xmlWriter.WriteStartAttribute(attr);
                        _xmlWriter.WriteString(value);
                        _xmlWriter.WriteEndAttribute();
                        break;

                    case ControlType.NodeEnd:
                        if (holdValue != null)
                        {
                            _xmlWriter.WriteString(holdValue);
                            holdValue = null;
                        }

                        _xmlWriter.WriteEndElement();
                        break;

                    case ControlType.FileEnd:
                        _xmlWriter.Flush();
                        return(_writerStream.ToArray());
                    }
                }
                else if (TypeDictionary.TypeMap.TryGetValue(nodeType, out propertyType))
                {
                    if (holdValue != null)
                    {
                        _xmlWriter.WriteString(holdValue);
                        holdValue = null;
                    }

                    var elementName = _nodeBuffer.ReadString();
                    _xmlWriter.WriteStartElement(elementName);

                    _xmlWriter.WriteStartAttribute("__type");
                    _xmlWriter.WriteString(propertyType.Name);
                    _xmlWriter.WriteEndAttribute();

                    int arraySize;
                    if (array || propertyType.Name == "str" || propertyType.Name == "bin")
                    {
                        arraySize = _dataBuffer.ReadS32(); //Total size.
                    }
                    else
                    {
                        arraySize = propertyType.Size * propertyType.Count;
                    }

                    if (propertyType.Name == "str")
                    {
                        holdValue = _dataBuffer.ReadString(arraySize);
                    }
                    else if (propertyType.Name == "bin")
                    {
                        _xmlWriter.WriteStartAttribute("__size");
                        _xmlWriter.WriteString(arraySize.ToString());
                        _xmlWriter.WriteEndAttribute();
                        holdValue = _dataBuffer.ReadBinary(arraySize);
                    }
                    else
                    {
                        if (array)
                        {
                            var size = (arraySize / (propertyType.Size * propertyType.Count)).ToString();
                            _xmlWriter.WriteStartAttribute("__count");
                            _xmlWriter.WriteString(size);
                            _xmlWriter.WriteEndAttribute();
                        }

                        var span          = _dataBuffer.ReadBytes(arraySize);
                        var stringBuilder = new StringBuilder();
                        var loopCount     = arraySize / propertyType.Size;
                        for (var i = 0; i < loopCount; i++)
                        {
                            var subSpan = span.Slice(i * propertyType.Size, propertyType.Size);
                            stringBuilder.Append(propertyType.GetString(subSpan));
                            if (i != loopCount - 1)
                            {
                                stringBuilder.Append(" ");
                            }
                        }

                        holdValue = stringBuilder.ToString();
                    }
                }
                else
                {
                    throw new KbinException($"Unknown node type: {nodeType}");
                }
            }
        }