Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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());
        }