public static OTBNode ParseOTBTree(byte[] serializedTreeData) { var treeBuilder = new OTBTreeBuilder(serializedTreeData); for (int i = 0; i < serializedTreeData.Length; i++) { var markupByte = (OTBMarkupByte)serializedTreeData[i]; switch (markupByte) { case OTBMarkupByte.Escape: i++; break; case OTBMarkupByte.Start: treeBuilder.AddNodeBegin(i + 1, OTBNodeType.NotSetYet); break; case OTBMarkupByte.End: treeBuilder.AddNodeEnd(i); break; } } return(treeBuilder.BuildTree()); }
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()); }