/// <summary> /// Gets the string value from the binary reader. /// </summary> /// <param name="stringToken">The buffer that has the string.</param> /// <param name="jsonStringDictionary">The JSON string dictionary.</param> /// <returns>A string value from the binary reader.</returns> public static string GetStringValue( Utf8Memory stringToken, IReadOnlyJsonStringDictionary jsonStringDictionary) { if (stringToken.IsEmpty) { throw new JsonInvalidTokenException(); } if (JsonBinaryEncoding.TryGetBufferedLengthPrefixedString( stringToken, out Utf8Memory lengthPrefixedString)) { return(lengthPrefixedString.ToString()); } if (JsonBinaryEncoding.TryGetEncodedStringValue( stringToken.Span, jsonStringDictionary, out UtfAllString encodedStringValue)) { return(encodedStringValue.Utf16String); } throw new JsonInvalidTokenException(); }
public JsonBinaryReader( ReadOnlyMemory <byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary = null) { if (buffer.Length < 2) { throw new ArgumentException($"{nameof(buffer)} must have at least two byte."); } if (buffer.Span[0] != (byte)JsonSerializationFormat.Binary) { throw new ArgumentNullException("buffer must be binary encoded."); } // offset for the 0x80 (128) binary serialization type marker. buffer = buffer.Slice(1); // Only navigate the outer most json value and trim off trailing bytes int jsonValueLength = JsonBinaryEncoding.GetValueLength(buffer.Span); if (buffer.Length < jsonValueLength) { throw new ArgumentException("buffer is shorter than the length prefix."); } buffer = buffer.Slice(0, jsonValueLength); this.jsonBinaryBuffer = new JsonBinaryMemoryReader(buffer); this.arrayAndObjectEndStack = new Stack <int>(); this.jsonStringDictionary = jsonStringDictionary; }
/// <summary> /// Initializes a new instance of the JsonBinaryNavigator class /// </summary> /// <param name="buffer">The (UTF-8) buffer to navigate.</param> /// <param name="jsonStringDictionary">The JSON string dictionary.</param> public JsonBinaryNavigator( ReadOnlyMemory <byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary) { if (buffer.Length < 2) { throw new ArgumentException($"{nameof(buffer)} must have at least two byte."); } if (buffer.Span[0] != (byte)JsonSerializationFormat.Binary) { throw new ArgumentNullException("buffer must be binary encoded."); } // offset for the 0x80 (128) binary serialization type marker. buffer = buffer.Slice(1); // Only navigate the outer most json value and trim off trailing bytes int jsonValueLength = JsonBinaryEncoding.GetValueLength(buffer.Span); if (buffer.Length < jsonValueLength) { throw new ArgumentException("buffer is shorter than the length prefix."); } buffer = buffer.Slice(0, jsonValueLength); this.buffer = buffer; this.jsonStringDictionary = jsonStringDictionary; this.rootNode = new BinaryNavigatorNode(this.buffer, JsonBinaryEncoding.NodeTypes.GetNodeType(this.buffer.Span[0])); }
public static bool TryGetBufferedStringValue( Utf8Memory stringToken, IReadOnlyJsonStringDictionary jsonStringDictionary, out Utf8Memory value) { if (stringToken.IsEmpty) { value = default; return(false); } if (JsonBinaryEncoding.TryGetBufferedLengthPrefixedString( stringToken, out value)) { return(true); } if (JsonBinaryEncoding.TryGetEncodedStringValue( stringToken.Span, jsonStringDictionary, out UtfAllString encodedStringValue)) { value = encodedStringValue.Utf8EscapedString; return(true); } value = default; return(false); }
public bool Equals(IReadOnlyJsonStringDictionary other) { if (other == null) { return(false); } if (!(other is JsonStringDictionary otherDictionary)) { throw new NotImplementedException(); } return(this.Equals(otherDictionary)); }
private bool IsSameStringDictionary(IReadOnlyJsonStringDictionary jsonStringDictionary) { if (object.ReferenceEquals(this.jsonStringDictionary, jsonStringDictionary)) { return(true); } if ((this.jsonStringDictionary != null) && (jsonStringDictionary != null)) { return(this.jsonStringDictionary.Equals(jsonStringDictionary)); } return(false); }
/// <summary> /// Creates a JsonReader that can read from the supplied byte array (assumes utf-8 encoding) with format marker. /// </summary> /// <param name="buffer">The byte array (with format marker) to read from.</param> /// <param name="jsonStringDictionary">The dictionary to use for user string encoding.</param> /// <returns>A concrete JsonReader that can read the supplied byte array.</returns> public static IJsonReader Create(ReadOnlyMemory <byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary = null) { if (buffer.IsEmpty) { throw new ArgumentOutOfRangeException($"{nameof(buffer)} can not be empty."); } byte firstByte = buffer.Span[0]; // Explicitly pick from the set of supported formats, or otherwise assume text format JsonSerializationFormat jsonSerializationFormat = (firstByte == (byte)JsonSerializationFormat.Binary) ? JsonSerializationFormat.Binary : JsonSerializationFormat.Text; return(JsonReader.Create(jsonSerializationFormat, buffer, jsonStringDictionary)); }
/// <summary> /// Gets the string value from the binary reader. /// </summary> /// <param name="stringToken">The buffer that has the string.</param> /// <param name="jsonStringDictionary">The JSON string dictionary.</param> /// <returns>A string value from the binary reader.</returns> public static string GetStringValue( Utf8Memory stringToken, IReadOnlyJsonStringDictionary jsonStringDictionary) { if (stringToken.IsEmpty) { throw new JsonInvalidTokenException(); } if (!JsonBinaryEncoding.TryGetBufferedStringValue(stringToken, jsonStringDictionary, out Utf8Memory bufferedUtf8StringValue)) { throw new JsonInvalidTokenException(); } return(bufferedUtf8StringValue.ToString()); }
/// <summary> /// Creates a JsonReader with a given serialization format and byte array. /// </summary> /// <param name="jsonSerializationFormat">The serialization format of the payload.</param> /// <param name="buffer">The buffer to read from.</param> /// <param name="jsonStringDictionary">The optional dictionary to decode strings.</param> /// <returns>An <see cref="IJsonReader"/> for the buffer, format, and dictionary.</returns> public static IJsonReader Create( JsonSerializationFormat jsonSerializationFormat, ReadOnlyMemory <byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary = null) { if (buffer.IsEmpty) { throw new ArgumentOutOfRangeException($"{nameof(buffer)} can not be empty."); } // Explicitly pick from the set of supported formats, or otherwise assume text format return(jsonSerializationFormat switch { JsonSerializationFormat.Binary => new JsonBinaryReader(buffer, jsonStringDictionary), JsonSerializationFormat.Text => new JsonTextReader(buffer), _ => throw new ArgumentOutOfRangeException($"Unknown {nameof(JsonSerializationFormat)}: {jsonSerializationFormat}."), });
/// <summary> /// Try Get Encoded String Value /// </summary> /// <param name="stringToken">The string token to read from.</param> /// <param name="jsonStringDictionary">The JSON string dictionary.</param> /// <param name="value">The encoded string if found.</param> /// <returns>Encoded String Value</returns> private static bool TryGetEncodedStringValue( Utf8Span stringToken, IReadOnlyJsonStringDictionary jsonStringDictionary, out UtfAllString value) { if (JsonBinaryEncoding.TryGetEncodedSystemStringValue(stringToken, out value)) { return(true); } if (JsonBinaryEncoding.TryGetEncodedUserStringValue(stringToken, jsonStringDictionary, out value)) { return(true); } value = default; return(false); }
/// <summary> /// Creates a JsonReader that can read from the supplied byte array (assumes utf-8 encoding). /// </summary> /// <param name="buffer">The byte array to read from.</param> /// <param name="jsonStringDictionary">The dictionary to use for user string encoding.</param> /// <returns>A concrete JsonReader that can read the supplied byte array.</returns> public static IJsonReader Create(ReadOnlyMemory <byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary = null) { if (buffer.IsEmpty) { throw new ArgumentOutOfRangeException($"{nameof(buffer)} can not be empty."); } byte firstByte = buffer.Span[0]; // Explicitly pick from the set of supported formats, or otherwise assume text format switch ((JsonSerializationFormat)firstByte) { case JsonSerializationFormat.Binary: return(new JsonBinaryReader(buffer, jsonStringDictionary)); default: return(new JsonTextReader(buffer)); } }
/// <summary> /// Try Get Encoded User String Value /// </summary> /// <param name="stringToken">The string token to read from.</param> /// <param name="jsonStringDictionary">The JSON string dictionary.</param> /// <param name="encodedUserStringValue">The encoded user string value if found.</param> /// <returns>Whether or not the Encoded User String Value was found</returns> private static bool TryGetEncodedUserStringValue( Utf8Span stringToken, IReadOnlyJsonStringDictionary jsonStringDictionary, out UtfAllString encodedUserStringValue) { if (jsonStringDictionary == null) { encodedUserStringValue = default; return(false); } if (!JsonBinaryEncoding.TryGetUserStringId(stringToken, out int userStringId)) { encodedUserStringValue = default; return(false); } return(jsonStringDictionary.TryGetStringAtIndex(userStringId, out encodedUserStringValue)); }
/// <summary> /// Creates a JsonNavigator that can navigate a supplied buffer /// </summary> /// <param name="buffer">The buffer to navigate</param> /// <param name="jsonStringDictionary">The optional json string dictionary for binary encoding.</param> /// <returns>A concrete JsonNavigator that can navigate the supplied buffer.</returns> public static IJsonNavigator Create( ReadOnlyMemory <byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary = null) { if (buffer.IsEmpty) { throw new ArgumentOutOfRangeException($"{nameof(buffer)} can not be empty."); } // Examine the first buffer byte to determine the serialization format byte firstByte = buffer.Span[0]; return(((JsonSerializationFormat)firstByte) switch { // Explicitly pick from the set of supported formats JsonSerializationFormat.Binary => new JsonBinaryNavigator(buffer, jsonStringDictionary), // or otherwise assume text format _ => new JsonTextNavigator(buffer), });
public JsonBinaryReader( ReadOnlyMemory<byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary = null) { if (buffer.IsEmpty) { throw new ArgumentException($"{nameof(buffer)} must not be empty."); } // Only navigate the outer most json value and trim off trailing bytes int jsonValueLength = JsonBinaryEncoding.GetValueLength(buffer.Span); if (buffer.Length < jsonValueLength) { throw new ArgumentException("buffer is shorter than the length prefix."); } buffer = buffer.Slice(0, jsonValueLength); this.jsonBinaryBuffer = new JsonBinaryMemoryReader(buffer); this.arrayAndObjectEndStack = new Stack<int>(); this.jsonStringDictionary = jsonStringDictionary; }
internal JsonBinaryReader( ReadOnlyMemory <byte> rootBuffer, int?indexToStartFrom = null, IReadOnlyJsonStringDictionary jsonStringDictionary = null) { if (rootBuffer.IsEmpty) { throw new ArgumentException($"{nameof(rootBuffer)} must not be empty."); } this.rootBuffer = rootBuffer; ReadOnlyMemory <byte> readerBuffer = this.rootBuffer; if (indexToStartFrom.HasValue) { readerBuffer = readerBuffer.Slice(start: indexToStartFrom.Value); } else { // Skip the 0x80 readerBuffer = readerBuffer.Slice(start: 1); } // Only navigate the outer most json value and trim off trailing bytes int jsonValueLength = JsonBinaryEncoding.GetValueLength(readerBuffer.Span); if (readerBuffer.Length < jsonValueLength) { throw new ArgumentException("buffer is shorter than the length prefix."); } readerBuffer = readerBuffer.Slice(0, jsonValueLength); // offset for the 0x80 binary type marker this.jsonBinaryBuffer = new JsonBinaryMemoryReader(readerBuffer); this.arrayAndObjectEndStack = new Stack <int>(); this.jsonStringDictionary = jsonStringDictionary; }
public void WriteRawJsonValue( ReadOnlyMemory <byte> rawJsonValue, bool isFieldName, bool isRootNode, IReadOnlyJsonStringDictionary jsonStringDictionary) { // Only if the we attempt to write the root node as is the input and output have the same dictionary encoding if (this.IsSameStringDictionary(jsonStringDictionary) && isRootNode && (this.binaryWriter.Position == 1)) { // Other that whether or not this is a field name, the type of the value does not matter here this.JsonObjectState.RegisterToken(isFieldName ? JsonTokenType.FieldName : JsonTokenType.String); this.binaryWriter.Write(rawJsonValue.Span); if (!isFieldName) { this.bufferedContexts.Peek().Count++; } } else { this.ForceRewriteRawJsonValue(rawJsonValue, isFieldName, jsonStringDictionary); } }
private void ForceRewriteRawJsonValue( ReadOnlyMemory <byte> rawJsonValue, bool isFieldName, IReadOnlyJsonStringDictionary jsonStringDictionary) { byte typeMarker = rawJsonValue.Span[0]; if (!JsonBinaryEncoding.TypeMarker.IsSystemString(typeMarker) && !JsonBinaryEncoding.TypeMarker.IsEmptyArray(typeMarker) && !JsonBinaryEncoding.TypeMarker.IsEmptyObject(typeMarker)) { JsonNodeType nodeType = JsonBinaryEncoding.NodeTypes.GetNodeType(typeMarker); switch (nodeType) { case JsonNodeType.String: { if (!JsonBinaryEncoding.TryGetBufferedStringValue( Utf8Memory.UnsafeCreateNoValidation(rawJsonValue), jsonStringDictionary, out Utf8Memory bufferedStringValue)) { throw new InvalidOperationException("Excepted to get the buffered string value."); } if (isFieldName) { this.WriteFieldName(bufferedStringValue.Span); } else { this.WriteStringValue(bufferedStringValue.Span); } return; } case JsonNodeType.Array: { this.WriteArrayStart(); foreach (ReadOnlyMemory <byte> arrayItem in JsonBinaryEncoding.Enumerator.GetArrayItems(rawJsonValue)) { this.ForceRewriteRawJsonValue(arrayItem, isFieldName, jsonStringDictionary); } this.WriteArrayEnd(); return; } case JsonNodeType.Object: { this.WriteObjectStart(); foreach (JsonBinaryEncoding.Enumerator.ObjectProperty property in JsonBinaryEncoding.Enumerator.GetObjectProperties(rawJsonValue)) { this.ForceRewriteRawJsonValue(property.Name, isFieldName: true, jsonStringDictionary); this.ForceRewriteRawJsonValue(property.Value, isFieldName: false, jsonStringDictionary); } this.WriteObjectEnd(); return; } } } // Other that whether or not this is a field name, the type of the value does not matter here this.JsonObjectState.RegisterToken(isFieldName ? JsonTokenType.FieldName : JsonTokenType.String); this.binaryWriter.Write(rawJsonValue.Span); if (!isFieldName) { this.bufferedContexts.Peek().Count++; } }
public JsonBinaryReader( ReadOnlyMemory <byte> buffer, IReadOnlyJsonStringDictionary jsonStringDictionary = null) : this(buffer, indexToStartFrom : null, jsonStringDictionary : jsonStringDictionary) { }