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); }
// 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); } }
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()); } }
// 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); } } } }
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++; }
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); }
public virtual void WriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { }
internal abstract void WriteEnumerable(JsonSerializerOptions options, ref WriteStackFrame current, ref Utf8JsonWriter writer);
public override void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer) { Debug.Assert(ShouldSerialize); JsonSerializer.WriteDictionary(ValueConverter, options, ref current, writer); }
internal override void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer) { JsonSerializer.WriteDictionary(ValueConverter, options, ref current, writer); }
public abstract void WriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer);
public abstract void Write(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer);
public virtual void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer) { }
public void Pop() { Debug.Assert(_index > 0); Current = _previous[--_index]; }
internal abstract void WriteDictionary(JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer);