/// <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); } }
/// <summary> /// Gets an IEnumerable of <see cref="IJsonNavigatorNode"/>s for an arrayNode. /// </summary> /// <param name="arrayNavigatorNode">The <see cref="IJsonNavigatorNode"/> of the array to get the items from</param> /// <returns>The IEnumerable of <see cref="IJsonNavigatorNode"/>s for an arrayNode.</returns> public override IEnumerable <IJsonNavigatorNode> GetArrayItems(IJsonNavigatorNode arrayNavigatorNode) { if (arrayNavigatorNode == null) { throw new ArgumentNullException(nameof(arrayNavigatorNode)); } if (!(((arrayNavigatorNode as BinaryNode)?.JsonNodeType ?? JsonNodeType.Unknown) == JsonNodeType.Array)) { throw new ArgumentException($"{nameof(arrayNavigatorNode)} must be a binary array node."); } int arrayOffset = ((BinaryNode)arrayNavigatorNode).Offset; byte typeMarker = this.buffer[arrayOffset]; long arrayLength = JsonBinaryEncoding.GetValueLength(this.buffer, arrayOffset); long firstValueOffset = arrayOffset + JsonBinaryEncoding.GetFirstValueOffset(typeMarker); long bytesToProcess = (arrayOffset + arrayLength) - firstValueOffset; for (int bytesProcessed = 0; bytesProcessed < bytesToProcess; bytesProcessed += (int)JsonBinaryEncoding.GetValueLength(this.buffer, firstValueOffset + bytesProcessed)) { yield return(this.CreateBinaryNode((int)(firstValueOffset + bytesProcessed))); } }
public static bool TryGetFloat64Value( ReadOnlySpan <byte> float64Token, out double float64Value) => JsonBinaryEncoding.TryGetFixedWidthValue <double>( float64Token, JsonBinaryEncoding.TypeMarker.Float64, out float64Value);
public static bool TryGetFloat32Value( ReadOnlySpan <byte> float32Token, out float float32Value) => JsonBinaryEncoding.TryGetFixedWidthValue <float>( float32Token, JsonBinaryEncoding.TypeMarker.Float32, out float32Value);
public static bool TryGetUInt32Value( ReadOnlySpan <byte> uInt32Token, out uint uInt32Value) => JsonBinaryEncoding.TryGetFixedWidthValue <uint>( uInt32Token, JsonBinaryEncoding.TypeMarker.UInt32, out uInt32Value);
public static bool TryGetInt64Value( ReadOnlySpan <byte> int64Token, out long int64Value) => JsonBinaryEncoding.TryGetFixedWidthValue <long>( int64Token, JsonBinaryEncoding.TypeMarker.Int64, out int64Value);
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++; } }
/// <inheritdoc /> public override bool Read() { JsonTokenType jsonTokenType; int nextTokenOffset; // First check if we just finished an array or object context if (!this.arrayAndObjectEndStack.Empty() && (this.arrayAndObjectEndStack.Peek() == this.jsonBinaryBuffer.Position)) { if (this.JsonObjectState.InArrayContext) { jsonTokenType = JsonTokenType.EndArray; } else if (this.JsonObjectState.InObjectContext) { jsonTokenType = JsonTokenType.EndObject; } else { throw new JsonInvalidTokenException(); } nextTokenOffset = 0; this.arrayAndObjectEndStack.Pop(); } else { // We are not at the end of a context. if (this.jsonBinaryBuffer.IsEof) { // Need to check if we are still inside of an object or array if (this.JsonObjectState.CurrentDepth != 0) { if (this.JsonObjectState.InObjectContext) { throw new JsonMissingEndObjectException(); } else if (this.JsonObjectState.InArrayContext) { throw new JsonMissingEndArrayException(); } else { throw new InvalidOperationException("Expected to be in either array or object context"); } } return false; } if ((this.JsonObjectState.CurrentDepth == 0) && (this.CurrentTokenType != JsonTokenType.NotStarted)) { // There are trailing characters outside of the outter most object or array throw new JsonUnexpectedTokenException(); } byte firstByte = this.jsonBinaryBuffer.Peek(); jsonTokenType = JsonBinaryReader.GetJsonTokenType(firstByte); if ((jsonTokenType == JsonTokenType.String) && this.JsonObjectState.IsPropertyExpected) { jsonTokenType = JsonTokenType.FieldName; } // If this is begin array/object token then we need to identify where array/object end token is. // Also the next token offset is just the array type marker + length prefix + count prefix if ((jsonTokenType == JsonTokenType.BeginArray) || (jsonTokenType == JsonTokenType.BeginObject)) { if (!JsonBinaryEncoding.TryGetValueLength( this.jsonBinaryBuffer.GetBufferedRawJsonToken().Span, out int arrayOrObjectLength)) { throw new JsonUnexpectedTokenException(); } this.arrayAndObjectEndStack.Push(this.jsonBinaryBuffer.Position + arrayOrObjectLength); nextTokenOffset = JsonBinaryReader.GetArrayOrObjectPrefixLength(firstByte); } else { if (!JsonBinaryEncoding.TryGetValueLength( this.jsonBinaryBuffer.GetBufferedRawJsonToken().Span, out nextTokenOffset)) { throw new JsonUnexpectedTokenException(); } } } this.JsonObjectState.RegisterToken(jsonTokenType); this.currentTokenPosition = this.jsonBinaryBuffer.Position; this.jsonBinaryBuffer.SkipBytes(nextTokenOffset); return true; }
private BinaryNode CreateBinaryNode(int offset) { return(new BinaryNode(offset, JsonBinaryEncoding.GetNodeType(this.buffer[offset]))); }
/// <summary> /// Gets the number of properties in an object node. /// </summary> /// <param name="objectNavigatorNode">The <see cref="IJsonNavigatorNode"/> of node to get the property count from.</param> /// <returns>The number of properties in an object node.</returns> public override int GetObjectPropertyCount(IJsonNavigatorNode objectNavigatorNode) { if (objectNavigatorNode == null) { throw new ArgumentNullException(nameof(objectNavigatorNode)); } if (!(((objectNavigatorNode as BinaryNode)?.JsonNodeType ?? JsonNodeType.Unknown) == JsonNodeType.Object)) { throw new ArgumentException($"{nameof(objectNavigatorNode)} must be a binary object node."); } int objectOffset = ((BinaryNode)objectNavigatorNode).Offset; byte typeMarker = this.buffer[objectOffset]; int firstObjectPropertyOffset = objectOffset + 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 = this.buffer[objectOffset + JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.OneByteLength]; break; case JsonBinaryEncoding.TypeMarker.Object2ByteLengthAndCount: count = BitConverter.ToUInt16(this.buffer, objectOffset + JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.TwoByteLength); break; case JsonBinaryEncoding.TypeMarker.Object4ByteLengthAndCount: count = BitConverter.ToUInt32(this.buffer, objectOffset + JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.FourByteLength); break; // Object with length prefix case JsonBinaryEncoding.TypeMarker.Object1ByteLength: count = this.GetValueCount(firstObjectPropertyOffset, this.buffer[objectOffset + JsonBinaryEncoding.TypeMarkerLength]); break; case JsonBinaryEncoding.TypeMarker.Object2ByteLength: count = this.GetValueCount(firstObjectPropertyOffset, BitConverter.ToUInt16(this.buffer, objectOffset + JsonBinaryEncoding.TypeMarkerLength)); break; case JsonBinaryEncoding.TypeMarker.Object4ByteLength: count = this.GetValueCount(firstObjectPropertyOffset, BitConverter.ToUInt32(this.buffer, objectOffset + JsonBinaryEncoding.TypeMarkerLength)); 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); }
/// <summary> /// Gets the number of elements in an array node. /// </summary> /// <param name="arrayNavigatorNode">The <see cref="IJsonNavigatorNode"/> of the (array) node to get the count of.</param> /// <returns>The number of elements in the array node.</returns> public override int GetArrayItemCount(IJsonNavigatorNode arrayNavigatorNode) { if (arrayNavigatorNode == null) { throw new ArgumentNullException(nameof(arrayNavigatorNode)); } if (!(((arrayNavigatorNode as BinaryNode)?.JsonNodeType ?? JsonNodeType.Unknown) == JsonNodeType.Array)) { throw new ArgumentException($"{nameof(arrayNavigatorNode)} must be a binary array node."); } int offset = ((BinaryNode)arrayNavigatorNode).Offset; byte typeMarker = this.buffer[offset]; int firstValueOffset = offset + 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 = this.buffer[offset + JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.OneByteLength]; break; case JsonBinaryEncoding.TypeMarker.Array2ByteLengthAndCount: count = BitConverter.ToUInt16(this.buffer, offset + JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.TwoByteLength); break; case JsonBinaryEncoding.TypeMarker.Array4ByteLengthAndCount: count = BitConverter.ToUInt32(this.buffer, offset + JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.FourByteLength); break; // Arrays with length prefix case JsonBinaryEncoding.TypeMarker.Array1ByteLength: count = this.GetValueCount(firstValueOffset, this.buffer[offset + JsonBinaryEncoding.TypeMarkerLength]); break; case JsonBinaryEncoding.TypeMarker.Array2ByteLength: count = this.GetValueCount(firstValueOffset, BitConverter.ToUInt16(this.buffer, offset + JsonBinaryEncoding.TypeMarkerLength)); break; case JsonBinaryEncoding.TypeMarker.Array4ByteLength: count = this.GetValueCount(firstValueOffset, BitConverter.ToUInt32(this.buffer, offset + JsonBinaryEncoding.TypeMarkerLength)); 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); }
private void WriteToInternal(BinaryNavigatorNode binaryNavigatorNode, IJsonWriter jsonWriter, bool sameEncoding) { ReadOnlyMemory <byte> buffer = binaryNavigatorNode.Buffer; JsonNodeType nodeType = binaryNavigatorNode.JsonNodeType; if (sameEncoding && this.TryGetBufferedRawJsonInternal(binaryNavigatorNode, out ReadOnlyMemory <byte> bufferedRawJson)) { // Token type doesn't make any difference other than whether it's a value or field name JsonTokenType tokenType = nodeType == JsonNodeType.FieldName ? JsonTokenType.FieldName : JsonTokenType.String; jsonWriter.WriteRawJsonToken(tokenType, bufferedRawJson.Span); return; } switch (nodeType) { case JsonNodeType.Null: jsonWriter.WriteNullValue(); break; case JsonNodeType.False: jsonWriter.WriteBoolValue(false); break; case JsonNodeType.True: jsonWriter.WriteBoolValue(true); break; case JsonNodeType.Number64: { Number64 value = JsonBinaryEncoding.GetNumberValue(buffer.Span); jsonWriter.WriteNumber64Value(value); } break; case JsonNodeType.String: case JsonNodeType.FieldName: bool fieldName = binaryNavigatorNode.JsonNodeType == JsonNodeType.FieldName; Utf8Memory utf8Buffer = Utf8Memory.UnsafeCreateNoValidation(buffer); if (JsonBinaryEncoding.TryGetBufferedStringValue( utf8Buffer, this.jsonStringDictionary, out Utf8Memory bufferedStringValue)) { if (fieldName) { jsonWriter.WriteFieldName(bufferedStringValue.Span); } else { jsonWriter.WriteStringValue(bufferedStringValue.Span); } } else { string value = JsonBinaryEncoding.GetStringValue( utf8Buffer, this.jsonStringDictionary); if (fieldName) { jsonWriter.WriteFieldName(value); } else { jsonWriter.WriteStringValue(value); } } break; case JsonNodeType.Array: { jsonWriter.WriteArrayStart(); foreach (BinaryNavigatorNode arrayItem in this.GetArrayItemsInternal(buffer)) { this.WriteToInternal(arrayItem, jsonWriter, sameEncoding); } jsonWriter.WriteArrayEnd(); } break; case JsonNodeType.Object: { jsonWriter.WriteObjectStart(); foreach (ObjectPropertyInternal objectProperty in this.GetObjectPropertiesInternal(buffer)) { this.WriteToInternal(objectProperty.NameNode, jsonWriter, sameEncoding); this.WriteToInternal(objectProperty.ValueNode, jsonWriter, sameEncoding); } jsonWriter.WriteObjectEnd(); } break; case JsonNodeType.Int8: { sbyte value = JsonBinaryEncoding.GetInt8Value(buffer.Span); jsonWriter.WriteInt8Value(value); } break; case JsonNodeType.Int16: { short value = JsonBinaryEncoding.GetInt16Value(buffer.Span); jsonWriter.WriteInt16Value(value); } break; case JsonNodeType.Int32: { int value = JsonBinaryEncoding.GetInt32Value(buffer.Span); jsonWriter.WriteInt32Value(value); } break; case JsonNodeType.Int64: { long value = JsonBinaryEncoding.GetInt64Value(buffer.Span); jsonWriter.WriteInt64Value(value); } break; case JsonNodeType.UInt32: { uint value = JsonBinaryEncoding.GetUInt32Value(buffer.Span); jsonWriter.WriteUInt32Value(value); } break; case JsonNodeType.Float32: { float value = JsonBinaryEncoding.GetFloat32Value(buffer.Span); jsonWriter.WriteFloat32Value(value); } break; case JsonNodeType.Float64: { double value = JsonBinaryEncoding.GetFloat64Value(buffer.Span); jsonWriter.WriteFloat64Value(value); } break; case JsonNodeType.Binary: { ReadOnlyMemory <byte> value = JsonBinaryEncoding.GetBinaryValue(buffer); jsonWriter.WriteBinaryValue(value.Span); } break; case JsonNodeType.Guid: { Guid value = JsonBinaryEncoding.GetGuidValue(buffer.Span); jsonWriter.WriteGuidValue(value); } break; default: throw new ArgumentOutOfRangeException($"Unknown {nameof(JsonNodeType)}: {nodeType}."); } }
private static bool TryGetBufferedLengthPrefixedString( Utf8Memory stringToken, out Utf8Memory value) { ReadOnlySpan <byte> stringTokenSpan = stringToken.Memory.Span; byte typeMarker = stringTokenSpan[0]; stringTokenSpan = stringTokenSpan.Slice(start: 1); int start; long length; if (JsonBinaryEncoding.TypeMarker.IsEncodedLengthString(typeMarker)) { start = JsonBinaryEncoding.TypeMarkerLength; length = JsonBinaryEncoding.GetStringLengths(typeMarker); } else { switch (typeMarker) { case JsonBinaryEncoding.TypeMarker.String1ByteLength: if (stringTokenSpan.Length < JsonBinaryEncoding.OneByteLength) { value = default; return(false); } start = JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.OneByteLength; length = stringTokenSpan[0]; break; case JsonBinaryEncoding.TypeMarker.String2ByteLength: if (stringTokenSpan.Length < JsonBinaryEncoding.TwoByteLength) { value = default; return(false); } start = JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.TwoByteLength; length = MemoryMarshal.Read <ushort>(stringTokenSpan); break; case JsonBinaryEncoding.TypeMarker.String4ByteLength: if (stringTokenSpan.Length < JsonBinaryEncoding.FourByteLength) { value = default; return(false); } start = JsonBinaryEncoding.TypeMarkerLength + JsonBinaryEncoding.FourByteLength; length = MemoryMarshal.Read <uint>(stringTokenSpan); break; default: value = default; return(false); } if ((start + length) > stringToken.Length) { value = default; return(false); } } value = stringToken.Slice(start: start, length: (int)length); return(true); }
/// <inheritdoc /> public override bool Read() { // Check if we just finished an array or object context if (!this.arrayAndObjectEndStack.Empty() && this.arrayAndObjectEndStack.Peek() == this.jsonBinaryBuffer.Position) { if (this.JsonObjectState.InArrayContext) { this.JsonObjectState.RegisterEndArray(); } else if (this.JsonObjectState.InObjectContext) { this.JsonObjectState.RegisterEndObject(); } else { throw new JsonInvalidTokenException(); } this.currentTokenPosition = this.jsonBinaryBuffer.Position; this.arrayAndObjectEndStack.Pop(); } else if (this.jsonBinaryBuffer.IsEof) { // Need to check if we are still inside of an object or array if (this.JsonObjectState.CurrentDepth != 0) { if (this.JsonObjectState.InObjectContext) { throw new JsonMissingEndObjectException(); } if (this.JsonObjectState.InArrayContext) { throw new JsonMissingEndArrayException(); } throw new InvalidOperationException("Expected to be in either array or object context"); } return(false); } else if (this.JsonObjectState.CurrentDepth == 0 && this.CurrentTokenType != JsonTokenType.NotStarted) { // There are trailing characters outside of the outter most object or array throw new JsonUnexpectedTokenException(); } else { ReadOnlySpan <byte> readOnlySpan = this.jsonBinaryBuffer.GetBufferedRawJsonToken().Span; int nextTokenOffset = JsonBinaryEncoding.GetValueLength(readOnlySpan); byte typeMarker = readOnlySpan[0]; JsonTokenType jsonTokenType = JsonBinaryReader.GetJsonTokenType(typeMarker); switch (jsonTokenType) { case JsonTokenType.String when this.JsonObjectState.IsPropertyExpected: jsonTokenType = JsonTokenType.FieldName; break; // If this is begin array/object token then we need to identify where array/object end token is. // Also the next token offset is just the array type marker + length prefix + count prefix case JsonTokenType.BeginArray: case JsonTokenType.BeginObject: this.arrayAndObjectEndStack.Push(this.jsonBinaryBuffer.Position + nextTokenOffset); nextTokenOffset = JsonBinaryReader.GetArrayOrObjectPrefixLength(typeMarker); break; } this.JsonObjectState.RegisterToken(jsonTokenType); this.currentTokenPosition = this.jsonBinaryBuffer.Position; this.jsonBinaryBuffer.SkipBytes(nextTokenOffset); } return(true); }
public static bool TryGetInt8Value( ReadOnlySpan <byte> int8Token, out sbyte int8Value) => JsonBinaryEncoding.TryGetFixedWidthValue <sbyte>( int8Token, JsonBinaryEncoding.TypeMarker.Int8, out int8Value);
private void WriteFieldNameOrString(bool isFieldName, ReadOnlySpan <byte> utf8String) { // String dictionary encoding is currently performed only for field names. // This would be changed later, so that the writer can control which strings need to be encoded. this.JsonObjectState.RegisterToken(isFieldName ? JsonTokenType.FieldName : JsonTokenType.String); if (JsonBinaryEncoding.TryGetEncodedStringTypeMarker( utf8String, this.JsonObjectState.CurrentTokenType == JsonTokenType.FieldName ? this.jsonStringDictionary : null, out JsonBinaryEncoding.MultiByteTypeMarker multiByteTypeMarker)) { switch (multiByteTypeMarker.Length) { case 1: this.binaryWriter.Write(multiByteTypeMarker.One); break; case 2: this.binaryWriter.Write(multiByteTypeMarker.One); this.binaryWriter.Write(multiByteTypeMarker.Two); break; default: throw new ArgumentOutOfRangeException($"Unable to serialize a {nameof(JsonBinaryEncoding.MultiByteTypeMarker)} of length: {multiByteTypeMarker.Length}"); } } else { // See if the string length can be encoded into a single type marker byte typeMarker = JsonBinaryEncoding.TypeMarker.GetEncodedStringLengthTypeMarker(utf8String.Length); if (JsonBinaryEncoding.TypeMarker.IsValid(typeMarker)) { this.binaryWriter.Write(typeMarker); } else { // Just write the type marker and the corresponding length if (utf8String.Length < byte.MaxValue) { this.binaryWriter.Write(JsonBinaryEncoding.TypeMarker.String1ByteLength); this.binaryWriter.Write((byte)utf8String.Length); } else if (utf8String.Length < ushort.MaxValue) { this.binaryWriter.Write(JsonBinaryEncoding.TypeMarker.String2ByteLength); this.binaryWriter.Write((ushort)utf8String.Length); } else { // (utf8String.Length < uint.MaxValue) this.binaryWriter.Write(JsonBinaryEncoding.TypeMarker.String4ByteLength); this.binaryWriter.Write((uint)utf8String.Length); } } // Finally write the string itself. this.binaryWriter.Write(utf8String); } if (!isFieldName) { // If we just wrote a string then increment the count (we don't increment for field names, since we need to wait for the corresponding property value). this.bufferedContexts.Peek().Count++; } }
public static bool TryGetInt16Value( ReadOnlySpan <byte> int16Token, out short int16Value) => JsonBinaryEncoding.TryGetFixedWidthValue <short>( int16Token, JsonBinaryEncoding.TypeMarker.Int16, out int16Value);
public static bool TryGetValueLength(ReadOnlySpan <byte> buffer, out int length) { // Too lazy to convert this right now. length = (int)JsonBinaryEncoding.GetValueLength(buffer); return(true); }
public static bool TryGetInt32Value( ReadOnlySpan <byte> int32Token, out int int32Value) => JsonBinaryEncoding.TryGetFixedWidthValue <int>( int32Token, JsonBinaryEncoding.TypeMarker.Int32, out int32Value);
private void WriteToInternal(BinaryNavigatorNode binaryNavigatorNode, IJsonWriter jsonWriter) { ReadOnlyMemory <byte> buffer = binaryNavigatorNode.Buffer; JsonNodeType nodeType = binaryNavigatorNode.JsonNodeType; switch (nodeType) { case JsonNodeType.Null: jsonWriter.WriteNullValue(); break; case JsonNodeType.False: jsonWriter.WriteBoolValue(false); break; case JsonNodeType.True: jsonWriter.WriteBoolValue(true); break; case JsonNodeType.Number64: { Number64 value = JsonBinaryEncoding.GetNumberValue(buffer.Span); jsonWriter.WriteNumber64Value(value); } break; case JsonNodeType.String: case JsonNodeType.FieldName: bool fieldName = binaryNavigatorNode.JsonNodeType == JsonNodeType.FieldName; if (JsonBinaryEncoding.TryGetBufferedStringValue( this.rootBuffer, buffer, out Utf8Memory bufferedStringValue)) { if (fieldName) { jsonWriter.WriteFieldName(bufferedStringValue.Span); } else { jsonWriter.WriteStringValue(bufferedStringValue.Span); } } else { string value = JsonBinaryEncoding.GetStringValue( this.rootBuffer, buffer); if (fieldName) { jsonWriter.WriteFieldName(value); } else { jsonWriter.WriteStringValue(value); } } break; case JsonNodeType.Array: { jsonWriter.WriteArrayStart(); foreach (BinaryNavigatorNode arrayItem in this.GetArrayItemsInternal(buffer)) { this.WriteToInternal(arrayItem, jsonWriter); } jsonWriter.WriteArrayEnd(); } break; case JsonNodeType.Object: { jsonWriter.WriteObjectStart(); foreach (ObjectPropertyInternal objectProperty in this.GetObjectPropertiesInternal(buffer)) { this.WriteToInternal(objectProperty.NameNode, jsonWriter); this.WriteToInternal(objectProperty.ValueNode, jsonWriter); } jsonWriter.WriteObjectEnd(); } break; case JsonNodeType.Int8: { sbyte value = JsonBinaryEncoding.GetInt8Value(buffer.Span); jsonWriter.WriteInt8Value(value); } break; case JsonNodeType.Int16: { short value = JsonBinaryEncoding.GetInt16Value(buffer.Span); jsonWriter.WriteInt16Value(value); } break; case JsonNodeType.Int32: { int value = JsonBinaryEncoding.GetInt32Value(buffer.Span); jsonWriter.WriteInt32Value(value); } break; case JsonNodeType.Int64: { long value = JsonBinaryEncoding.GetInt64Value(buffer.Span); jsonWriter.WriteInt64Value(value); } break; case JsonNodeType.UInt32: { uint value = JsonBinaryEncoding.GetUInt32Value(buffer.Span); jsonWriter.WriteUInt32Value(value); } break; case JsonNodeType.Float32: { float value = JsonBinaryEncoding.GetFloat32Value(buffer.Span); jsonWriter.WriteFloat32Value(value); } break; case JsonNodeType.Float64: { double value = JsonBinaryEncoding.GetFloat64Value(buffer.Span); jsonWriter.WriteFloat64Value(value); } break; case JsonNodeType.Binary: { ReadOnlyMemory <byte> value = JsonBinaryEncoding.GetBinaryValue(buffer); jsonWriter.WriteBinaryValue(value.Span); } break; case JsonNodeType.Guid: { Guid value = JsonBinaryEncoding.GetGuidValue(buffer.Span); jsonWriter.WriteGuidValue(value); } break; default: throw new ArgumentOutOfRangeException($"Unknown {nameof(JsonNodeType)}: {nodeType}."); } }
public static bool TryGetGuidValue( ReadOnlySpan <byte> guidToken, out Guid guidValue) => JsonBinaryEncoding.TryGetFixedWidthValue <Guid>( guidToken, JsonBinaryEncoding.TypeMarker.Guid, out guidValue);