Exemplo n.º 1
0
        private void WriteAttribute(NodeAttribute attr)
        {
            switch (attr.Type)
            {
            case NodeAttribute.DataType.DT_None:
                break;

            case NodeAttribute.DataType.DT_Byte:
                writer.Write((Byte)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Short:
                writer.Write((Int16)attr.Value);
                break;

            case NodeAttribute.DataType.DT_UShort:
                writer.Write((UInt16)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Int:
                writer.Write((Int32)attr.Value);
                break;

            case NodeAttribute.DataType.DT_UInt:
                writer.Write((UInt32)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Float:
                writer.Write((float)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Double:
                writer.Write((Double)attr.Value);
                break;

            case NodeAttribute.DataType.DT_IVec2:
            case NodeAttribute.DataType.DT_IVec3:
            case NodeAttribute.DataType.DT_IVec4:
                foreach (var item in (int[])attr.Value)
                {
                    writer.Write(item);
                }
                break;

            case NodeAttribute.DataType.DT_Vec2:
            case NodeAttribute.DataType.DT_Vec3:
            case NodeAttribute.DataType.DT_Vec4:
                foreach (var item in (float[])attr.Value)
                {
                    writer.Write(item);
                }
                break;

            case NodeAttribute.DataType.DT_Mat2:
            case NodeAttribute.DataType.DT_Mat3:
            case NodeAttribute.DataType.DT_Mat3x4:
            case NodeAttribute.DataType.DT_Mat4x3:
            case NodeAttribute.DataType.DT_Mat4:
            {
                var mat = (Matrix)attr.Value;
                for (int col = 0; col < mat.cols; col++)
                {
                    for (int row = 0; row < mat.rows; row++)
                    {
                        writer.Write((float)mat[row, col]);
                    }
                }
                break;
            }

            case NodeAttribute.DataType.DT_Bool:
                writer.Write((Byte)((Boolean)attr.Value ? 1 : 0));
                break;

            case NodeAttribute.DataType.DT_String:
            case NodeAttribute.DataType.DT_Path:
            case NodeAttribute.DataType.DT_FixedString:
            case NodeAttribute.DataType.DT_LSString:
                WriteString((string)attr.Value, true);
                break;

            case NodeAttribute.DataType.DT_WString:
            case NodeAttribute.DataType.DT_LSWString:
                WriteWideString((string)attr.Value, true);
                break;

            case NodeAttribute.DataType.DT_TranslatedString:
                var str = (TranslatedString)attr.Value;
                WriteString(str.Value, true);
                WriteString(str.Handle, true);
                break;

            case NodeAttribute.DataType.DT_ULongLong:
                writer.Write((UInt64)attr.Value);
                break;

            case NodeAttribute.DataType.DT_ScratchBuffer:
                var buffer = (byte[])attr.Value;
                writer.Write((UInt32)buffer.Length);
                writer.Write(buffer);
                break;

            case NodeAttribute.DataType.DT_Long:
                writer.Write((Int64)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Int8:
                writer.Write((SByte)attr.Value);
                break;

            default:
                throw new InvalidFormatException(String.Format("WriteAttribute() not implemented for type {0}", attr.Type));
            }
        }
Exemplo n.º 2
0
        public static void WriteAttribute(BinaryWriter writer, NodeAttribute attr)
        {
            switch (attr.Type)
            {
            case NodeAttribute.DataType.DT_None:
                break;

            case NodeAttribute.DataType.DT_Byte:
                writer.Write((Byte)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Short:
                writer.Write((Int16)attr.Value);
                break;

            case NodeAttribute.DataType.DT_UShort:
                writer.Write((UInt16)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Int:
                writer.Write((Int32)attr.Value);
                break;

            case NodeAttribute.DataType.DT_UInt:
                writer.Write((UInt32)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Float:
                writer.Write((float)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Double:
                writer.Write((Double)attr.Value);
                break;

            case NodeAttribute.DataType.DT_IVec2:
            case NodeAttribute.DataType.DT_IVec3:
            case NodeAttribute.DataType.DT_IVec4:
                foreach (var item in (int[])attr.Value)
                {
                    writer.Write(item);
                }
                break;

            case NodeAttribute.DataType.DT_Vec2:
            case NodeAttribute.DataType.DT_Vec3:
            case NodeAttribute.DataType.DT_Vec4:
                foreach (var item in (float[])attr.Value)
                {
                    writer.Write(item);
                }
                break;

            case NodeAttribute.DataType.DT_Mat2:
            case NodeAttribute.DataType.DT_Mat3:
            case NodeAttribute.DataType.DT_Mat3x4:
            case NodeAttribute.DataType.DT_Mat4x3:
            case NodeAttribute.DataType.DT_Mat4:
            {
                var mat = (Matrix)attr.Value;
                for (int col = 0; col < mat.cols; col++)
                {
                    for (int row = 0; row < mat.rows; row++)
                    {
                        writer.Write((float)mat[row, col]);
                    }
                }
                break;
            }

            case NodeAttribute.DataType.DT_Bool:
                writer.Write((Byte)((Boolean)attr.Value ? 1 : 0));
                break;

            case NodeAttribute.DataType.DT_ULongLong:
                writer.Write((UInt64)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Long:
                writer.Write((Int64)attr.Value);
                break;

            case NodeAttribute.DataType.DT_Int8:
                writer.Write((SByte)attr.Value);
                break;

            case NodeAttribute.DataType.DT_UUID:
                writer.Write(((Guid)attr.Value).ToByteArray());
                break;

            default:
                throw new InvalidFormatException(String.Format("WriteAttribute() not implemented for type {0}", attr.Type));
            }
        }
Exemplo n.º 3
0
        public static NodeAttribute ReadAttribute(NodeAttribute.DataType type, BinaryReader reader)
        {
            var attr = new NodeAttribute(type);

            switch (type)
            {
            case NodeAttribute.DataType.DT_None:
                break;

            case NodeAttribute.DataType.DT_Byte:
                attr.Value = reader.ReadByte();
                break;

            case NodeAttribute.DataType.DT_Short:
                attr.Value = reader.ReadInt16();
                break;

            case NodeAttribute.DataType.DT_UShort:
                attr.Value = reader.ReadUInt16();
                break;

            case NodeAttribute.DataType.DT_Int:
                attr.Value = reader.ReadInt32();
                break;

            case NodeAttribute.DataType.DT_UInt:
                attr.Value = reader.ReadUInt32();
                break;

            case NodeAttribute.DataType.DT_Float:
                attr.Value = reader.ReadSingle();
                break;

            case NodeAttribute.DataType.DT_Double:
                attr.Value = reader.ReadDouble();
                break;

            case NodeAttribute.DataType.DT_IVec2:
            case NodeAttribute.DataType.DT_IVec3:
            case NodeAttribute.DataType.DT_IVec4:
            {
                int columns = attr.GetColumns();
                var vec     = new int[columns];
                for (int i = 0; i < columns; i++)
                {
                    vec[i] = reader.ReadInt32();
                }
                attr.Value = vec;
                break;
            }

            case NodeAttribute.DataType.DT_Vec2:
            case NodeAttribute.DataType.DT_Vec3:
            case NodeAttribute.DataType.DT_Vec4:
            {
                int columns = attr.GetColumns();
                var vec     = new float[columns];
                for (int i = 0; i < columns; i++)
                {
                    vec[i] = reader.ReadSingle();
                }
                attr.Value = vec;
                break;
            }

            case NodeAttribute.DataType.DT_Mat2:
            case NodeAttribute.DataType.DT_Mat3:
            case NodeAttribute.DataType.DT_Mat3x4:
            case NodeAttribute.DataType.DT_Mat4x3:
            case NodeAttribute.DataType.DT_Mat4:
            {
                int columns = attr.GetColumns();
                int rows    = attr.GetRows();
                var mat     = new Matrix(rows, columns);
                attr.Value = mat;

                for (int col = 0; col < columns; col++)
                {
                    for (int row = 0; row < rows; row++)
                    {
                        mat[row, col] = reader.ReadSingle();
                    }
                }
                break;
            }

            case NodeAttribute.DataType.DT_Bool:
                attr.Value = reader.ReadByte() != 0;
                break;

            case NodeAttribute.DataType.DT_ULongLong:
                attr.Value = reader.ReadUInt64();
                break;

            case NodeAttribute.DataType.DT_Long:
                attr.Value = reader.ReadInt64();
                break;

            case NodeAttribute.DataType.DT_Int8:
                attr.Value = reader.ReadSByte();
                break;

            case NodeAttribute.DataType.DT_UUID:
                attr.Value = new Guid(reader.ReadBytes(16));
                break;

            default:
                // Strings are serialized differently for each file format and should be
                // handled by the format-specific ReadAttribute()
                throw new InvalidFormatException(String.Format("ReadAttribute() not implemented for type {0}", type));
            }

            return(attr);
        }
Exemplo n.º 4
0
        private NodeAttribute ReadAttribute(NodeAttribute.DataType type)
        {
            var attr = new NodeAttribute(type);

            switch (type)
            {
            case NodeAttribute.DataType.DT_None:
                break;

            case NodeAttribute.DataType.DT_Byte:
                attr.Value = reader.ReadByte();
                break;

            case NodeAttribute.DataType.DT_Short:
                attr.Value = reader.ReadInt16();
                break;

            case NodeAttribute.DataType.DT_UShort:
                attr.Value = reader.ReadUInt16();
                break;

            case NodeAttribute.DataType.DT_Int:
                attr.Value = reader.ReadInt32();;
                break;

            case NodeAttribute.DataType.DT_UInt:
                attr.Value = reader.ReadUInt32();
                break;

            case NodeAttribute.DataType.DT_Float:
                attr.Value = reader.ReadSingle();
                break;

            case NodeAttribute.DataType.DT_Double:
                attr.Value = reader.ReadDouble();
                break;

            case NodeAttribute.DataType.DT_IVec2:
            case NodeAttribute.DataType.DT_IVec3:
            case NodeAttribute.DataType.DT_IVec4:
            {
                int columns = attr.GetColumns();
                var vec     = new int[columns];
                for (int i = 0; i < columns; i++)
                {
                    vec[i] = reader.ReadInt32();
                }
                attr.Value = vec;
                break;
            }

            case NodeAttribute.DataType.DT_Vec2:
            case NodeAttribute.DataType.DT_Vec3:
            case NodeAttribute.DataType.DT_Vec4:
            {
                int columns = attr.GetColumns();
                var vec     = new float[columns];
                for (int i = 0; i < columns; i++)
                {
                    vec[i] = reader.ReadSingle();
                }
                attr.Value = vec;
                break;
            }

            case NodeAttribute.DataType.DT_Mat2:
            case NodeAttribute.DataType.DT_Mat3:
            case NodeAttribute.DataType.DT_Mat3x4:
            case NodeAttribute.DataType.DT_Mat4x3:
            case NodeAttribute.DataType.DT_Mat4:
            {
                int columns = attr.GetColumns();
                int rows    = attr.GetRows();
                var mat     = new Matrix(rows, columns);
                attr.Value = mat;

                for (int col = 0; col < columns; col++)
                {
                    for (int row = 0; row < rows; row++)
                    {
                        mat[row, col] = reader.ReadSingle();
                    }
                }
                break;
            }

            case NodeAttribute.DataType.DT_Bool:
                attr.Value = reader.ReadByte() != 0;
                break;

            case NodeAttribute.DataType.DT_String:
            case NodeAttribute.DataType.DT_Path:
            case NodeAttribute.DataType.DT_FixedString:
            case NodeAttribute.DataType.DT_LSString:
                attr.Value = ReadString(true);
                break;

            case NodeAttribute.DataType.DT_WString:
            case NodeAttribute.DataType.DT_LSWString:
                attr.Value = ReadWideString(true);
                break;

            case NodeAttribute.DataType.DT_TranslatedString:
                var str = new TranslatedString();
                str.Value  = ReadString(true);
                str.Handle = ReadString(true);
                attr.Value = str;
                break;

            case NodeAttribute.DataType.DT_ULongLong:
                attr.Value = reader.ReadUInt64();
                break;

            case NodeAttribute.DataType.DT_ScratchBuffer:
                var bufferLength = reader.ReadInt32();
                attr.Value = reader.ReadBytes(bufferLength);
                break;

            case NodeAttribute.DataType.DT_Long:
                attr.Value = reader.ReadInt64();
                break;

            case NodeAttribute.DataType.DT_Int8:
                attr.Value = reader.ReadSByte();
                break;

            default:
                throw new InvalidFormatException(String.Format("ReadAttribute() not implemented for type {0}", type));
            }

            return(attr);
        }
Exemplo n.º 5
0
        private NodeAttribute ReadAttribute(NodeAttribute.DataType type)
        {
            switch (type)
            {
                case NodeAttribute.DataType.DT_String:
                case NodeAttribute.DataType.DT_Path:
                case NodeAttribute.DataType.DT_FixedString:
                case NodeAttribute.DataType.DT_LSString:
                    {
                        var attr = new NodeAttribute(type);
                        attr.Value = ReadString(true);
                        return attr;
                    }

                case NodeAttribute.DataType.DT_WString:
                case NodeAttribute.DataType.DT_LSWString:
                    {
                        var attr = new NodeAttribute(type);
                        attr.Value = ReadWideString(true);
                        return attr;
                    }

                case NodeAttribute.DataType.DT_TranslatedString:
                    {
                        var attr = new NodeAttribute(type);
                        var str = new TranslatedString();
                        str.Value = ReadString(true);
                        str.Handle = ReadString(true);
                        attr.Value = str;
                        return attr;
                    }

                case NodeAttribute.DataType.DT_ScratchBuffer:
                    {
                        var attr = new NodeAttribute(type);
                        var bufferLength = reader.ReadInt32();
                        attr.Value = reader.ReadBytes(bufferLength);
                        return attr;
                    }

                default:
                    return BinUtils.ReadAttribute(type, reader);
            }
        }
Exemplo n.º 6
0
        private NodeAttribute ReadAttribute(JsonReader reader)
        {
            string key = "", handle = null;
            List <TranslatedFSStringArgument> fsStringArguments = null;
            NodeAttribute attribute = null;

            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.EndObject)
                {
                    break;
                }
                else if (reader.TokenType == JsonToken.PropertyName)
                {
                    key = reader.Value.ToString();
                }
                else if (reader.TokenType == JsonToken.String ||
                         reader.TokenType == JsonToken.Integer ||
                         reader.TokenType == JsonToken.Float ||
                         reader.TokenType == JsonToken.Boolean)
                {
                    if (key == "type")
                    {
                        var type = (NodeAttribute.DataType)Convert.ToUInt32(reader.Value);
                        attribute = new NodeAttribute(type);
                    }
                    else if (key == "value")
                    {
                        switch (attribute.Type)
                        {
                        case NodeAttribute.DataType.DT_Byte:
                            attribute.Value = Convert.ToByte(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_Short:
                            attribute.Value = Convert.ToInt16(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_UShort:
                            attribute.Value = Convert.ToUInt16(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_Int:
                            attribute.Value = Convert.ToInt32(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_UInt:
                            attribute.Value = Convert.ToUInt32(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_Float:
                            attribute.Value = Convert.ToSingle(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_Double:
                            attribute.Value = Convert.ToDouble(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_Bool:
                            attribute.Value = Convert.ToBoolean(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_String:
                        case NodeAttribute.DataType.DT_Path:
                        case NodeAttribute.DataType.DT_FixedString:
                        case NodeAttribute.DataType.DT_LSString:
                        case NodeAttribute.DataType.DT_WString:
                        case NodeAttribute.DataType.DT_LSWString:
                            attribute.Value = reader.Value.ToString();
                            break;

                        case NodeAttribute.DataType.DT_ULongLong:
                            if (reader.Value.GetType() == typeof(System.Int64))
                            {
                                attribute.Value = Convert.ToUInt64((long)reader.Value);
                            }
                            else if (reader.Value.GetType() == typeof(BigInteger))
                            {
                                attribute.Value = (ulong)((BigInteger)reader.Value);
                            }
                            else
                            {
                                attribute.Value = (ulong)reader.Value;
                            }
                            break;

                        // TODO: Not sure if this is the correct format
                        case NodeAttribute.DataType.DT_ScratchBuffer:
                            attribute.Value = Convert.FromBase64String(reader.Value.ToString());
                            break;

                        case NodeAttribute.DataType.DT_Long:
                        case NodeAttribute.DataType.DT_Int64:
                            attribute.Value = Convert.ToInt64(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_Int8:
                            attribute.Value = Convert.ToSByte(reader.Value);
                            break;

                        case NodeAttribute.DataType.DT_TranslatedString:
                        {
                            if (attribute.Value == null)
                            {
                                attribute.Value = new TranslatedString();
                            }

                            var ts = (TranslatedString)attribute.Value;
                            ts.Value  = reader.Value.ToString();
                            ts.Handle = handle;
                            break;
                        }

                        case NodeAttribute.DataType.DT_TranslatedFSString:
                        {
                            var fsString = new TranslatedFSString();
                            fsString.Value     = reader.Value.ToString();
                            fsString.Handle    = handle;
                            fsString.Arguments = fsStringArguments;
                            attribute.Value    = fsString;
                            break;
                        }

                        case NodeAttribute.DataType.DT_UUID:
                            attribute.Value = new Guid(reader.Value.ToString());
                            break;

                        case NodeAttribute.DataType.DT_IVec2:
                        case NodeAttribute.DataType.DT_IVec3:
                        case NodeAttribute.DataType.DT_IVec4:
                        {
                            string[] nums   = reader.Value.ToString().Split(' ');
                            int      length = attribute.GetColumns();
                            if (length != nums.Length)
                            {
                                throw new FormatException(String.Format("A vector of length {0} was expected, got {1}", length, nums.Length));
                            }

                            int[] vec = new int[length];
                            for (int i = 0; i < length; i++)
                            {
                                vec[i] = int.Parse(nums[i]);
                            }

                            attribute.Value = vec;
                            break;
                        }

                        case NodeAttribute.DataType.DT_Vec2:
                        case NodeAttribute.DataType.DT_Vec3:
                        case NodeAttribute.DataType.DT_Vec4:
                        {
                            string[] nums   = reader.Value.ToString().Split(' ');
                            int      length = attribute.GetColumns();
                            if (length != nums.Length)
                            {
                                throw new FormatException(String.Format("A vector of length {0} was expected, got {1}", length, nums.Length));
                            }

                            float[] vec = new float[length];
                            for (int i = 0; i < length; i++)
                            {
                                vec[i] = float.Parse(nums[i]);
                            }

                            attribute.Value = vec;
                            break;
                        }

                        case NodeAttribute.DataType.DT_Mat2:
                        case NodeAttribute.DataType.DT_Mat3:
                        case NodeAttribute.DataType.DT_Mat3x4:
                        case NodeAttribute.DataType.DT_Mat4x3:
                        case NodeAttribute.DataType.DT_Mat4:
                            var mat = Matrix.Parse(reader.Value.ToString());
                            if (mat.cols != attribute.GetColumns() || mat.rows != attribute.GetRows())
                            {
                                throw new FormatException("Invalid column/row count for matrix");
                            }
                            attribute.Value = mat;
                            break;

                        case NodeAttribute.DataType.DT_None:
                        default:
                            throw new NotImplementedException("Don't know how to unserialize type " + attribute.Type.ToString());
                        }
                    }
                    else if (key == "handle")
                    {
                        if (attribute != null && attribute.Type == NodeAttribute.DataType.DT_TranslatedString)
                        {
                            if (attribute.Value == null)
                            {
                                attribute.Value = new TranslatedString();
                            }

                            var ts = (TranslatedString)attribute.Value;
                            ts.Handle = reader.Value.ToString();
                        }
                        else
                        {
                            handle = reader.Value.ToString();
                        }
                    }
                    else if (key == "version")
                    {
                        if (attribute.Value == null)
                        {
                            attribute.Value = new TranslatedString();
                        }

                        var ts = (TranslatedString)attribute.Value;
                        ts.Version = UInt16.Parse(reader.Value.ToString());
                    }
                    else
                    {
                        throw new InvalidDataException("Unknown property encountered during attribute parsing: " + key);
                    }
                }
                else if (reader.TokenType == JsonToken.StartArray && key == "arguments")
                {
                    var args = ReadFSStringArguments(reader);

                    if (attribute.Value != null)
                    {
                        var fs = ((TranslatedFSString)attribute.Value);
                        fs.Arguments = args;
                    }
                    else
                    {
                        fsStringArguments = args;
                    }
                }
                else
                {
                    throw new InvalidDataException("Unexpected JSON token during parsing of attribute: " + reader.TokenType);
                }
            }

            return(attribute);
        }
Exemplo n.º 7
0
        public Resource Read()
        {
            using (this.reader = XmlReader.Create(stream))
            {
                Resource    rsrc          = new Resource();
                Region      currentRegion = null;
                List <Node> stack         = new List <Node>();

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        switch (reader.Name)
                        {
                        case "save":
                            // Root element
                            if (stack.Count() > 0)
                            {
                                throw new InvalidFormatException("Node <save> was unexpected.");
                            }
                            break;

                        case "header":
                            // LSX metadata part 1
                            rsrc.Metadata.Timestamp = Convert.ToUInt64(reader["time"]);
                            break;

                        case "version":
                            // LSX metadata part 2
                            rsrc.Metadata.MajorVersion = Convert.ToUInt32(reader["major"]);
                            rsrc.Metadata.MinorVersion = Convert.ToUInt32(reader["minor"]);
                            rsrc.Metadata.Revision     = Convert.ToUInt32(reader["revision"]);
                            rsrc.Metadata.BuildNumber  = Convert.ToUInt32(reader["build"]);
                            Version = rsrc.Metadata.MajorVersion;
                            break;

                        case "region":
                            if (currentRegion != null)
                            {
                                throw new InvalidFormatException("A <region> can only start at the root level of a resource.");
                            }

                            Debug.Assert(!reader.IsEmptyElement);
                            var region = new Region();
                            region.RegionName = reader["id"];
                            Debug.Assert(region.RegionName != null);
                            rsrc.Regions.Add(region.RegionName, region);
                            currentRegion = region;
                            break;

                        case "node":
                            if (currentRegion == null)
                            {
                                throw new InvalidFormatException("A <node> must be located inside a region.");
                            }

                            Node node;
                            if (stack.Count() == 0)
                            {
                                // The node is the root node of the region
                                node = currentRegion;
                            }
                            else
                            {
                                // New node under the current parent
                                node        = new Node();
                                node.Parent = stack.Last();
                            }

                            node.Name = reader["id"];
                            Debug.Assert(node.Name != null);
                            if (node.Parent != null)
                            {
                                node.Parent.AppendChild(node);
                            }

                            if (!reader.IsEmptyElement)
                            {
                                stack.Add(node);
                            }
                            break;

                        case "attribute":
                            UInt32 attrTypeId;
                            if (Version >= 4)
                            {
                                attrTypeId = (uint)TypeNames[reader["type"]];
                            }
                            else
                            {
                                attrTypeId = Convert.ToUInt32(reader["type"]);
                            }

                            var attrName = reader["id"];
                            if (attrTypeId > (int)NodeAttribute.DataType.DT_Max)
                            {
                                throw new InvalidFormatException(String.Format("Unsupported attribute data type: {0}", attrTypeId));
                            }

                            Debug.Assert(attrName != null);
                            var attr = new NodeAttribute((NodeAttribute.DataType)attrTypeId);

                            var attrValue = reader["value"];
                            if (attrValue != null)
                            {
                                attr.FromString(attrValue);
                            }

                            if (attr.Type == NodeAttribute.DataType.DT_TranslatedString)
                            {
                                if (attr.Value == null)
                                {
                                    attr.Value = new TranslatedString();
                                }

                                var ts = ((TranslatedString)attr.Value);
                                ts.Handle = reader["handle"];
                                Debug.Assert(ts.Handle != null);

                                if (attrValue == null)
                                {
                                    ts.Version = UInt16.Parse(reader["version"]);
                                }
                            }
                            else if (attr.Type == NodeAttribute.DataType.DT_TranslatedFSString)
                            {
                                var fs = ((TranslatedFSString)attr.Value);
                                ReadTranslatedFSString(fs);
                            }

                            stack.Last().Attributes.Add(attrName, attr);
                            break;

                        case "children":
                            // Child nodes are handled in the "node" case
                            break;

                        default:
                            throw new InvalidFormatException(String.Format("Unknown element encountered: {0}", reader.Name));
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        switch (reader.Name)
                        {
                        case "save":
                        case "header":
                        case "version":
                        case "attribute":
                        case "children":
                            // These elements don't change the stack, just discard them
                            break;

                        case "region":
                            Debug.Assert(stack.Count == 0);
                            Debug.Assert(currentRegion != null);
                            Debug.Assert(currentRegion.Name != null);
                            currentRegion = null;
                            break;

                        case "node":
                            stack.RemoveAt(stack.Count - 1);
                            break;

                        default:
                            throw new InvalidFormatException(String.Format("Unknown element encountered: {0}", reader.Name));
                        }
                    }
                }

                return(rsrc);
            }
        }
Exemplo n.º 8
0
        private void WriteAttribute(NodeAttribute attr)
        {
            switch (attr.Type)
            {
                case NodeAttribute.DataType.DT_String:
                case NodeAttribute.DataType.DT_Path:
                case NodeAttribute.DataType.DT_FixedString:
                case NodeAttribute.DataType.DT_LSString:
                    WriteString((string)attr.Value, true);
                    break;

                case NodeAttribute.DataType.DT_WString:
                case NodeAttribute.DataType.DT_LSWString:
                    WriteWideString((string)attr.Value, true);
                    break;

                case NodeAttribute.DataType.DT_TranslatedString:
                    var str = (TranslatedString)attr.Value;
                    WriteString(str.Value, true);
                    WriteString(str.Handle, true);
                    break;

                case NodeAttribute.DataType.DT_ScratchBuffer:
                    var buffer = (byte[])attr.Value;
                    writer.Write((UInt32)buffer.Length);
                    writer.Write(buffer);
                    break;

                default:
                    BinUtils.WriteAttribute(writer, attr);
                    break;
            }
        }
Exemplo n.º 9
0
        public Resource Read()
        {
            using (this.reader = XmlReader.Create(stream))
            {
                Resource rsrc = new Resource();
                Region currentRegion = null;
                List<Node> stack = new List<Node>();

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        switch (reader.Name)
                        {
                            case "save":
                                // Root element
                                if (stack.Count() > 0)
                                    throw new InvalidFormatException("Node <save> was unexpected.");
                                break;

                            case "header":
                                // LSX metadata part 1
                                string version = reader["version"];
                                if (version != InitialVersion && version != CurrentVersion)
                                    throw new InvalidFormatException(String.Format("Unsupported LSX version; expected {0}, found {1}", CurrentVersion, version));

                                rsrc.Metadata.timestamp = Convert.ToUInt64(reader["timestamp"]);
                                break;

                            case "version":
                                // LSX metadata part 2
                                rsrc.Metadata.majorVersion = Convert.ToUInt32(reader["major"]);
                                rsrc.Metadata.minorVersion = Convert.ToUInt32(reader["minor"]);
                                rsrc.Metadata.revision = Convert.ToUInt32(reader["revision"]);
                                rsrc.Metadata.buildNumber = Convert.ToUInt32(reader["build"]);
                                break;

                            case "region":
                                if (currentRegion != null)
                                    throw new InvalidFormatException("A <region> can only start at the root level of a resource.");

                                Debug.Assert(!reader.IsEmptyElement);
                                var region = new Region();
                                region.RegionName = reader["id"];
                                Debug.Assert(region.RegionName != null);
                                rsrc.Regions.Add(region.RegionName, region);
                                currentRegion = region;
                                break;

                            case "node":
                                if (currentRegion == null)
                                    throw new InvalidFormatException("A <node> must be located inside a region.");

                                Node node;
                                if (stack.Count() == 0)
                                {
                                    // The node is the root node of the region
                                    node = currentRegion;
                                }
                                else
                                {
                                    // New node under the current parent
                                    node = new Node();
                                    node.Parent = stack.Last();
                                }

                                node.Name = reader["id"];
                                Debug.Assert(node.Name != null);
                                if (node.Parent != null)
                                    node.Parent.AppendChild(node);

                                if (!reader.IsEmptyElement)
                                    stack.Add(node);
                                break;

                            case "attribute":
                                var attrTypeId = Convert.ToUInt32(reader["type"]);
                                var attrName = reader["id"];
                                var attrValue = reader["value"];
                                if (attrTypeId > (int)NodeAttribute.DataType.DT_Max)
                                    throw new InvalidFormatException(String.Format("Unsupported attribute data type: {0}", attrTypeId));
                                
                                Debug.Assert(attrName != null);
                                Debug.Assert(attrValue != null);
                                var attr = new NodeAttribute((NodeAttribute.DataType)attrTypeId);
                                attr.FromString(attrValue);
                                if (attr.Type == NodeAttribute.DataType.DT_TranslatedString)
                                {
                                    ((TranslatedString)attr.Value).Handle = reader["handle"];
                                    Debug.Assert(((TranslatedString)attr.Value).Handle != null);
                                }

                                stack.Last().Attributes.Add(attrName, attr);
                                break;

                            case "children":
                                // Child nodes are handled in the "node" case
                                break;

                            default:
                                throw new InvalidFormatException(String.Format("Unknown element encountered: {0}", reader.Name));
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        switch (reader.Name)
                        {
                            case "save":
                            case "header":
                            case "version":
                            case "attribute":
                            case "children":
                                // These elements don't change the stack, just discard them
                                break;

                            case "region":
                                Debug.Assert(stack.Count == 0);
                                Debug.Assert(currentRegion != null);
                                Debug.Assert(currentRegion.Name != null);
                                currentRegion = null;
                                break;

                            case "node":
                                stack.RemoveAt(stack.Count - 1);
                                break;

                            default:
                                throw new InvalidFormatException(String.Format("Unknown element encountered: {0}", reader.Name));
                        }
                    }
                }

                return rsrc;
            }
        }
Exemplo n.º 10
0
        private NodeAttribute ReadAttribute(NodeAttribute.DataType type)
        {
            switch (type)
            {
            case NodeAttribute.DataType.DT_String:
            case NodeAttribute.DataType.DT_Path:
            case NodeAttribute.DataType.DT_FixedString:
            case NodeAttribute.DataType.DT_LSString:
            {
                var attr = new NodeAttribute(type);
                attr.Value = ReadString(true);
                return(attr);
            }

            case NodeAttribute.DataType.DT_WString:
            case NodeAttribute.DataType.DT_LSWString:
            {
                var attr = new NodeAttribute(type);
                attr.Value = ReadWideString(true);
                return(attr);
            }

            case NodeAttribute.DataType.DT_TranslatedString:
            {
                var attr = new NodeAttribute(type);
                var str  = new TranslatedString();

                if (IsBG3)
                {
                    str.Version = reader.ReadUInt16();

                    // Sometimes BG3 string keys still contain the value?
                    // Weird heuristic to find these cases
                    var test = reader.ReadUInt16();
                    if (test == 0)
                    {
                        stream.Seek(-4, SeekOrigin.Current);
                        str.Version = 0;
                        str.Value   = ReadString(true);
                    }
                    else
                    {
                        stream.Seek(-2, SeekOrigin.Current);
                        str.Value = null;
                    }
                }
                else
                {
                    str.Version = 0;
                    str.Value   = ReadString(true);
                }

                str.Handle = ReadString(true);
                attr.Value = str;
                return(attr);
            }

            case NodeAttribute.DataType.DT_ScratchBuffer:
            {
                var attr         = new NodeAttribute(type);
                var bufferLength = reader.ReadInt32();
                attr.Value = reader.ReadBytes(bufferLength);
                return(attr);
            }

            // DT_TranslatedFSString not supported in LSB
            default:
                return(BinUtils.ReadAttribute(type, reader));
            }
        }