Example #1
0
        public override void WriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer)
        {
            Debug.Assert(ShouldSerialize);

            if (ValueConverter != null)
            {
                Debug.Assert(current.Enumerator != null);

                TRuntimeProperty value;
                if (current.Enumerator is IEnumerator <TRuntimeProperty> enumerator)
                {
                    // Avoid boxing for strongly-typed enumerators such as returned from IList<T>.
                    value = enumerator.Current;
                }
                else
                {
                    value = (TRuntimeProperty)current.Enumerator.Current;
                }

                if (value == null)
                {
                    writer.WriteNullValue();
                }
                else
                {
                    ValueConverter.Write(value, writer);
                }
            }
        }
        protected override void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer)
        {
            if (Converter != null)
            {
                Debug.Assert(current.CollectionEnumerator != null);

                TConverter value;
                if (current.CollectionEnumerator is IEnumerator <TConverter> enumerator)
                {
                    // Avoid boxing for strongly-typed enumerators such as returned from IList<T>.
                    value = enumerator.Current;
                }
                else
                {
                    value = (TConverter)current.CollectionEnumerator.Current !;
                }

                if (value == null)
                {
                    writer.WriteNullValue();
                }
                else
                {
                    Converter.Write(writer, value, Options);
                }
            }
        }
        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
            }
        }
        protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writer)
        {
            TConverter value;

            if (IsPropertyPolicy)
            {
                value = (TConverter)current.CurrentValue !;
            }
            else
            {
                Debug.Assert(Get != null);
                value = (TConverter)Get(current.CurrentValue);
            }

            if (value == null)
            {
                Debug.Assert(EscapedName.HasValue);

                if (!IgnoreNullValues)
                {
                    writer.WriteNull(EscapedName.Value);
                }
            }
            else if (Converter != null)
            {
                if (EscapedName.HasValue)
                {
                    writer.WritePropertyName(EscapedName.Value);
                }

                Converter.Write(writer, value, Options);
            }
        }
        public override void WriteEnumerable(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer)
        {
            Debug.Assert(ShouldSerialize);

            if (ValueConverter != null)
            {
                Debug.Assert(current.Enumerator != null);

                TProperty?value;
                if (current.Enumerator is IEnumerator <TProperty?> enumerator)
                {
                    // Avoid boxing for strongly-typed enumerators such as returned from IList<T>.
                    value = enumerator.Current;
                }
                else
                {
                    value = (TProperty?)current.Enumerator.Current;
                }

                if (value == null)
                {
                    writer.WriteNullValue();
                }
                else
                {
                    ValueConverter.Write(value.GetValueOrDefault(), writer);
                }
            }
        }
        private static bool WriteValue(
            JsonSerializerOptions options,
            ref Utf8JsonWriter writer,
            ref WriteStackFrame current)
        {
            Debug.Assert(current.JsonPropertyInfo.ClassType == ClassType.Value);

            current.JsonPropertyInfo.Write(options, ref current, ref writer);
            return(true);
        }
