< Summary

Information
Line coverage
50%
Covered lines: 33
Uncovered lines: 32
Coverable lines: 65
Total lines: 192
Line coverage: 50.7%
Branch coverage
18%
Covered branches: 4
Total branches: 22
Branch coverage: 18.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
Encode(...)100%11100%
Encode(...)50%2266.66%
TranscodeAndEncode(...)50%4477.77%
Encode(...)0%220%
EncodeHelper(...)50%2275%
Equals(...)0%220%
Equals(...)0%440%
ToString()0%220%
GetHashCode()0%220%

File(s)

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\JsonEncodedText.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.Diagnostics;
 6using System.Diagnostics.CodeAnalysis;
 7using System.Text.Encodings.Web;
 8
 9namespace System.Text.Json
 10{
 11    /// <summary>
 12    /// Provides a way to transform UTF-8 or UTF-16 encoded text into a form that is suitable for JSON.
 13    /// </summary>
 14    /// <remarks>
 15    /// This can be used to cache and store known strings used for writing JSON ahead of time by pre-encoding them up fr
 16    /// </remarks>
 17    public readonly struct JsonEncodedText : IEquatable<JsonEncodedText>
 18    {
 19        internal readonly byte[] _utf8Value;
 20        internal readonly string _value;
 21
 22        /// <summary>
 23        /// Returns the UTF-8 encoded representation of the pre-encoded JSON text.
 24        /// </summary>
 025        public ReadOnlySpan<byte> EncodedUtf8Bytes => _utf8Value;
 26
 27        /// <summary>
 28        /// Returns the UTF-16 encoded representation of the pre-encoded JSON text as a <see cref="string"/>.
 29        /// </summary>
 030        public string Value => _value ?? string.Empty;
 31
 32        private JsonEncodedText(byte[] utf8Value)
 433        {
 434            Debug.Assert(utf8Value != null);
 35
 436            _value = JsonReaderHelper.GetTextFromUtf8(utf8Value);
 437            _utf8Value = utf8Value;
 438        }
 39
 40        /// <summary>
 41        /// Encodes the string text value as a JSON string.
 42        /// </summary>
 43        /// <param name="value">The value to be transformed as JSON encoded text.</param>
 44        /// <param name="encoder">The encoder to use when escaping the string, or <see langword="null" /> to use the def
 45        /// <exception cref="ArgumentNullException">
 46        /// Thrown if value is null.
 47        /// </exception>
 48        /// <exception cref="ArgumentException">
 49        /// Thrown when the specified value is too large or if it contains invalid UTF-16 characters.
 50        /// </exception>
 51        public static JsonEncodedText Encode(string value, JavaScriptEncoder? encoder = null)
 452        {
 453            ArgumentNullException.ThrowIfNull(value);
 54
 455            return Encode(value.AsSpan(), encoder);
 456        }
 57
 58        /// <summary>
 59        /// Encodes the text value as a JSON string.
 60        /// </summary>
 61        /// <param name="value">The value to be transformed as JSON encoded text.</param>
 62        /// <param name="encoder">The encoder to use when escaping the string, or <see langword="null" /> to use the def
 63        /// <exception cref="ArgumentException">
 64        /// Thrown when the specified value is too large or if it contains invalid UTF-16 characters.
 65        /// </exception>
 66        public static JsonEncodedText Encode(ReadOnlySpan<char> value, JavaScriptEncoder? encoder = null)
 467        {
 468            if (value.Length == 0)
 069            {
 070                return new JsonEncodedText(Array.Empty<byte>());
 71            }
 72
 473            return TranscodeAndEncode(value, encoder);
 474        }
 75
 76        private static JsonEncodedText TranscodeAndEncode(ReadOnlySpan<char> value, JavaScriptEncoder? encoder)
 477        {
 478            JsonWriterHelper.ValidateValue(value);
 79
 480            int expectedByteCount = JsonReaderHelper.GetUtf8ByteCount(value);
 81
 482            byte[]? array = null;
 483            Span<byte> utf8Bytes = expectedByteCount <= JsonConstants.StackallocByteThreshold ?
 484                stackalloc byte[JsonConstants.StackallocByteThreshold] :
 485                (array = ArrayPool<byte>.Shared.Rent(expectedByteCount));
 86
 87            // Since GetUtf8ByteCount above already throws on invalid input, the transcoding
 88            // to UTF-8 is guaranteed to succeed here. Therefore, there's no need for a try-catch-finally block.
 489            int actualByteCount = JsonReaderHelper.GetUtf8FromText(value, utf8Bytes);
 490            utf8Bytes = utf8Bytes.Slice(0, actualByteCount);
 491            Debug.Assert(expectedByteCount == utf8Bytes.Length);
 92
 493            JsonEncodedText encodedText = EncodeHelper(utf8Bytes, encoder);
 94
 495            if (array is not null)
 096            {
 97                // On the basis that this is user data, go ahead and clear it.
 098                utf8Bytes.Clear();
 099                ArrayPool<byte>.Shared.Return(array);
 0100            }
 101
 4102            return encodedText;
 4103        }
 104
 105        /// <summary>
 106        /// Encodes the UTF-8 text value as a JSON string.
 107        /// </summary>
 108        /// <param name="utf8Value">The UTF-8 encoded value to be transformed as JSON encoded text.</param>
 109        /// <param name="encoder">The encoder to use when escaping the string, or <see langword="null" /> to use the def
 110        /// <exception cref="ArgumentException">
 111        /// Thrown when the specified value is too large or if it contains invalid UTF-8 bytes.
 112        /// </exception>
 113        public static JsonEncodedText Encode(ReadOnlySpan<byte> utf8Value, JavaScriptEncoder? encoder = null)
 0114        {
 0115            if (utf8Value.Length == 0)
 0116            {
 0117                return new JsonEncodedText(Array.Empty<byte>());
 118            }
 119
 0120            JsonWriterHelper.ValidateValue(utf8Value);
 0121            return EncodeHelper(utf8Value, encoder);
 0122        }
 123
 124        private static JsonEncodedText EncodeHelper(ReadOnlySpan<byte> utf8Value, JavaScriptEncoder? encoder)
 4125        {
 4126            int idx = JsonWriterHelper.NeedsEscaping(utf8Value, encoder);
 127
 4128            if (idx != -1)
 0129            {
 0130                return new JsonEncodedText(JsonHelpers.EscapeValue(utf8Value, idx, encoder));
 131            }
 132            else
 4133            {
 4134                return new JsonEncodedText(utf8Value.ToArray());
 135            }
 4136        }
 137
 138        /// <summary>
 139        /// Determines whether this instance and another specified <see cref="JsonEncodedText"/> instance have the same 
 140        /// </summary>
 141        /// <remarks>
 142        /// Default instances of <see cref="JsonEncodedText"/> are treated as equal.
 143        /// </remarks>
 144        public bool Equals(JsonEncodedText other)
 0145        {
 0146            if (_value == null)
 0147            {
 0148                return other._value == null;
 149            }
 150            else
 0151            {
 0152                return _value.Equals(other._value);
 153            }
 0154        }
 155
 156        /// <summary>
 157        /// Determines whether this instance and a specified object, which must also be a <see cref="JsonEncodedText"/> 
 158        /// </summary>
 159        /// <remarks>
 160        /// If <paramref name="obj"/> is null, the method returns false.
 161        /// </remarks>
 162        public override bool Equals([NotNullWhen(true)] object? obj)
 0163        {
 0164            if (obj is JsonEncodedText encodedText)
 0165            {
 0166                return Equals(encodedText);
 167            }
 0168            return false;
 0169        }
 170
 171        /// <summary>
 172        /// Converts the value of this instance to a <see cref="string"/>.
 173        /// </summary>
 174        /// <remarks>
 175        /// Returns an empty string on a default instance of <see cref="JsonEncodedText"/>.
 176        /// </remarks>
 177        /// <returns>
 178        /// Returns the underlying UTF-16 encoded string.
 179        /// </returns>
 180        public override string ToString()
 0181            => _value ?? string.Empty;
 182
 183        /// <summary>
 184        /// Returns the hash code for this <see cref="JsonEncodedText"/>.
 185        /// </summary>
 186        /// <remarks>
 187        /// Returns 0 on a default instance of <see cref="JsonEncodedText"/>.
 188        /// </remarks>
 189        public override int GetHashCode()
 0190            => _value == null ? 0 : _value.GetHashCode();
 191    }
 192}