internal static void WriteDictionary <TProperty>(
            JsonValueConverter <TProperty> converter,
            JsonSerializerOptions options,
            ref WriteStackFrame current,
            Utf8JsonWriter writer)
        {
            if (converter == null)
            {
                return;
            }

            Debug.Assert(current.Enumerator != null);

            string    key;
            TProperty value;

            if (current.Enumerator is IEnumerator <KeyValuePair <string, TProperty> > enumerator)
            {
                // Avoid boxing for strongly-typed enumerators such as returned from IDictionary<string, TRuntimeProperty>
                value = enumerator.Current.Value;
                key   = enumerator.Current.Key;
            }
            else
            {
                // Todo: support non-generic Dictionary here (IDictionaryEnumerator)
                throw new NotSupportedException();
            }

            if (value == null)
            {
                writer.WriteNull(key);
            }
            else
            {
#if true
                // temporary behavior until the writer can accept escaped string.
                byte[] utf8Key = Encoding.UTF8.GetBytes(key);
                converter.Write(utf8Key, value, writer);
#else
                byte[] pooledKey = null;
                byte[] utf8Key   = Encoding.UTF8.GetBytes(key);
                int    length    = JsonWriterHelper.GetMaxEscapedLength(utf8Key.Length, 0);

                Span <byte> escapedKey = length <= JsonConstants.StackallocThreshold ?
                                         stackalloc byte[length] :
                                         (pooledKey = ArrayPool <byte> .Shared.Rent(length));

                JsonWriterHelper.EscapeString(utf8Key, escapedKey, 0, out int written);

                converter.Write(escapedKey.Slice(0, written), value, writer);

                if (pooledKey != null)
                {
                    // We clear the array because it is "user data" (although a property name).
                    new Span <byte>(pooledKey, 0, written).Clear();
                    ArrayPool <byte> .Shared.Return(pooledKey);
                }
#endif
            }
        }
Beispiel #2
0
        internal static void WriteDictionary <TProperty>(
            JsonValueConverter <TProperty> converter,
            JsonSerializerOptions options,
            ref WriteStackFrame current,
            Utf8JsonWriter writer)
        {
            if (converter == null)
            {
                return;
            }

            Debug.Assert(current.Enumerator != null);

            string    key;
            TProperty value;

            if (current.Enumerator is IEnumerator <KeyValuePair <string, TProperty> > enumerator)
            {
                // Avoid boxing for strongly-typed enumerators such as returned from IDictionary<string, TRuntimeProperty>
                value = enumerator.Current.Value;
                key   = enumerator.Current.Key;
            }
            else if (current.Enumerator is IEnumerator <KeyValuePair <string, object> > polymorphicEnumerator)
            {
                value = (TProperty)polymorphicEnumerator.Current.Value;
                key   = polymorphicEnumerator.Current.Key;
            }
            else if (current.IsImmutableDictionary || current.IsImmutableDictionaryProperty)
            {
                value = (TProperty)((DictionaryEntry)current.Enumerator.Current).Value;
                key   = (string)((DictionaryEntry)current.Enumerator.Current).Key;
            }
            else
            {
                // Todo: support non-generic Dictionary here (IDictionaryEnumerator)
                throw new NotSupportedException();
            }

            if (value == null)
            {
                writer.WriteNull(key);
            }
            else
            {
                JsonEncodedText escapedKey = JsonEncodedText.Encode(key);
                converter.Write(escapedKey, value, writer);
            }
        }