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); } }
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); }
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); } }
public void Expect(BionToken expected) { if (this.TokenType != expected) { throw new BionSyntaxException(this, expected); } }
public bool Read(BionToken expected) { bool result = Read(); Expect(expected); return(result); }
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}.") { }