Exemple #1
0
        private void WriteStringValue(BionToken markerType, string value)
        {
            if (value == null)
            {
                WriteNull();
                return;
            }

            if (_compressor == null)
            {
                int length = Encoding.UTF8.GetByteCount(value);

                // Write marker and length
                WriteStringLength(markerType, length);

                // Encode and writer value
                _writer.EnsureSpace(length);
                Encoding.UTF8.GetBytes(value, 0, value.Length, _writer.Buffer, _writer.Index);
                _writer.Index += length;
            }
            else
            {
                // Write marker for compressed, terminated value
                Write((byte)(markerType == BionToken.String ? BionMarker.StringCompressedTerminated : BionMarker.PropertyNameCompressedTerminated));

                // Compress and write value
                using (BufferedReader reader = BufferedReader.FromString(value, ref _stringConvertBuffer))
                {
                    _compressor.Compress(reader, _writer);
                }

                // Write end token
                Write(BionMarker.EndValue);
            }
        }
Exemple #2
0
        private void WriteStringLength(BionToken marker, int stringLength)
        {
            int lengthOfLength;
            int markerAdjustment;

            if (stringLength <= MaxOneByteLength)
            {
                lengthOfLength   = 1;
                markerAdjustment = -2;
            }
            else if (stringLength <= MaxTwoByteLength)
            {
                lengthOfLength   = 2;
                markerAdjustment = -1;
            }
            else
            {
                lengthOfLength   = 5;
                markerAdjustment = 0;
            }

            _writer.EnsureSpace(lengthOfLength + 1);
            int index = _writer.Index++;

            NumberConverter.WriteSevenBitFixed(_writer, (ulong)stringLength, lengthOfLength);
            _writer.Buffer[index] = (byte)((int)marker + markerAdjustment);
        }
Exemple #3
0
        private void WriteStringValue(BionToken markerType, String8 value)
        {
            if (_compressor == null)
            {
                // Write marker and length
                WriteStringLength(markerType, value.Length);

                // Write value
                _writer.EnsureSpace(value.Length);
                value.CopyTo(_writer.Buffer, _writer.Index);
                _writer.Index += value.Length;
            }
            else
            {
                // Write marker for compressed, terminated value
                Write((byte)(markerType == BionToken.String ? BionMarker.StringCompressedTerminated : BionMarker.PropertyNameCompressedTerminated));

                // Compress and write value
                using (BufferedReader reader = BufferedReader.FromString(value))
                {
                    _compressor.Compress(reader, _writer);
                }

                // Write end token
                Write(BionMarker.EndValue);
            }
        }
Exemple #4
0
 public void Expect(BionToken expected)
 {
     if (this.TokenType != expected)
     {
         throw new BionSyntaxException(this, expected);
     }
 }
Exemple #5
0
        public bool Read(BionToken expected)
        {
            bool result = Read();

            Expect(expected);
            return(result);
        }
Exemple #6
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);
        }
        private static void Expect(BionReader reader, BionToken requiredToken, string parseContext)
        {
            if (reader.TokenType == BionToken.None)
            {
                reader.Read();
            }

            if (reader.TokenType != requiredToken)
            {
                throw new IOException($"Reader found invalid token type '{requiredToken}' while parsing {parseContext}.");
            }

            reader.Read();
        }
 public BionSyntaxException(BionReader reader, BionToken expected)
     : this($"@{reader.BytesRead:n0}, expected {expected} but found {reader.TokenType}.")
 {
 }