public void WriteObjectOrArrayStart(ClassType classType, Utf8JsonWriter writer, JsonSerializerOptions options, bool writeNull = false) { if (JsonPropertyInfo?.EscapedName.HasValue == true) { WriteObjectOrArrayStart(classType, JsonPropertyInfo.EscapedName.Value, writer, writeNull); } else if (KeyName != null) { JsonEncodedText propertyName = JsonEncodedText.Encode(KeyName, options.Encoder); WriteObjectOrArrayStart(classType, propertyName, writer, writeNull); } else { Debug.Assert(writeNull == false); // Write start without a property name. if (classType == ClassType.Object || classType == ClassType.Dictionary || classType == ClassType.IDictionaryConstructible) { writer.WriteStartObject(); StartObjectWritten = true; } else { Debug.Assert(classType == ClassType.Enumerable); writer.WriteStartArray(); } } }
internal static void WriteDictionary <TProperty>( JsonConverter <TProperty> converter, JsonSerializerOptions options, ref WriteStackFrame current, Utf8JsonWriter writer) { if (converter == null) { return; } Debug.Assert(current.CollectionEnumerator != null); string key; TProperty value; if (current.CollectionEnumerator 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.CollectionEnumerator is IEnumerator <KeyValuePair <string, object> > polymorphicEnumerator) { value = (TProperty)polymorphicEnumerator.Current.Value; key = polymorphicEnumerator.Current.Key; } else if (current.IsIDictionaryConstructible || current.IsIDictionaryConstructibleProperty) { value = (TProperty)((DictionaryEntry)current.CollectionEnumerator.Current).Value; key = (string)((DictionaryEntry)current.CollectionEnumerator.Current).Key; } else { // Todo: support non-generic Dictionary here (IDictionaryEnumerator) throw new NotSupportedException(); } if (value == null) { writer.WriteNull(key); } else { if (options.DictionaryKeyPolicy != null && current.ExtensionDataStatus != ExtensionDataWriteStatus.Writing) // We do not convert extension data. { key = options.DictionaryKeyPolicy.ConvertName(key); if (key == null) { ThrowHelper.ThrowInvalidOperationException_SerializerDictionaryKeyNull(options.DictionaryKeyPolicy.GetType()); } } JsonEncodedText escapedKey = JsonEncodedText.Encode(key, options.Encoder); writer.WritePropertyName(escapedKey); converter.Write(writer, value, options); } }
private void DeterminePropertyName() { if (PropertyInfo == null) { return; } JsonPropertyNameAttribute nameAttribute = GetAttribute <JsonPropertyNameAttribute>(PropertyInfo); if (nameAttribute != null) { string name = nameAttribute.Name; if (name == null) { ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameNull(ParentClassType, this); } NameAsString = name; } else if (Options.PropertyNamingPolicy != null) { string name = Options.PropertyNamingPolicy.ConvertName(PropertyInfo.Name); if (name == null) { ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameNull(ParentClassType, this); } NameAsString = name; } else { NameAsString = PropertyInfo.Name; } Debug.Assert(NameAsString != null); // At this point propertyName is valid UTF16, so just call the simple UTF16->UTF8 encoder. Name = Encoding.UTF8.GetBytes(NameAsString); // Set the compare name. if (Options.PropertyNameCaseInsensitive) { NameUsedToCompareAsString = NameAsString.ToUpperInvariant(); NameUsedToCompare = Encoding.UTF8.GetBytes(NameUsedToCompareAsString); } else { NameUsedToCompareAsString = NameAsString; NameUsedToCompare = Name; } // Cache the escaped name. EscapedName = JsonEncodedText.Encode(Name); }
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); } }
private void DeterminePropertyName() { if (PropertyInfo == null) { return; } JsonPropertyNameAttribute nameAttribute = GetAttribute <JsonPropertyNameAttribute>(PropertyInfo); if (nameAttribute != null) { string name = nameAttribute.Name; if (name == null) { ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameNull(ParentClassType, this); } NameAsString = name; } else if (Options.PropertyNamingPolicy != null) { string name = Options.PropertyNamingPolicy.ConvertName(PropertyInfo.Name); if (name == null) { ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameNull(ParentClassType, this); } NameAsString = name; } else { NameAsString = PropertyInfo.Name; } Debug.Assert(NameAsString != null); // At this point propertyName is valid UTF16, so just call the simple UTF16->UTF8 encoder. Name = Encoding.UTF8.GetBytes(NameAsString); // Cache the escaped property name. EscapedName = JsonEncodedText.Encode(Name, Options.Encoder); ulong key = JsonClassInfo.GetKey(Name); PropertyNameKey = key; }