コード例 #1
0
        private Property.Node DeserializeNode(MemoryStream input)
        {
            var node   = new Property.Node();
            var endian = this.Endian;

            while (true)
            {
                var id         = input.ReadValueU32(endian);
                var type       = input.ReadValueEnum <SectionType>(endian);
                var dataOffset = input.ReadValueS32(endian);
                var nextOffset = input.ReadValueS32(endian);

                switch (type)
                {
                case SectionType.Node:
                {
                    // why? WHY? :(
                    if (dataOffset != -1)
                    {
                        input.Seek(dataOffset, SeekOrigin.Begin);
                        dataOffset = input.ReadValueS32(endian);
                    }

                    if (dataOffset == -1)
                    {
                        node.Nodes.Add(id, new Property.Node());
                    }
                    else
                    {
                        input.Seek(dataOffset, SeekOrigin.Begin);
                        node.Nodes.Add(id, this.DeserializeNode(input));
                    }

                    break;
                }

                case SectionType.Variant:
                {
                    if (dataOffset == -1)
                    {
                        node.Variants.Add(id, null);
                    }
                    else
                    {
                        input.Seek(dataOffset, SeekOrigin.Begin);
                        node.Variants.Add(id, this.DeserializeVariant(input));
                    }

                    break;
                }

                default:
                {
                    throw new FormatException("unknown object section type " +
                                              type.ToString());
                }
                }

                if (nextOffset == -1)
                {
                    break;
                }

                input.Seek(nextOffset, SeekOrigin.Begin);
            }

            return(node);
        }
コード例 #2
0
        private Property.Node DeserializeNode(Stream input)
        {
            var node   = new Property.Node();
            var endian = this.Endian;

            var sectionsHandled = new List <SectionType>();
            var sectionCount    = input.ReadValueU8();

            for (byte i = 0; i < sectionCount; i++)
            {
                var sectionType  = (SectionType)input.ReadValueU16(endian);
                var elementCount = input.ReadValueU16(endian);

                if (sectionsHandled.Contains(sectionType) == true)
                {
                    throw new FormatException();
                }
                sectionsHandled.Add(sectionType);

                switch (sectionType)
                {
                case SectionType.Node:
                {
                    for (ushort j = 0; j < elementCount; j++)
                    {
                        var length = input.ReadValueU32(endian);
                        if (length >= 0x7FFF)
                        {
                            throw new FormatException();
                        }

                        var name = input.ReadString(length, true, Encoding.ASCII);
                        var id   = name.HashJenkins();

                        if (node.KnownNames.ContainsKey(id) == false)
                        {
                            node.KnownNames.Add(id, name);
                        }
                        else if (node.KnownNames[id] != name)
                        {
                            throw new FormatException();
                        }

                        node.Nodes.Add(id, this.DeserializeNode(input));
                    }

                    break;
                }

                case SectionType.Variant:
                {
                    for (ushort j = 0; j < elementCount; j++)
                    {
                        var length = input.ReadValueU32(endian);
                        if (length >= 0x7FFF)
                        {
                            throw new FormatException();
                        }

                        var name = input.ReadString(length, true, Encoding.ASCII);
                        var id   = name.HashJenkins();

                        if (node.KnownNames.ContainsKey(id) == false)
                        {
                            node.KnownNames.Add(id, name);
                        }
                        else if (node.KnownNames[id] != name)
                        {
                            throw new FormatException();
                        }

                        node.Variants.Add(id, this.DeserializeVariant(input));
                    }

                    break;
                }

                case SectionType.Tag:
                {
                    node.Tag = input.ReadString(elementCount, Encoding.ASCII);
                    break;
                }

                case SectionType.NodeByHash:
                {
                    for (ushort j = 0; j < elementCount; j++)
                    {
                        var id = input.ReadValueU32(endian);
                        node.Nodes.Add(id, this.DeserializeNode(input));
                    }

                    break;
                }

                case SectionType.VariantByHash:
                {
                    for (ushort j = 0; j < elementCount; j++)
                    {
                        var id = input.ReadValueU32(endian);
                        node.Variants.Add(id, this.DeserializeVariant(input));
                    }

                    break;
                }

                default:
                {
                    throw new FormatException("unknown object section type " +
                                              sectionType.ToString());
                }
                }
            }

            return(node);
        }
コード例 #3
0
        private void SerializeNode(MemoryStream output, Property.Node node)
        {
            var endian = this.Endian;

            if (node.Tag != null)
            {
                throw new InvalidOperationException("node tags not supported");
            }

            var nodes = new List <KeyValuePair <long, Property.Node> >();

            foreach (var kv in node.Nodes)
            {
                var baseOffset = output.Position;
                output.WriteValueU32(kv.Key, endian);
                output.WriteValueEnum <SectionType>(SectionType.Node, endian);
                output.WriteValueS32(-1, endian);
                output.WriteValueU32((uint)(baseOffset + 16), endian);

                nodes.Add(new KeyValuePair <long, Property.Node>(baseOffset + 8, kv.Value));
            }

            var variants = new List <KeyValuePair <long, Property.IVariant> >();

            foreach (var kv in node.Variants)
            {
                var baseOffset = output.Position;
                output.WriteValueU32(kv.Key, endian);
                output.WriteValueEnum <SectionType>(SectionType.Variant, endian);
                output.WriteValueS32(-1, endian);
                output.WriteValueU32((uint)(baseOffset + 16), endian);

                variants.Add(new KeyValuePair <long, Property.IVariant>(baseOffset + 8, kv.Value));
            }

            output.Seek(-4, SeekOrigin.Current);
            output.WriteValueS32(-1, endian);

            var dataNodes = new List <KeyValuePair <long, Property.Node> >();

            foreach (var kv in nodes)
            {
                if (kv.Value.Nodes.Count == 0 &&
                    kv.Value.Variants.Count == 0)
                {
                    continue;
                }

                var baseOffset = output.Position;

                dataNodes.Add(new KeyValuePair <long, Property.Node>(output.Position, kv.Value));
                output.Seek(4, SeekOrigin.Current);

                var nextOffset = output.Position;

                output.Position = kv.Key;
                output.WriteValueU32((uint)baseOffset, endian);

                output.Position = nextOffset;
            }

            //output.Position = output.Position.Align(16);

            foreach (var kv in variants)
            {
                if (kv.Value != null)
                {
                    var baseOffset = output.Position;
                    this.SerializeVariant(output, kv.Value);

                    var nextOffset = output.Position;

                    output.Position = kv.Key;
                    output.WriteValueU32((uint)baseOffset, endian);

                    output.Position = nextOffset.Align(4);
                    //output.Position = nextOffset.Align(16);
                }
            }

            foreach (var kv in dataNodes)
            {
                var baseOffset = output.Position;
                this.SerializeNode(output, kv.Value);

                var nextOffset = output.Position;

                output.Position = kv.Key;
                output.WriteValueU32((uint)baseOffset, endian);

                output.Position = nextOffset;
            }
        }
コード例 #4
0
        private void SerializeNode(Stream output, Property.Node node)
        {
            var endian = this.Endian;

            byte count = 0;

            var nodesByName = node.Nodes
                              .Where(kv => node.KnownNames.ContainsKey(kv.Key) == true)
                              .ToArray();

            var variantsByName = node.Variants
                                 .Where(kv => node.KnownNames.ContainsKey(kv.Key) == true)
                                 .ToArray();

            var nodesByHash = node.Nodes
                              .Where(kv => node.KnownNames.ContainsKey(kv.Key) == false)
                              .ToArray();

            var variantsByHash = node.Variants
                                 .Where(kv => node.KnownNames.ContainsKey(kv.Key) == false)
                                 .ToArray();

            if (nodesByName.Length > 0)
            {
                count++;
            }

            if (variantsByName.Length > 0)
            {
                count++;
            }

            if (nodesByHash.Length > 0)
            {
                count++;
            }

            if (variantsByHash.Length > 0)
            {
                count++;
            }

            if (node.Tag != null)
            {
                count++;
            }

            output.WriteValueU8(count);

            if (nodesByName.Length > 0)
            {
                if (nodesByName.Length > 0xFFFF)
                {
                    throw new InvalidOperationException();
                }

                output.WriteValueU16((ushort)SectionType.Node, endian);
                output.WriteValueU16((ushort)nodesByName.Length, endian);
                foreach (var kv in nodesByName)
                {
                    var name = node.KnownNames[kv.Key];
                    output.WriteValueS32(name.Length, endian);
                    output.WriteString(name, Encoding.ASCII);
                    this.SerializeNode(output, kv.Value);
                }
            }

            if (variantsByName.Length > 0)
            {
                if (variantsByName.Length > 0xFFFF)
                {
                    throw new InvalidOperationException();
                }

                output.WriteValueU16((ushort)SectionType.Variant, endian);
                output.WriteValueU16((ushort)variantsByName.Length, endian);
                foreach (var kv in variantsByName)
                {
                    var name = node.KnownNames[kv.Key];
                    output.WriteValueS32(name.Length, endian);
                    output.WriteString(name, Encoding.ASCII);
                    this.SerializeVariant(output, kv.Value);
                }
            }

            if (node.Tag != null)
            {
                var bytes = Encoding.ASCII.GetBytes(node.Tag);

                if (bytes.Length > 0xFFFF)
                {
                    throw new InvalidOperationException();
                }

                output.WriteValueU16(3, endian);
                output.WriteValueU16((ushort)bytes.Length, endian);
                output.WriteBytes(bytes);
            }

            if (nodesByHash.Length > 0)
            {
                if (nodesByHash.Length > 0xFFFF)
                {
                    throw new InvalidOperationException();
                }

                output.WriteValueU16((ushort)SectionType.NodeByHash, endian);
                output.WriteValueU16((ushort)nodesByHash.Length, endian);
                foreach (var kv in nodesByHash)
                {
                    output.WriteValueU32(kv.Key, endian);
                    this.SerializeNode(output, kv.Value);
                }
            }

            if (variantsByHash.Length > 0)
            {
                if (variantsByHash.Length > 0xFFFF)
                {
                    throw new InvalidOperationException();
                }

                output.WriteValueU16((ushort)SectionType.VariantByHash, endian);
                output.WriteValueU16((ushort)variantsByHash.Length, endian);
                foreach (var kv in variantsByHash)
                {
                    output.WriteValueU32(kv.Key, endian);
                    this.SerializeVariant(output, kv.Value);
                }
            }
        }