Esempio n. 1
0
        private static void WriteNode(
            XmlWriter writer,
            BinaryResourceFile.Object node,
            IDefinitionProvider provider)
        {
            var def = provider.GetClassDefinition(node.TypeHash);

            writer.WriteStartElement("object");

            if (def.Name != null)
            {
                writer.WriteAttributeString("type", def.Name);
            }
            else
            {
                writer.WriteAttributeString("hash", node.TypeHash.ToString("X8"));
            }

            if (node.Values != null &&
                node.Values.Count > 0)
            {
                foreach (var kv in node.Values)
                {
                    writer.WriteStartElement("value");

                    var member = def.GetMemberDefinition(kv.Key);

                    if (member != null && member.Name != null)
                    {
                        writer.WriteAttributeString("name", member.Name);
                    }
                    else
                    {
                        writer.WriteAttributeString("hash", kv.Key.ToString("X8"));
                    }

                    if (member == null)
                    {
                        writer.WriteAttributeString("type", MemberType.BinHex.ToString());
                        writer.WriteBinHex(kv.Value, 0, kv.Value.Length);
                    }
                    else
                    {
                        writer.WriteAttributeString("type", member.Type.ToString());

                        switch (member.Type)
                        {
                        case MemberType.BinHex:
                        {
                            writer.WriteBinHex(kv.Value, 0, kv.Value.Length);
                            break;
                        }

                        case MemberType.Hash:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt32(kv.Value, 0).ToString("X8", CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.String:
                        {
                            if (kv.Value.Length < 1)
                            {
                                throw new FormatException();
                            }
                            else if (kv.Value[kv.Value.Length - 1] != 0)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(Encoding.UTF8.GetString(kv.Value, 0, kv.Value.Length - 1));
                            break;
                        }

                        case MemberType.Enum:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt32(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Bool:
                        {
                            if (kv.Value.Length != 1)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString((kv.Value[0] != 0 ? true : false).ToString());
                            break;
                        }

                        case MemberType.Float:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Int32:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToInt32(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.UInt32:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt32(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Int64:
                        {
                            if (kv.Value.Length != 8)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToInt64(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.UInt64:
                        {
                            if (kv.Value.Length != 8)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt64(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Vector2:
                        {
                            if (kv.Value.Length != 4 * 2)
                            {
                                throw new FormatException();
                            }

                            writer.WriteElementString("x", BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("y", BitConverter.ToSingle(kv.Value, 4).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Vector3:
                        {
                            if (kv.Value.Length != 4 * 3)
                            {
                                throw new FormatException();
                            }

                            writer.WriteElementString("x", BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("y", BitConverter.ToSingle(kv.Value, 4).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("z", BitConverter.ToSingle(kv.Value, 8).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Vector4:
                        {
                            if (kv.Value.Length != 4 * 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteElementString("x", BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("y", BitConverter.ToSingle(kv.Value, 4).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("z", BitConverter.ToSingle(kv.Value, 8).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("w", BitConverter.ToSingle(kv.Value, 12).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.UInt32Array:
                        {
                            if (kv.Value.Length < 4)
                            {
                                throw new FormatException();
                            }

                            var count = BitConverter.ToInt32(kv.Value, 0);
                            if (kv.Value.Length != 4 + (count * 4))
                            {
                                throw new FormatException();
                            }

                            for (int i = 0, offset = 4; i < count; i++, offset += 4)
                            {
                                writer.WriteElementString("item", BitConverter.ToUInt32(kv.Value, offset).ToString(CultureInfo.InvariantCulture));
                            }

                            break;
                        }

                        case MemberType.HashArray:
                        {
                            if (kv.Value.Length < 4)
                            {
                                throw new FormatException();
                            }

                            var count = BitConverter.ToInt32(kv.Value, 0);
                            if (kv.Value.Length != 4 + (count * 4))
                            {
                                throw new FormatException();
                            }

                            for (int i = 0, offset = 4; i < count; i++, offset += 4)
                            {
                                writer.WriteElementString("item", BitConverter.ToUInt32(kv.Value, offset).ToString("X8"));
                            }

                            break;
                        }

                        case MemberType.Rml:
                        {
                            var rez = new XmlResourceFile();
                            using (var input = new MemoryStream(kv.Value))
                            {
                                rez.Deserialize(input);
                            }

                            writer.WriteStartElement("rml");
                            ConvertXml.Program.WriteNode(writer, rez.Root);
                            writer.WriteEndElement();
                            break;
                        }

                        default:
                        {
                            throw new NotSupportedException();
                        }
                        }
                    }

                    writer.WriteEndElement();
                }
            }

            if (node.Children != null &&
                node.Children.Count > 0)
            {
                foreach (var child in node.Children)
                {
                    WriteNode(writer, child, def);
                }
            }

            writer.WriteEndElement();
        }
Esempio n. 2
0
        private static BinaryResourceFile.Object ReadNode(string basePath, XPathNavigator node)
        {
            string className;
            uint   classHash;

            Definitions.LoadTypeAndHash(node, out className, out classHash);

            var parent = new BinaryResourceFile.Object();

            parent.TypeHash = classHash;

            var values = node.Select("value");

            while (values.MoveNext() == true)
            {
                string valueName;
                uint   valueHash;

                Definitions.LoadNameAndHash(values.Current, out valueName, out valueHash);

                MemberType valueType;
                string     _valueType;
                _valueType = values.Current.GetAttribute("type", "");
                if (string.IsNullOrWhiteSpace(_valueType) == true ||
                    Enum.IsDefined(typeof(MemberType), _valueType) == false)
                {
                    throw new FormatException();
                }
                valueType = (MemberType)Enum.Parse(typeof(MemberType), _valueType);

                byte[] valueData;
                switch (valueType)
                {
                case MemberType.BinHex:
                {
                    using (var reader = new XmlTextReader(new StringReader(values.Current.OuterXml)))
                    {
                        reader.MoveToContent();
                        valueData = new byte[0];
                        int read = 0;
                        do
                        {
                            Array.Resize(ref valueData, valueData.Length + 4096);
                            read += reader.ReadBinHex(valueData, read, 4096);
                        }while (reader.EOF == false);
                        Array.Resize(ref valueData, read);
                    }

                    break;
                }

                case MemberType.Hash:
                {
                    valueData = BitConverter.GetBytes(uint.Parse(values.Current.Value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture));
                    break;
                }

                case MemberType.String:
                {
                    valueData = Encoding.UTF8.GetBytes(values.Current.Value);
                    Array.Resize(ref valueData, valueData.Length + 1);
                    break;
                }

                case MemberType.Enum:
                {
                    valueData = BitConverter.GetBytes(uint.Parse(values.Current.Value, CultureInfo.InvariantCulture));
                    break;
                }

                case MemberType.Bool:
                {
                    valueData    = new byte[1];
                    valueData[0] = (byte)(bool.Parse(values.Current.Value) == true ? 1 : 0);
                    break;
                }

                case MemberType.Int32:
                {
                    valueData = BitConverter.GetBytes(int.Parse(values.Current.Value, CultureInfo.InvariantCulture));
                    break;
                }

                case MemberType.UInt32:
                {
                    valueData = BitConverter.GetBytes(uint.Parse(values.Current.Value, CultureInfo.InvariantCulture));
                    break;
                }

                case MemberType.Int64:
                {
                    valueData = BitConverter.GetBytes(long.Parse(values.Current.Value, CultureInfo.InvariantCulture));
                    break;
                }

                case MemberType.UInt64:
                {
                    valueData = BitConverter.GetBytes(ulong.Parse(values.Current.Value, CultureInfo.InvariantCulture));
                    break;
                }

                case MemberType.Float:
                {
                    valueData = BitConverter.GetBytes(float.Parse(values.Current.Value, CultureInfo.InvariantCulture));
                    break;
                }

                case MemberType.Vector2:
                {
                    valueData = new byte[8];
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("x").Value, CultureInfo.InvariantCulture)), 0, valueData, 0, 4);
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("y").Value, CultureInfo.InvariantCulture)), 0, valueData, 4, 4);
                    break;
                }

                case MemberType.Vector3:
                {
                    valueData = new byte[12];
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("x").Value, CultureInfo.InvariantCulture)), 0, valueData, 0, 4);
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("y").Value, CultureInfo.InvariantCulture)), 0, valueData, 4, 4);
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("z").Value, CultureInfo.InvariantCulture)), 0, valueData, 8, 4);
                    break;
                }

                case MemberType.Vector4:
                {
                    valueData = new byte[16];
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("x").Value, CultureInfo.InvariantCulture)), 0, valueData, 0, 4);
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("y").Value, CultureInfo.InvariantCulture)), 0, valueData, 4, 4);
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("z").Value, CultureInfo.InvariantCulture)), 0, valueData, 8, 4);
                    Array.Copy(BitConverter.GetBytes(float.Parse(values.Current.SelectSingleNode("w").Value, CultureInfo.InvariantCulture)), 0, valueData, 12, 4);
                    break;
                }

                case MemberType.Rml:
                {
                    var rez = new XmlResourceFile();

                    var nav = values.Current.SelectSingleNode("rml");

                    rez.Root = ConvertXml.Program.ReadNode(nav);

                    using (var output = new MemoryStream())
                    {
                        rez.Serialize(output);
                        output.Position = 0;

                        valueData = new byte[output.Length];
                        output.Read(valueData, 0, valueData.Length);
                    }

                    break;
                }

                default:
                {
                    throw new FormatException();
                }
                }

                parent.Values.Add(valueHash, valueData);
            }

            var children = node.Select("object");

            while (children.MoveNext() == true)
            {
                parent.Children.Add(LoadNode(basePath, children.Current));
            }

            return(parent);
        }