public bool Read() { _reader.EnsureSpace(20); // Check for end (after reading one thing at the root depth) if (_reader.EndOfStream) { TokenType = BionToken.None; return(false); } // Read the marker byte marker = _reader.Buffer[_reader.Index++]; // Identify the token type and length _currentMarker = (BionMarker)marker; _currentLength = LengthLookup[marker]; TokenType = TokenLookup[marker]; if (_currentLength < 0) { _currentLength = LengthIncludingTerminator(); _currentDecodedString = null; _currentCompressedStringStart = _reader.Index; _reader.Index += _currentLength; } else if (_currentLength > 0) { // Read value (non-string) or length (string) _currentDecodedNumber = NumberConverter.ReadSevenBitExplicit(_reader, _currentLength); // Read value (string) if (marker >= 0xF0) { _currentCompressedStringStart = -1; _currentDecodedString = null; _currentLength = (int)_currentDecodedNumber; _reader.EnsureSpace(_currentLength); _currentString = String8.Reference(_reader.Buffer, _reader.Index, _currentLength); _reader.Index += _currentLength; } } else { // Adjust depth (length 0 tokens only) _currentDepth += DepthLookup[marker]; } if (TokenType == BionToken.None) { throw new BionSyntaxException($"Invalid Bion Token 0x{_currentMarker:X2} @{BytesRead:n0}."); } return(true); }
private void DecompressString() { if (_decompressReader == null) { _decompressReader = BufferedReader.FromArray(_reader.Buffer, 0, 0); _decompressWriter = BufferedWriter.ToArray(new byte[1024]); } _decompressReader.ReadSlice(_reader.Buffer, _currentCompressedStringStart, _reader.Index - 1); _decompressWriter.Index = 0; // Decompress the content _compressor.Expand(_decompressReader, _decompressWriter); // Make a String8 referencing the full decompressed value _currentString = String8.Reference(_decompressWriter.Buffer, 0, _decompressWriter.Index); }
private static string SplitAndJoin(string content) { StringBuilder result = new StringBuilder(); byte[] buffer = new byte[content.Length]; using (BufferedReader reader = BufferedReader.FromString(content, ref buffer)) { bool isWord = WordSplitter.IsLetterOrDigit(reader.Buffer[reader.Index]); int length = 0; while (!reader.EndOfStream) { // Read the next word length = WordSplitter.NextWordLength(reader, isWord); String8 word = String8.Reference(reader.Buffer, reader.Index, length); // Set state to read next word reader.Index += length; isWord = !isWord; if (reader.Index < reader.Length || reader.EndOfStream) { // If this is word is definitely complete, write it if (result.Length > 0) { result.Append("|"); } result.Append(word.ToString()); } else if (!reader.EndOfStream) { // Reset state to re-read this word reader.Index -= length; isWord = !isWord; // If end of buffer but not stream, request more reader.EnsureSpace(length * 2); } } } return(result.ToString()); }