Exemplo n.º 1
0
        private void ExtractTree()
        {
            var stream = new ReadOnlyMemoryStream(_serializedTreeData);

            stream.Skip(4);             // Skip indentifier
            while (!stream.IsOver)
            {
                var currentMark = (OTBMarkupByte)stream.ReadByte();
                if (currentMark < OTBMarkupByte.Escape)
                {
                    // What is under Escape = 0xFD is just prop data. Just skip
                    continue;
                }

                switch (currentMark)
                {
                case OTBMarkupByte.Start:
                    var nodeType = (OTBNodeType)stream.ReadByte();
                    AddNodeBegin(stream.Position, nodeType);
                    break;

                case OTBMarkupByte.End:
                    AddNodeEnd(stream.Position);
                    break;

                case OTBMarkupByte.Escape:
                    stream.Skip();
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
        }
Exemplo n.º 2
0
        private static OTBNode ExtractOTBTree(byte[] serializedWorldData)
        {
            var stream = new ReadOnlyMemoryStream(serializedWorldData);

            // Skipping the first 4 bytes coz they are used to store a... identifier?
            stream.Skip(IdentifierLength);

            var treeBuilder = new OTBTreeBuilder(serializedWorldData);

            while (!stream.IsOver)
            {
                var currentMark = (OTBMarkupByte)stream.ReadByte();
                if (currentMark < OTBMarkupByte.Escape)
                {
                    /// Since <see cref="OTBMarkupByte"/> can only have values Escape (0xFD), Start (0xFE) and
                    /// End (0xFF), if currentMark < Escape, then it's just prop data
                    /// and we can safely skip it.
                    continue;
                }

                var nodeType = (OTBNodeType)stream.ReadByte();

                switch (currentMark)
                {
                case OTBMarkupByte.Start:
                    treeBuilder.AddNodeBegin(
                        start: stream.Position,
                        type: nodeType);
                    break;

                case OTBMarkupByte.End:
                    treeBuilder.AddNodeEnd(stream.Position);
                    break;

                case OTBMarkupByte.Escape:
                    stream.Skip();
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            return(treeBuilder.BuildTree());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Parses data serialized as .otb and returns the deserialized .otb tree structure.
        /// </summary>
        /// <remarks>
        /// Beware that some .otb serializers add a "format identifier" before the data.
        /// Maps (worlds?), for instance, contain 4 "format identifier bytes" that should be skiped.
        /// </remarks>
        public static OTBNode DeserializeOTBData(ReadOnlyMemory <byte> serializedOTBData, int skipFirstBytes)
        {
            if (skipFirstBytes < 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            var relevantData = serializedOTBData.Slice(skipFirstBytes);
            var stream       = new ReadOnlyMemoryStream(serializedOTBData);

            var treeBuilder = new OTBTreeBuilder(serializedOTBData);

            while (!stream.IsOver)
            {
                var currentMark = (OTBMarkupByte)stream.ReadByte();
                if (currentMark < OTBMarkupByte.Escape)
                {
                    // Since <see cref="OTBMarkupByte"/> can only have values Escape (0xFD), Start (0xFE) and
                    // End (0xFF), if currentMark < Escape, then it's just prop data
                    // and we can safely skip it.
                    continue;
                }

                switch (currentMark)
                {
                case OTBMarkupByte.Start:
                    var nodeType = (OTBNodeType)stream.ReadByte();
                    treeBuilder.AddNodeDataBegin(
                        start: stream.Position,
                        type: nodeType);
                    break;

                case OTBMarkupByte.End:
                    treeBuilder.AddNodeEnd(stream.Position - 1);
                    break;

                case OTBMarkupByte.Escape:
                    stream.Skip();
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            return(treeBuilder.BuildTree());
        }