/// <inheritdoc /> public override bool TryGetObjectProperty( IJsonNavigatorNode objectNode, string propertyName, out ObjectProperty objectProperty) { _ = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Object, objectNode); Utf8Span utf8StringPropertyName = Utf8Span.TranscodeUtf16(propertyName); foreach (ObjectProperty objectPropertyNode in this.GetObjectProperties(objectNode)) { if (this.TryGetBufferedStringValue(objectPropertyNode.NameNode, out Utf8Memory bufferedUtf8StringValue)) { // First try and see if we can avoid materializing the UTF16 string. if (utf8StringPropertyName.Equals(bufferedUtf8StringValue.Span)) { objectProperty = objectPropertyNode; return(true); } } else { if (this.GetStringValue(objectPropertyNode.NameNode) == propertyName) { objectProperty = objectPropertyNode; return(true); } } } objectProperty = default; return(false); }
/// <inheritdoc /> public override bool TryGetObjectProperty( IJsonNavigatorNode objectNode, string propertyName, out ObjectProperty objectProperty) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Object, objectNode); ReadOnlySpan <byte> utf8StringPropertyName = Encoding.UTF8.GetBytes(propertyName); foreach (ObjectProperty objectPropertyNode in this.GetObjectProperties(objectNode)) { if (this.TryGetBufferedUtf8StringValue(objectPropertyNode.NameNode, out ReadOnlyMemory <byte> bufferedUtf8StringValue)) { // First try and see if we can avoid materializing the UTF16 string. if (utf8StringPropertyName.SequenceEqual(bufferedUtf8StringValue.Span)) { objectProperty = objectPropertyNode; return(true); } } else { if (this.GetStringValue(objectPropertyNode.NameNode) == propertyName) { objectProperty = objectPropertyNode; return(true); } } } objectProperty = default(ObjectProperty); return(false); }
/// <inheritdoc /> public override IEnumerable <ObjectProperty> GetObjectProperties(IJsonNavigatorNode objectNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Object, objectNode); byte typeMarker = buffer.Span[0]; int firstValueOffset = JsonBinaryEncoding.GetFirstValueOffset(typeMarker); buffer = buffer.Slice(firstValueOffset); while (buffer.Length != 0) { int nameNodeLength = JsonBinaryEncoding.GetValueLength(buffer.Span); if (nameNodeLength > buffer.Length) { throw new JsonInvalidTokenException(); } ReadOnlyMemory <byte> nameNode = buffer.Slice(0, nameNodeLength); buffer = buffer.Slice(nameNodeLength); int valueNodeLength = JsonBinaryEncoding.GetValueLength(buffer.Span); if (valueNodeLength > buffer.Length) { throw new JsonInvalidTokenException(); } ReadOnlyMemory <byte> valueNode = buffer.Slice(0, valueNodeLength); buffer = buffer.Slice(valueNodeLength); yield return(new ObjectProperty( new BinaryNavigatorNode(nameNode, JsonNodeType.FieldName), new BinaryNavigatorNode(valueNode, NodeTypes.GetNodeType(valueNode.Span[0])))); } }
/// <inheritdoc /> public override IEnumerable <IJsonNavigatorNode> GetArrayItems(IJsonNavigatorNode arrayNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Array, arrayNode); return(this.GetArrayItemsInternal(buffer).Select((node) => (IJsonNavigatorNode)node)); }
/// <inheritdoc /> public override double GetFloat64Value(IJsonNavigatorNode numberNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Float64, numberNode); return(JsonBinaryEncoding.GetFloat64Value(buffer.Span)); }
/// <inheritdoc /> public override uint GetUInt32Value(IJsonNavigatorNode numberNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.UInt32, numberNode); return(JsonBinaryEncoding.GetUInt32Value(buffer.Span)); }
/// <inheritdoc /> public override Guid GetGuidValue(IJsonNavigatorNode guidNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Guid, guidNode); return(JsonBinaryEncoding.GetGuidValue(buffer.Span)); }
/// <inheritdoc /> public override string GetStringValue(IJsonNavigatorNode stringNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.String, stringNode); return(JsonBinaryEncoding.GetStringValue(buffer.Span, this.jsonStringDictionary)); }
/// <inheritdoc /> public override int GetObjectPropertyCount(IJsonNavigatorNode objectNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Object, objectNode); byte typeMarker = buffer.Span[0]; int firstObjectPropertyOffset = JsonBinaryEncoding.GetFirstValueOffset(typeMarker); long count; switch (typeMarker) { // Empty and Single Object case JsonBinaryEncoding.TypeMarker.EmptyObject: count = 0; break; case JsonBinaryEncoding.TypeMarker.SinglePropertyObject: // This number gets divided by 2 later. count = 2; break; // Object with length and count prefix case JsonBinaryEncoding.TypeMarker.Object1ByteLengthAndCount: count = MemoryMarshal.Read <byte>(buffer .Slice(JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.OneByteLength).Span); break; case JsonBinaryEncoding.TypeMarker.Object2ByteLengthAndCount: count = MemoryMarshal.Read <ushort>(buffer .Slice(JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.TwoByteLength).Span); break; case JsonBinaryEncoding.TypeMarker.Object4ByteLengthAndCount: count = MemoryMarshal.Read <uint>(buffer .Slice(JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.FourByteLength).Span); break; // Object with length prefix case JsonBinaryEncoding.TypeMarker.Object1ByteLength: case JsonBinaryEncoding.TypeMarker.Object2ByteLength: case JsonBinaryEncoding.TypeMarker.Object4ByteLength: count = JsonBinaryNavigator.GetValueCount(buffer.Slice(firstObjectPropertyOffset).Span); break; default: throw new InvalidOperationException($"Unexpected object type marker: {typeMarker}"); } // Divide by 2 since the count includes fieldname and value as seperate entities count = count / 2; if (count > int.MaxValue) { throw new InvalidOperationException("count can not be more than int.MaxValue"); } return((int)count); }
/// <inheritdoc /> public override bool TryGetBufferedUtf8StringValue( IJsonNavigatorNode stringNode, out ReadOnlyMemory <byte> bufferedUtf8StringValue) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.String, stringNode); return(JsonBinaryEncoding.TryGetBufferedUtf8StringValue(buffer, this.jsonStringDictionary, out bufferedUtf8StringValue)); }
/// <inheritdoc /> public override string GetStringValue(IJsonNavigatorNode stringNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.String, stringNode); return(JsonBinaryEncoding.GetStringValue( Utf8Memory.UnsafeCreateNoValidation(buffer), this.jsonStringDictionary)); }
/// <inheritdoc /> public override UtfAnyString GetStringValue(IJsonNavigatorNode stringNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.String, stringNode); return(JsonBinaryEncoding.GetUtf8StringValue( this.rootBuffer, buffer)); }
/// <inheritdoc /> public override int GetArrayItemCount(IJsonNavigatorNode arrayNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Array, arrayNode); byte typeMarker = buffer.Span[0]; int firstValueOffset = JsonBinaryEncoding.GetFirstValueOffset(typeMarker); long count; switch (typeMarker) { // Empty and Single Array case JsonBinaryEncoding.TypeMarker.EmptyArray: count = 0; break; case JsonBinaryEncoding.TypeMarker.SingleItemArray: count = 1; break; // Arrays with length and count prefix case JsonBinaryEncoding.TypeMarker.Array1ByteLengthAndCount: count = MemoryMarshal.Read <byte>(buffer .Slice(JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.OneByteLength).Span); break; case JsonBinaryEncoding.TypeMarker.Array2ByteLengthAndCount: count = MemoryMarshal.Read <ushort>(buffer .Slice(JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.TwoByteLength).Span); break; case JsonBinaryEncoding.TypeMarker.Array4ByteLengthAndCount: count = MemoryMarshal.Read <uint>(buffer .Slice(JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.FourByteLength).Span); break; // Arrays with length prefix case JsonBinaryEncoding.TypeMarker.Array1ByteLength: case JsonBinaryEncoding.TypeMarker.Array2ByteLength: case JsonBinaryEncoding.TypeMarker.Array4ByteLength: count = JsonBinaryNavigator.GetValueCount(buffer.Slice(firstValueOffset).Span); break; default: throw new InvalidOperationException($"Unexpected array type marker: {typeMarker}"); } if (count > int.MaxValue) { throw new InvalidOperationException("count can not be more than int.MaxValue"); } return((int)count); }
public override bool TryGetBufferedBinaryValue( IJsonNavigatorNode binaryNode, out ReadOnlyMemory <byte> bufferedBinaryValue) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Binary, binaryNode); bufferedBinaryValue = JsonBinaryEncoding.GetBinaryValue(buffer); return(true); }
/// <inheritdoc /> public override IEnumerable <ObjectProperty> GetObjectProperties(IJsonNavigatorNode objectNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Object, objectNode); return(this.GetObjectPropertiesInternal(buffer) .Select((objectPropertyInternal) => new ObjectProperty( objectPropertyInternal.NameNode, objectPropertyInternal.ValueNode))); }
/// <inheritdoc /> public override bool TryGetBufferedStringValue( IJsonNavigatorNode stringNode, out Utf8Memory value) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.String, stringNode); return(JsonBinaryEncoding.TryGetBufferedStringValue( this.rootBuffer, buffer, out value)); }
/// <inheritdoc /> public override bool TryGetObjectProperty( IJsonNavigatorNode objectNode, string propertyName, out ObjectProperty objectProperty) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Object, objectNode); foreach (ObjectProperty objectPropertyNode in this.GetObjectProperties(objectNode)) { if (this.GetStringValue(objectPropertyNode.NameNode) == propertyName) { objectProperty = objectPropertyNode; return(true); } } objectProperty = default(ObjectProperty); return(false); }
/// <inheritdoc /> public override IJsonNavigatorNode GetArrayItemAt(IJsonNavigatorNode arrayNode, int index) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Array, arrayNode); if (index < 0) { throw new IndexOutOfRangeException(); } // TODO (brchon): We can optimize for the case where the count is serialized so we can avoid using the linear time call to TryGetValueAt(). if (!JsonBinaryNavigator.TryGetValueAt(buffer, index, out ReadOnlyMemory <byte> arrayItem)) { throw new IndexOutOfRangeException($"Tried to access index:{index} in an array."); } return(new BinaryNavigatorNode( arrayItem, NodeTypes.GetNodeType(arrayItem.Span[0]))); }
/// <inheritdoc /> public override IEnumerable <IJsonNavigatorNode> GetArrayItems(IJsonNavigatorNode arrayNode) { ReadOnlyMemory <byte> buffer = JsonBinaryNavigator.GetNodeOfType( JsonNodeType.Array, arrayNode); byte typeMarker = buffer.Span[0]; int firstArrayItemOffset = JsonBinaryEncoding.GetFirstValueOffset(typeMarker); int arrayLength = JsonBinaryEncoding.GetValueLength(buffer.Span); // Scope to just the array buffer = buffer.Slice(0, (int)arrayLength); // Seek to the first array item buffer = buffer.Slice(firstArrayItemOffset); while (buffer.Length != 0) { int arrayItemLength = JsonBinaryEncoding.GetValueLength(buffer.Span); if (arrayItemLength > buffer.Length) { // Array Item got cut off. throw new JsonInvalidTokenException(); } // Create a buffer for that array item IJsonNavigatorNode arrayItem = new BinaryNavigatorNode( buffer.Slice(0, arrayItemLength), NodeTypes.GetNodeType(buffer.Span[0])); yield return(arrayItem); // Slice off the array item buffer = buffer.Slice(arrayItemLength); } }