Example #7
0
        // There are three conditions to consider for an object (primitive value, enumerable or object) being processed here:
        // 1) The object type was specified as the root-level return type to a Parse\Read method.
        // 2) The object is property on a parent object.
        // 3) The object is an element in an enumerable.
        private static bool Write(
            Utf8JsonWriter writer,
            int flushThreshold,
            JsonSerializerOptions options,
            ref WriteStack state)
        {
            bool continueWriting = true;
            bool finishedSerializing;

            do
            {
                WriteStackFrame current = state.Current;
                switch (current.JsonClassInfo.ClassType)
                {
                case ClassType.Enumerable:
                    finishedSerializing = HandleEnumerable(current.JsonClassInfo.ElementClassInfo, options, writer, ref state);
                    break;

                case ClassType.Value:
                    Debug.Assert(current.JsonPropertyInfo.ClassType == ClassType.Value);
                    current.JsonPropertyInfo.Write(ref current, writer);
                    finishedSerializing = true;
                    break;

                case ClassType.Object:
                    finishedSerializing = WriteObject(options, writer, ref state);
                    break;

                case ClassType.Dictionary:
                case ClassType.ImmutableDictionary:
                    finishedSerializing = HandleDictionary(current.JsonClassInfo.ElementClassInfo, options, writer, ref state);
                    break;

                default:
                    Debug.Assert(state.Current.JsonClassInfo.ClassType == ClassType.Unknown);

                    // Treat typeof(object) as an empty object.
                    finishedSerializing = WriteObject(options, writer, ref state);
                    break;
                }

                if (flushThreshold >= 0 && writer.BytesPending > flushThreshold)
                {
                    return(false);
                }

                if (finishedSerializing && writer.CurrentDepth == 0)
                {
                    continueWriting = false;
                }
            } while (continueWriting);

            return(true);
        }
 public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object?value)
 {
     if (writeStackFrame.CollectionEnumerator is IEnumerator <KeyValuePair <string, TDeclaredProperty> > genericEnumerator)
     {
         key   = genericEnumerator.Current.Key;
         value = genericEnumerator.Current.Value;
     }
     else
     {
         throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(
                   writeStackFrame.JsonPropertyInfo !.DeclaredPropertyType,
                   writeStackFrame.JsonPropertyInfo.ParentClassType,
                   writeStackFrame.JsonPropertyInfo.PropertyInfo);
     }
 }
Example #9
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);
            }
        }
 internal override void WriteEnumerable(JsonSerializerOptions options, ref WriteStackFrame current, ref Utf8JsonWriter writer)
 {
     if (ValueConverter != null)
     {
         Debug.Assert(current.Enumerator != null);
         TRuntimeProperty value = (TRuntimeProperty)current.Enumerator.Current;
         if (value == null)
         {
             writer.WriteNullValue();
         }
         else
         {
             ValueConverter.Write(value, ref writer);
         }
     }
 }
        private static void WriteExtensionData(Utf8JsonWriter writer, ref WriteStackFrame frame)
        {
            DictionaryEntry entry = ((IDictionaryEnumerator)frame.Enumerator).Entry;

            if (entry.Value is JsonElement element)
            {
                Debug.Assert(entry.Key is string);

                string propertyName = (string)entry.Key;
                element.WriteAsProperty(propertyName, writer);
            }
            else
            {
                ThrowHelper.ThrowInvalidOperationException_SerializationDataExtensionPropertyInvalid(frame.JsonClassInfo, entry.Value.GetType());
            }
        }
