< Summary

Information
Line coverage
7%
Covered lines: 4
Uncovered lines: 50
Coverable lines: 54
Total lines: 318
Line coverage: 7.4%
Branch coverage
0%
Covered branches: 0
Total branches: 26
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%110%
WriteTo(...)100%110%
GetValue()0%220%
TryGetValue(...)0%24240%

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)
 35241            : base(options)
 35242        {
 35243            _value = utf8String;
 35244        }
 45
 046        internal override JsonNode DeepCloneCore() => new JsonValueOfJsonString(_value, Options);
 047        private protected override JsonValueKind GetValueKindCore() => JsonValueKind.String;
 48
 49        public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null)
 050        {
 051            ArgumentNullException.ThrowIfNull(writer);
 52
 053            writer.WriteStringValue(_value.Span);
 054        }
 55
 56        public override T GetValue<T>()
 057        {
 058            if (!TryGetValue(out T? value))
 059            {
 060                ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(JsonValueKind.String, typeof(T));
 61            }
 62
 063            return value;
 064        }
 65
 66        public override bool TryGetValue<T>([NotNullWhen(true)] out T? value)
 67            where T : default
 068        {
 069            if (typeof(T) == typeof(JsonElement))
 070            {
 071                value = (T)(object)JsonWriterHelper.WriteString(_value.Span, static serialized => JsonElement.Parse(seri
 072                return true;
 73            }
 74
 075            if (typeof(T) == typeof(string))
 076            {
 077                string? result = JsonReaderHelper.TranscodeHelper(_value.Span);
 78
 079                Debug.Assert(result != null);
 080                value = (T)(object)result;
 081                return true;
 82            }
 83
 84            bool success;
 85
 086            if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
 087            {
 088                success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out DateTime result);
 089                value = (T)(object)result;
 090                return success;
 91            }
 92
 093            if (typeof(T) == typeof(DateTimeOffset) || typeof(T) == typeof(DateTimeOffset?))
 094            {
 095                success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out DateTimeOffset result);
 096                value = (T)(object)result;
 097                return success;
 98            }
 99
 0100            if (typeof(T) == typeof(Guid) || typeof(T) == typeof(Guid?))
 0101            {
 0102                success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out Guid result);
 0103                value = (T)(object)result;
 0104                return success;
 105            }
 106
 0107            if (typeof(T) == typeof(char) || typeof(T) == typeof(char?))
 0108            {
 0109                string? result = JsonReaderHelper.TranscodeHelper(_value.Span);
 110
 0111                Debug.Assert(result != null);
 0112                if (result.Length == 1)
 0113                {
 0114                    value = (T)(object)result[0];
 0115                    return true;
 116                }
 0117            }
 118
 0119            value = default!;
 0120            return false;
 0121        }
 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)
 179            : base(options)
 180        {
 181            _value = number;
 182        }
 183
 184        internal override JsonNode DeepCloneCore() => new JsonValueOfJsonNumber(_value, Options);
 185        private protected override JsonValueKind GetValueKindCore() => JsonValueKind.Number;
 186
 187        public override T GetValue<T>()
 188        {
 189            if (!TryGetValue(out T? value))
 190            {
 191                ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(JsonValueKind.Number, typeof(T));
 192            }
 193
 194            return value;
 195        }
 196
 197        public override bool TryGetValue<T>([NotNullWhen(true)] out T? value)
 198            where T : default
 199        {
 200            if (typeof(T) == typeof(JsonElement))
 201            {
 202                value = (T)(object)JsonElement.Parse(_value);
 203                return true;
 204            }
 205
 206            bool success;
 207
 208            if (typeof(T) == typeof(int) || typeof(T) == typeof(int?))
 209            {
 210                success = Utf8Parser.TryParse(_value, out int result, out int consumed) &&
 211                            consumed == _value.Length;
 212
 213                value = (T)(object)result;
 214                return success;
 215            }
 216
 217            if (typeof(T) == typeof(long) || typeof(T) == typeof(long?))
 218            {
 219                success = Utf8Parser.TryParse(_value, out long result, out int consumed) &&
 220                            consumed == _value.Length;
 221
 222                value = (T)(object)result;
 223                return success;
 224            }
 225
 226            if (typeof(T) == typeof(double) || typeof(T) == typeof(double?))
 227            {
 228                success = Utf8Parser.TryParse(_value, out double result, out int consumed) &&
 229                            consumed == _value.Length;
 230
 231                value = (T)(object)result;
 232                return success;
 233            }
 234
 235            if (typeof(T) == typeof(short) || typeof(T) == typeof(short?))
 236            {
 237                success = Utf8Parser.TryParse(_value, out short result, out int consumed) &&
 238                            consumed == _value.Length;
 239
 240                value = (T)(object)result;
 241                return success;
 242            }
 243
 244            if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?))
 245            {
 246                success = Utf8Parser.TryParse(_value, out decimal result, out int consumed) &&
 247                            consumed == _value.Length;
 248
 249                value = (T)(object)result;
 250                return success;
 251            }
 252
 253            if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?))
 254            {
 255                success = Utf8Parser.TryParse(_value, out byte result, out int consumed) &&
 256                            consumed == _value.Length;
 257
 258                value = (T)(object)result;
 259                return success;
 260            }
 261
 262            if (typeof(T) == typeof(float) || typeof(T) == typeof(float?))
 263            {
 264                success = Utf8Parser.TryParse(_value, out float result, out int consumed) &&
 265                            consumed == _value.Length;
 266
 267                value = (T)(object)result;
 268                return success;
 269            }
 270
 271            if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?))
 272            {
 273                success = Utf8Parser.TryParse(_value, out uint result, out int consumed) &&
 274                            consumed == _value.Length;
 275
 276                value = (T)(object)result;
 277                return success;
 278            }
 279
 280            if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?))
 281            {
 282                success = Utf8Parser.TryParse(_value, out ushort result, out int consumed) &&
 283                            consumed == _value.Length;
 284
 285                value = (T)(object)result;
 286                return success;
 287            }
 288
 289            if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?))
 290            {
 291                success = Utf8Parser.TryParse(_value, out ulong result, out int consumed) &&
 292                            consumed == _value.Length;
 293
 294                value = (T)(object)result;
 295                return success;
 296            }
 297
 298            if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?))
 299            {
 300                success = Utf8Parser.TryParse(_value, out sbyte result, out int consumed) &&
 301                            consumed == _value.Length;
 302
 303                value = (T)(object)result;
 304                return success;
 305            }
 306
 307            value = default!;
 308            return false;
 309        }
 310
 311        public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null)
 312        {
 313            ArgumentNullException.ThrowIfNull(writer);
 314
 315            writer.WriteNumberValue(_value);
 316        }
 317    }
 318}