< Summary

Information
Line coverage
0%
Covered lines: 0
Uncovered lines: 66
Coverable lines: 66
Total lines: 116
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 32
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
Add(System.String,System.Object& modreq(...)0%660%
CreateCollection(...)0%220%
OnWriteResume(...)0%18180%
ConfigureJsonTypeInfo(...)0%660%

File(s)

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\Serialization\Converters\Collection\IDictionaryConverter.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.Collections;
 5using System.Collections.Generic;
 6using System.Diagnostics;
 7using System.Text.Json.Serialization.Metadata;
 8
 9namespace System.Text.Json.Serialization.Converters
 10{
 11    /// <summary>
 12    /// Converter for <cref>System.Collections.IDictionary</cref> that (de)serializes as a JSON object with properties
 13    /// representing the dictionary element key and value.
 14    /// </summary>
 15    internal sealed class IDictionaryConverter<TDictionary>
 16        : JsonDictionaryConverter<TDictionary, string, object?>
 17        where TDictionary : IDictionary
 18    {
 019        internal override bool CanPopulate => true;
 20
 21        protected override void Add(string key, in object? value, JsonSerializerOptions options, ref ReadStack state)
 022        {
 023            TDictionary collection = (TDictionary)state.Current.ReturnValue!;
 24
 025            if (!options.AllowDuplicateProperties && collection.Contains(key))
 026            {
 027                ThrowHelper.ThrowJsonException_DuplicatePropertyNotAllowed(key);
 28            }
 29
 030            collection[key] = value;
 31
 032            if (IsValueType)
 033            {
 034                state.Current.ReturnValue = collection;
 035            }
 036        }
 37
 38        protected override void CreateCollection(ref Utf8JsonReader reader, scoped ref ReadStack state)
 039        {
 040            base.CreateCollection(ref reader, ref state);
 041            TDictionary returnValue = (TDictionary)state.Current.ReturnValue!;
 042            if (returnValue.IsReadOnly)
 043            {
 044                state.Current.ReturnValue = null; // clear out for more accurate JsonPath reporting.
 045                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
 46            }
 047        }
 48
 49        protected internal override bool OnWriteResume(Utf8JsonWriter writer, TDictionary value, JsonSerializerOptions o
 050        {
 51            IDictionaryEnumerator enumerator;
 052            if (state.Current.CollectionEnumerator == null)
 053            {
 054                enumerator = value.GetEnumerator();
 055                state.Current.CollectionEnumerator = enumerator;
 056                if (!enumerator.MoveNext())
 057                {
 058                    return true;
 59                }
 060            }
 61            else
 062            {
 063                enumerator = (IDictionaryEnumerator)state.Current.CollectionEnumerator;
 064            }
 65
 066            JsonTypeInfo typeInfo = state.Current.JsonTypeInfo;
 067            _valueConverter ??= GetConverter<object?>(typeInfo.ElementTypeInfo!);
 68
 69            do
 070            {
 071                if (ShouldFlush(ref state, writer))
 072                {
 073                    return false;
 74                }
 75
 076                if (state.Current.PropertyState < StackFramePropertyState.Name)
 077                {
 078                    state.Current.PropertyState = StackFramePropertyState.Name;
 079                    object key = enumerator.Key;
 80                    // Optimize for string since that's the hot path.
 081                    if (key is string keyString)
 082                    {
 083                        _keyConverter ??= GetConverter<string>(typeInfo.KeyTypeInfo!);
 084                        _keyConverter.WriteAsPropertyNameCore(writer, keyString, options, state.Current.IsWritingExtensi
 085                    }
 86                    else
 087                    {
 88                        // IDictionary is a special case since it has polymorphic object semantics on serialization
 89                        // but needs to use JsonConverter<string> on deserialization.
 090                        _valueConverter.WriteAsPropertyNameCore(writer, key, options, state.Current.IsWritingExtensionDa
 091                    }
 092                }
 93
 094                object? element = enumerator.Value;
 095                if (!_valueConverter.TryWrite(writer, element, options, ref state))
 096                {
 097                    return false;
 98                }
 99
 0100                state.Current.EndDictionaryEntry();
 0101            } while (enumerator.MoveNext());
 102
 0103            return true;
 0104        }
 105
 106        internal override void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options)
 0107        {
 108            // Deserialize as Dictionary<TKey,TValue> for interface types that support it.
 0109            if (jsonTypeInfo.CreateObject is null && Type.IsAssignableFrom(typeof(Dictionary<string, object?>)))
 0110            {
 0111                Debug.Assert(Type.IsInterface);
 0112                jsonTypeInfo.CreateObject = () => new Dictionary<string, object?>();
 0113            }
 0114        }
 115    }
 116}