Example #12
0
        // todo: have the caller check if current.Enumerator != null and call WriteEnumerable of the underlying property directly to avoid an extra virtual call.
        internal override void Write(JsonSerializerOptions options, ref WriteStackFrame current, ref Utf8JsonWriter writer)
        {
            if (current.Enumerator != null)
            {
                // Forward the setter to the value-based JsonPropertyInfo.
                JsonPropertyInfo propertyInfo = ElementClassInfo.GetPolicyProperty();
                propertyInfo.WriteEnumerable(options, ref current, ref writer);
            }
            else if (ShouldSerialize)
            {
                TRuntimeProperty value;
                if (_isPropertyPolicy)
                {
                    value = (TRuntimeProperty)current.CurrentValue;
                }
                else
                {
                    value = (TRuntimeProperty)Get((TClass)current.CurrentValue);
                }

                if (value == null)
                {
                    if (_escapedName == null)
                    {
                        writer.WriteNullValue();
                    }
                    else if (!IgnoreNullValues)
                    {
                        writer.WriteNull(_escapedName);
                    }
                }
                else if (ValueConverter != null)
                {
                    if (_escapedName != null)
                    {
                        ValueConverter.Write(_escapedName, value, ref writer);
                    }
                    else
                    {
                        ValueConverter.Write(value, ref writer);
                    }
                }
            }
        }
        public override void Write(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer)
        {
            Debug.Assert(ShouldSerialize);

            if (current.Enumerator != null)
            {
                // Forward the setter to the value-based JsonPropertyInfo.
                JsonPropertyInfo propertyInfo = ElementClassInfo.GetPolicyProperty();
                propertyInfo.WriteEnumerable(options, ref current, writer);
            }
            else
            {
                TProperty?value;
                if (IsPropertyPolicy)
                {
                    value = (TProperty?)current.CurrentValue;
                }
                else
                {
                    value = Get((TClass)current.CurrentValue);
                }

                if (value == null)
                {
                    Debug.Assert(EscapedName != null);

                    if (!IgnoreNullValues)
                    {
                        writer.WriteNull(EscapedName);
                    }
                }
                else if (ValueConverter != null)
                {
                    if (EscapedName != null)
                    {
                        ValueConverter.Write(EscapedName, value.GetValueOrDefault(), writer);
                    }
                    else
                    {
                        ValueConverter.Write(value.GetValueOrDefault(), writer);
                    }
                }
            }
        }
        public override void Write(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer)
        {
            Debug.Assert(current.Enumerator == null);

            if (ShouldSerialize)
            {
                TRuntimeProperty value;
                if (_isPropertyPolicy)
                {
                    value = (TRuntimeProperty)current.CurrentValue;
                }
                else
                {
                    value = (TRuntimeProperty)Get((TClass)current.CurrentValue);
                }

                if (value == null)
                {
                    Debug.Assert(_escapedName != null);

                    if (!IgnoreNullValues)
                    {
                        writer.WriteNull(_escapedName);
                    }
                }
                else if (ValueConverter != null)
                {
                    if (_escapedName != null)
                    {
                        ValueConverter.Write(_escapedName, value, writer);
                    }
                    else
                    {
                        ValueConverter.Write(value, writer);
                    }
                }
            }
        }
Example #15
0
        public void Push()
        {
            if (_previous == null)
            {
                _previous = new List <WriteStackFrame>();
            }

            if (_index == _previous.Count)
            {
                // Need to allocate a new array element.
                _previous.Add(Current);
            }
            else
            {
                Debug.Assert(_index < _previous.Count);

                // Use a previously allocated slot.
                Current = _previous[_index];
            }

            Current.Reset();
            _index++;
        }
Example #16
0
        public override void Write(ref WriteStackFrame current, Utf8JsonWriter writer)
        {
            Debug.Assert(current.Enumerator == null);
            Debug.Assert(ShouldSerialize);

            TRuntimeProperty value;

            if (IsPropertyPolicy)
            {
                value = (TRuntimeProperty)current.CurrentValue;
            }
            else
            {
                value = (TRuntimeProperty)Get(current.CurrentValue);
            }

            if (value == null)
            {
                Debug.Assert(EscapedName.HasValue);

                if (!IgnoreNullValues)
                {
                    writer.WriteNull(EscapedName.Value);
                }
            }
            else if (ValueConverter != null)
            {
                if (EscapedName.HasValue)
                {
                    ValueConverter.Write(EscapedName.Value, value, writer);
                }
                else
                {
                    ValueConverter.Write(value, writer);
                }
            }
        }
 protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer)
 {
     Debug.Assert(Converter != null);
     JsonSerializer.WriteDictionary(Converter, Options, ref current, writer);
 }
Example #18
0
 public virtual void WriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer)
 {
 }
Example #19
0
 internal abstract void WriteEnumerable(JsonSerializerOptions options, ref WriteStackFrame current, ref Utf8JsonWriter writer);
Example #20
0
 public override void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer)
 {
     Debug.Assert(ShouldSerialize);
     JsonSerializer.WriteDictionary(ValueConverter, options, ref current, writer);
 }
Example #21
0
 internal override void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer)
 {
     JsonSerializer.WriteDictionary(ValueConverter, options, ref current, writer);
 }
Example #22
0
 public abstract void WriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer);
Example #23
0
 public abstract void Write(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer);
Example #24
0
 public virtual void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer)
 {
 }
Example #25
0
 public void Pop()
 {
     Debug.Assert(_index > 0);
     Current = _previous[--_index];
 }
Example #26
0
 internal abstract void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer);