< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 65
Coverable lines: 65
Total lines: 193
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 22
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%110%
Encode(...)100%110%
Encode(...)0%220%
TranscodeAndEncode(...)0%440%
Encode(...)0%220%
EncodeHelper(...)0%220%
Equals(...)0%220%
Equals(...)0%440%
ToString()0%220%
GetHashCode()0%220%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/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)
 033        {
 034            Debug.Assert(utf8Value is not null);
 35
 036            _value = JsonReaderHelper.GetTextFromUtf8(utf8Value);
 037            _utf8Value = utf8Value;
 038        }
 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)
 052        {
 053            ArgumentNullException.ThrowIfNull(value);
 54
 055            return Encode(value.AsSpan(), encoder);
 056        }
 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)
 067        {
 068            if (value.Length == 0)
 069            {
 070                return new JsonEncodedText(Array.Empty<byte>());
 71            }
 72
 073            return TranscodeAndEncode(value, encoder);
 074        }
 75
 76        private static unsafe JsonEncodedText TranscodeAndEncode(ReadOnlySpan<char> value, JavaScriptEncoder? encoder)
 077        {
 078            JsonWriterHelper.ValidateValue(value);
 79
 080            int expectedByteCount = JsonReaderHelper.GetUtf8ByteCount(value);
 81
 082            byte[]? array = null;
 083            Span<byte> utf8Bytes = expectedByteCount <= JsonConstants.StackallocByteThreshold ?
 084                stackalloc byte[JsonConstants.StackallocByteThreshold] :
 085                (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.
 089            int actualByteCount = JsonReaderHelper.GetUtf8FromText(value, utf8Bytes);
 090            utf8Bytes = utf8Bytes.Slice(0, actualByteCount);
 091            Debug.Assert(expectedByteCount == utf8Bytes.Length);
 92
 093            JsonEncodedText encodedText = EncodeHelper(utf8Bytes, encoder);
 94
 095            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
 0102            return encodedText;
 0103        }
 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)
 0125        {
 0126            int idx = JsonWriterHelper.NeedsEscaping(utf8Value, encoder);
 127
 0128            if (idx != -1)
 0129            {
 0130                return new JsonEncodedText(JsonHelpers.EscapeValue(utf8Value, idx, encoder));
 131            }
 132            else
 0133            {
 0134                return new JsonEncodedText(utf8Value.ToArray());
 135            }
 0136        }
 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 is null)
 0147            {
 0148                return other._value is 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?.GetHashCode() ?? 0;
 191    }
 192}
 193