private void StartEntry(string type, string line, BsbChartReaderState state)
            {
                this.FlushEntry(state);

                this.type = type;
                this.lines.Add(line);
            }
            private void FlushEntry(BsbChartReaderState state)
            {
                if (this.type != null)
                {
                    state.TextEntries.Add(new BsbTextEntry(this.type, this.lines.ToArray()));
                }

                this.Reset();
            }
            public (ReaderState?, bool?) ReadChart(ref SequenceReader <byte> reader, CancellationToken cancellationToken, BsbChartReaderState state)
            {
                if (reader.IsNext(RasterEndToken.Span))
                {
                    reader.Advance(RasterEndToken.Length);

                    if (!this.rowNumber.HasValue)
                    {
                        throw new InvalidOperationException("A raster row should start with a row number.");
                    }

                    state.RowEntries.Add(this.rowNumber.Value, this.entries.ToArray());

                    return(ReaderState.RasterSegment, null);
                }

                if (reader.TryReadVariableLengthValue(out ReadOnlySequence <byte> values))
                {
                    if (this.rowNumber == null)
                    {
                        this.rowNumber = ParseRasterRowNumber(values);
                    }
                    else
                    {
                        if (!state.BitDepth.HasValue)
                        {
                            throw new InvalidOperationException("Bit depth must be parsed before the raster segment.");
                        }

                        this.entries.Add(ParseRasterRun(values, state.BitDepth.Value));
                    }

                    return(null, true);
                }
                else
                {
                    return(null, false);
                }
            }
            public (ReaderState?, bool?) ReadChart(ref SequenceReader <byte> reader, CancellationToken cancellationToken, BsbChartReaderState state)
            {
                if (reader.IsNext(RasterEndToken.Span))
                {
                    reader.Advance(RasterEndToken.Length);

                    return(ReaderState.Done, null);
                }
                else
                {
                    return(ReaderState.RasterRow, null);
                }
            }
            public (ReaderState?, bool?) ReadChart(ref SequenceReader <byte> reader, CancellationToken cancellationToken, BsbChartReaderState state)
            {
                if (reader.TryRead(out byte value))
                {
                    state.BitDepth = value;

                    return(ReaderState.RasterSegment, null);
                }
                else
                {
                    return(null, false);
                }
            }
            public (ReaderState?, bool?) ReadChart(ref SequenceReader <byte> reader, CancellationToken cancellationToken, BsbChartReaderState state)
            {
                if (reader.IsNext(TextSegmentEndToken.Span))
                {
                    reader.Advance(TextSegmentEndToken.Length);

                    this.FlushEntry(state);

                    return(ReaderState.BitDepth, null);
                }

                if (reader.TryReadTo(out ReadOnlySequence <byte> text, TextEntryEndToken.Span))
                {
                    // TODO: Use SequenceReader to extract segments?
                    string line = Encoding.ASCII.GetString(text);

                    if (line.Length > 0)
                    {
                        if (line[0] == '!')
                        {
                            this.StartEntry("!", line.Substring(1), state);
                        }
                        else if (line.StartsWith("    "))
                        {
                            this.lines.Add(line.Substring(4));
                        }
                        else
                        {
                            int index = line.IndexOf('/');

                            if (index >= 0)
                            {
                                this.StartEntry(line.Substring(0, index), line.Substring(index + 1), state);
                            }
                            else
                            {
                                this.StartEntry("?", line, state);
                            }
                        }
                    }

                    return(null, true);
                }
                else
                {
                    return(null, false);
                }
            }