/// <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 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); }