< Summary

Information
Line coverage
10%
Covered lines: 9
Uncovered lines: 81
Coverable lines: 90
Total lines: 318
Line coverage: 10%
Branch coverage
0%
Covered branches: 0
Total branches: 70
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
DeepCloneCore()100%110%
GetValueKindCore()100%11100%
GetValue()0%220%
TryGetValue(...)0%68680%
WriteTo(...)100%11100%

File(s)

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\Nodes\JsonValueOfJsonPrimitive.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Buffers;
 5using System.Buffers.Text;
 6using System.Diagnostics;
 7using System.Diagnostics.CodeAnalysis;
 8using System.Text.Encodings.Web;
 9
 10namespace System.Text.Json.Nodes
 11{
 12    internal static class JsonValueOfJsonPrimitive
 13    {
 14        internal static JsonValue CreatePrimitiveValue(ref Utf8JsonReader reader, JsonNodeOptions options)
 15        {
 16            switch (reader.TokenType)
 17            {
 18                case JsonTokenType.False:
 19                case JsonTokenType.True:
 20                    return new JsonValueOfJsonBool(reader.GetBoolean(), options);
 21                case JsonTokenType.String:
 22                    byte[] buffer = new byte[reader.ValueLength];
 23                    ReadOnlyMemory<byte> utf8String = buffer.AsMemory(0, reader.CopyString(buffer));
 24                    return new JsonValueOfJsonString(utf8String, options);
 25                case JsonTokenType.Number:
 26                    byte[] numberValue = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan.ToA
 27                    return new JsonValueOfJsonNumber(numberValue, options);
 28                default:
 29                    Debug.Fail("Only primitives allowed.");
 30                    ThrowHelper.ThrowJsonException();
 31                    return null!; // Unreachable, but required for compilation.
 32            }
 33        }
 34    }
 35
 36    internal sealed class JsonValueOfJsonString : JsonValue
 37    {
 38        private readonly ReadOnlyMemory<byte> _value;
 39
 40        internal JsonValueOfJsonString(ReadOnlyMemory<byte> utf8String, JsonNodeOptions? options)
 41            : base(options)
 42        {
 43            _value = utf8String;
 44        }
 45
 46        internal override JsonNode DeepCloneCore() => new JsonValueOfJsonString(_value, Options);
 47        private protected override JsonValueKind GetValueKindCore() => JsonValueKind.String;
 48
 49        public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null)
 50        {
 51            ArgumentNullException.ThrowIfNull(writer);
 52
 53            writer.WriteStringValue(_value.Span);
 54        }
 55
 56        public override T GetValue<T>()
 57        {
 58            if (!TryGetValue(out T? value))
 59            {
 60                ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(JsonValueKind.String, typeof(T));
 61            }
 62
 63            return value;
 64        }
 65
 66        public override bool TryGetValue<T>([NotNullWhen(true)] out T? value)
 67            where T : default
 68        {
 69            if (typeof(T) == typeof(JsonElement))
 70            {
 71                value = (T)(object)JsonWriterHelper.WriteString(_value.Span, static serialized => JsonElement.Parse(seri
 72                return true;
 73            }
 74
 75            if (typeof(T) == typeof(string))
 76            {
 77                string? result = JsonReaderHelper.TranscodeHelper(_value.Span);
 78
 79                Debug.Assert(result != null);
 80                value = (T)(object)result;
 81                return true;
 82            }
 83
 84            bool success;
 85
 86            if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
 87            {
 88                success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out DateTime result);
 89                value = (T)(object)result;
 90                return success;
 91            }
 92
 93            if (typeof(T) == typeof(DateTimeOffset) || typeof(T) == typeof(DateTimeOffset?))
 94            {
 95                success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out DateTimeOffset result);
 96                value = (T)(object)result;
 97                return success;
 98            }
 99
 100            if (typeof(T) == typeof(Guid) || typeof(T) == typeof(Guid?))
 101            {
 102                success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out Guid result);
 103                value = (T)(object)result;
 104                return success;
 105            }
 106
 107            if (typeof(T) == typeof(char) || typeof(T) == typeof(char?))
 108            {
 109                string? result = JsonReaderHelper.TranscodeHelper(_value.Span);
 110
 111                Debug.Assert(result != null);
 112                if (result.Length == 1)
 113                {
 114                    value = (T)(object)result[0];
 115                    return true;
 116                }
 117            }
 118
 119            value = default!;
 120            return false;
 121        }
 122    }
 123
 124    internal sealed class JsonValueOfJsonBool : JsonValue
 125    {
 126        private readonly bool _value;
 127
 128        private JsonValueKind ValueKind => _value ? JsonValueKind.True : JsonValueKind.False;
 129
 130        internal JsonValueOfJsonBool(bool value, JsonNodeOptions? options)
 131            : base(options)
 132        {
 133            _value = value;
 134        }
 135
 136        public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null) => writer.WriteBoolea
 137        internal override JsonNode DeepCloneCore() => new JsonValueOfJsonBool(_value, Options);
 138        private protected override JsonValueKind GetValueKindCore() => ValueKind;
 139
 140        public override T GetValue<T>()
 141        {
 142            if (!TryGetValue(out T? value))
 143            {
 144                ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(_value ? JsonValueKind.True : Json
 145            }
 146
 147            return value;
 148        }
 149
 150        public override bool TryGetValue<T>([NotNullWhen(true)] out T? value)
 151            where T : default
 152        {
 153            if (typeof(T) == typeof(JsonElement))
 154            {
 155                value = (T)(object)JsonElement.Parse(_value ? JsonConstants.TrueValue : JsonConstants.FalseValue);
 156                return true;
 157            }
 158
 159            if (typeof(T) == typeof(bool) || typeof(T) == typeof(bool?))
 160            {
 161                value = (T)(object)_value;
 162                return true;
 163            }
 164
 165            value = default!;
 166            return false;
 167        }
 168    }
 169
 170    internal sealed class JsonValueOfJsonNumber : JsonValue
 171    {
 172        // This can be optimized to store the decimal point position and the exponent so that
 173        // conversion to different numeric types can be done without parsing the string again.
 174        // Utf8Parser uses an internal ref struct, Number.NumberBuffer, which is really the
 175        // same functionality that we would want here.
 176        private readonly byte[] _value;
 177
 178        internal JsonValueOfJsonNumber(byte[] number, JsonNodeOptions? options)
 256179            : base(options)
 256180        {
 256181            _value = number;
 256182        }
 183
 0184        internal override JsonNode DeepCloneCore() => new JsonValueOfJsonNumber(_value, Options);
 28185        private protected override JsonValueKind GetValueKindCore() => JsonValueKind.Number;
 186
 187        public override T GetValue<T>()
 0188        {
 0189            if (!TryGetValue(out T? value))
 0190            {
 0191                ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(JsonValueKind.Number, typeof(T));
 192            }
 193
 0194            return value;
 0195        }
 196
 197        public override bool TryGetValue<T>([NotNullWhen(true)] out T? value)
 198            where T : default
 0199        {
 0200            if (typeof(T) == typeof(JsonElement))
 0201            {
 0202                value = (T)(object)JsonElement.Parse(_value);
 0203                return true;
 204            }
 205
 206            bool success;
 207
 0208            if (typeof(T) == typeof(int) || typeof(T) == typeof(int?))
 0209            {
 0210                success = Utf8Parser.TryParse(_value, out int result, out int consumed) &&
 0211                            consumed == _value.Length;
 212
 0213                value = (T)(object)result;
 0214                return success;
 215            }
 216
 0217            if (typeof(T) == typeof(long) || typeof(T) == typeof(long?))
 0218            {
 0219                success = Utf8Parser.TryParse(_value, out long result, out int consumed) &&
 0220                            consumed == _value.Length;
 221
 0222                value = (T)(object)result;
 0223                return success;
 224            }
 225
 0226            if (typeof(T) == typeof(double) || typeof(T) == typeof(double?))
 0227            {
 0228                success = Utf8Parser.TryParse(_value, out double result, out int consumed) &&
 0229                            consumed == _value.Length;
 230
 0231                value = (T)(object)result;
 0232                return success;
 233            }
 234
 0235            if (typeof(T) == typeof(short) || typeof(T) == typeof(short?))
 0236            {
 0237                success = Utf8Parser.TryParse(_value, out short result, out int consumed) &&
 0238                            consumed == _value.Length;
 239
 0240                value = (T)(object)result;
 0241                return success;
 242            }
 243
 0244            if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?))
 0245            {
 0246                success = Utf8Parser.TryParse(_value, out decimal result, out int consumed) &&
 0247                            consumed == _value.Length;
 248
 0249                value = (T)(object)result;
 0250                return success;
 251            }
 252
 0253            if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?))
 0254            {
 0255                success = Utf8Parser.TryParse(_value, out byte result, out int consumed) &&
 0256                            consumed == _value.Length;
 257
 0258                value = (T)(object)result;
 0259                return success;
 260            }
 261
 0262            if (typeof(T) == typeof(float) || typeof(T) == typeof(float?))
 0263            {
 0264                success = Utf8Parser.TryParse(_value, out float result, out int consumed) &&
 0265                            consumed == _value.Length;
 266
 0267                value = (T)(object)result;
 0268                return success;
 269            }
 270
 0271            if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?))
 0272            {
 0273                success = Utf8Parser.TryParse(_value, out uint result, out int consumed) &&
 0274                            consumed == _value.Length;
 275
 0276                value = (T)(object)result;
 0277                return success;
 278            }
 279
 0280            if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?))
 0281            {
 0282                success = Utf8Parser.TryParse(_value, out ushort result, out int consumed) &&
 0283                            consumed == _value.Length;
 284
 0285                value = (T)(object)result;
 0286                return success;
 287            }
 288
 0289            if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?))
 0290            {
 0291                success = Utf8Parser.TryParse(_value, out ulong result, out int consumed) &&
 0292                            consumed == _value.Length;
 293
 0294                value = (T)(object)result;
 0295                return success;
 296            }
 297
 0298            if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?))
 0299            {
 0300                success = Utf8Parser.TryParse(_value, out sbyte result, out int consumed) &&
 0301                            consumed == _value.Length;
 302
 0303                value = (T)(object)result;
 0304                return success;
 305            }
 306
 0307            value = default!;
 0308            return false;
 0309        }
 310
 311        public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null)
 28312        {
 28313            ArgumentNullException.ThrowIfNull(writer);
 314
 28315            writer.WriteNumberValue(_value);
 28316        }
 317    }
 318}