private static void HandleStartObject(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            Debug.Assert(!state.Current.IsProcessingDictionary);

            if (state.Current.IsProcessingEnumerable)
            {
                // A nested object within an enumerable.
                Type objType = state.Current.GetElementType();
                state.Push();
                state.Current.Initialize(objType, options);
            }
            else if (state.Current.JsonPropertyInfo != null)
            {
                // Nested object.
                Type objType = state.Current.JsonPropertyInfo.RuntimePropertyType;
                state.Push();
                state.Current.Initialize(objType, options);
            }

            JsonClassInfo classInfo = state.Current.JsonClassInfo;

            if (classInfo.CreateObject is null && classInfo.ClassType == ClassType.Object)
            {
                if (classInfo.Type.IsInterface)
                {
                    ThrowHelper.ThrowInvalidOperationException_DeserializePolymorphicInterface(classInfo.Type);
                }
                else
                {
                    ThrowHelper.ThrowInvalidOperationException_DeserializeMissingParameterlessConstructor(classInfo.Type);
                }
            }

            state.Current.ReturnValue = classInfo.CreateObject();
        }
        private static void HandleStartObject(JsonSerializerOptions options, ref ReadStack state)
        {
            if (state.Current.Skip())
            {
                state.Push();
                state.Current.Drain = true;
                return;
            }

            if (state.Current.IsEnumerable() || state.Current.IsPropertyEnumerable())
            {
                // An array of objects either on the current property or on a list
                Type objType = state.Current.GetElementType();
                state.Push();
                state.Current.JsonClassInfo = options.GetOrAddClass(objType);
            }
            else if (state.Current.JsonPropertyInfo != null)
            {
                // Nested object
                Type objType = state.Current.JsonPropertyInfo.RuntimePropertyType;
                state.Push();
                state.Current.JsonClassInfo = options.GetOrAddClass(objType);
            }

            JsonClassInfo classInfo = state.Current.JsonClassInfo;

            state.Current.ReturnValue = classInfo.CreateObject();
        }
Beispiel #3
0
        private static void HandleStartDictionary(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            Debug.Assert(!state.Current.IsProcessingEnumerable);

            JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo;

            if (jsonPropertyInfo == null)
            {
                jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootObject(options);
            }

            Debug.Assert(jsonPropertyInfo != null);

            // A nested object or dictionary so push new frame.
            if (state.Current.PropertyInitialized)
            {
                Debug.Assert(state.Current.IsDictionary);

                JsonClassInfo classInfoTemp = state.Current.JsonClassInfo;
                state.Push();
                state.Current.JsonClassInfo = classInfoTemp.ElementClassInfo;
                state.Current.InitializeJsonPropertyInfo();

                ClassType classType = state.Current.JsonClassInfo.ClassType;
                if (classType == ClassType.Value &&
                    jsonPropertyInfo.ElementClassInfo.Type != typeof(object) &&
                    jsonPropertyInfo.ElementClassInfo.Type != typeof(JsonElement))
                {
                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonClassInfo.Type, reader, state.PropertyPath);
                }

                JsonClassInfo classInfo = state.Current.JsonClassInfo;
                state.Current.ReturnValue = classInfo.CreateObject();
                return;
            }

            state.Current.PropertyInitialized = true;

            // If current property is already set (from a constructor, for example) leave as-is.
            if (jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue) == null)
            {
                // Create the dictionary.
                JsonClassInfo dictionaryClassInfo = options.GetOrAddClass(jsonPropertyInfo.RuntimePropertyType);
                IDictionary   value = (IDictionary)dictionaryClassInfo.CreateObject();
                if (value != null)
                {
                    if (state.Current.ReturnValue != null)
                    {
                        state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value);
                    }
                    else
                    {
                        // A dictionary is being returned directly, or a nested dictionary.
                        state.Current.SetReturnValue(value);
                    }
                }
            }
        }
        private static void HandleStartObject(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            if (state.Current.Skip())
            {
                state.Push();
                state.Current.Drain = true;
                return;
            }

            if (state.Current.IsProcessingEnumerable)
            {
                Type objType = state.Current.GetElementType();
                state.Push();
                state.Current.Initialize(objType, options);
            }
            else if (state.Current.JsonPropertyInfo != null)
            {
                if (state.Current.IsDictionary)
                {
                    // Verify that the Dictionary can be deserialized by having <string> as first generic argument.
                    Debug.Assert(state.Current.JsonClassInfo.Type.GetGenericArguments().Length >= 1);
                    if (state.Current.JsonClassInfo.Type.GetGenericArguments()[0].UnderlyingSystemType != typeof(string))
                    {
                        ThrowHelper.ThrowJsonReaderException_DeserializeUnableToConvertValue(state.Current.JsonClassInfo.Type, reader, state);
                    }

                    ClassType classType = state.Current.JsonClassInfo.ElementClassInfo.ClassType;

                    if (state.Current.ReturnValue == null)
                    {
                        // The Dictionary created below will be returned to corresponding Parse() etc method.
                        // Ensure any nested array creates a new frame.
                        state.Current.EnumerableCreated = true;
                    }
                    else
                    {
                        Debug.Assert(classType == ClassType.Object || classType == ClassType.Dictionary);

                        // A nested object or dictionary.
                        JsonClassInfo classInfoTemp = state.Current.JsonClassInfo;
                        state.Push();
                        state.Current.JsonClassInfo = classInfoTemp.ElementClassInfo;
                        state.Current.InitializeJsonPropertyInfo();
                    }
                }
                else
                {
                    // Nested object.
                    Type objType = state.Current.JsonPropertyInfo.RuntimePropertyType;
                    state.Push();
                    state.Current.Initialize(objType, options);
                }
            }

            JsonClassInfo classInfo = state.Current.JsonClassInfo;

            state.Current.ReturnValue = classInfo.CreateObject();
        }
Beispiel #5
0
        public static object CreateEnumerableValue(ref ReadObjectState current, JsonSerializerOptions options)
        {
            // If the property has an EnumerableConverter, then we use tempEnumerableValues.
            if (current.PropertyInfo.EnumerableConverter != null)
            {
                current.TempEnumerableValues = new List <object>();
                return(null);
            }

            Type propType = current.PropertyInfo.PropertyType;

            if (typeof(IList).IsAssignableFrom(propType))
            {
                // If IList, add the members as we create them.
                JsonClassInfo collectionClassInfo = options.GetOrAddClass(propType);
                IList         collection          = (IList)collectionClassInfo.CreateObject();
                return(collection);
            }
            else
            {
                throw new InvalidOperationException($"todo: IEnumerable type {propType.ToString()} is not convertable.");
            }
        }
Beispiel #6
0
        private static void HandleStartObject(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            Debug.Assert(!state.Current.IsProcessingDictionary);

            if (state.Current.IsProcessingEnumerable)
            {
                // A nested object within an enumerable.
                Type objType = state.Current.GetElementType();
                state.Push();
                state.Current.Initialize(objType, options);
            }
            else if (state.Current.JsonPropertyInfo != null)
            {
                // Nested object.
                Type objType = state.Current.JsonPropertyInfo.RuntimePropertyType;
                state.Push();
                state.Current.Initialize(objType, options);
            }

            JsonClassInfo classInfo = state.Current.JsonClassInfo;

            state.Current.ReturnValue = classInfo.CreateObject();
        }
Beispiel #7
0
        public static object CreateEnumerableValue(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options)
        {
            JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo;

            // If the property has an EnumerableConverter, then we use tempEnumerableValues.
            if (jsonPropertyInfo.EnumerableConverter != null)
            {
                IList converterList;
                if (jsonPropertyInfo.ElementClassInfo.ClassType == ClassType.Value)
                {
                    converterList = jsonPropertyInfo.ElementClassInfo.GetPolicyProperty().CreateConverterList();
                }
                else
                {
                    converterList = new List <object>();
                }

                state.Current.TempEnumerableValues = converterList;

                return(null);
            }

            Type propType = state.Current.JsonPropertyInfo.RuntimePropertyType;

            if (typeof(IList).IsAssignableFrom(propType))
            {
                // If IList, add the members as we create them.
                JsonClassInfo collectionClassInfo = state.Current.JsonPropertyInfo.RuntimeClassInfo;
                IList         collection          = (IList)collectionClassInfo.CreateObject();
                return(collection);
            }
            else
            {
                ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(propType, reader, state.JsonPath);
                return(null);
            }
        }
Beispiel #8
0
        internal static object CreateEnumerableValue(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options)
        {
            // If the property has an EnumerableConverter, then we use tempEnumerableValues.
            if (state.Current.JsonPropertyInfo.EnumerableConverter != null)
            {
                state.Current.TempEnumerableValues = new List <object>();
                return(null);
            }

            Type propType = state.Current.JsonPropertyInfo.RuntimePropertyType;

            if (typeof(IList).IsAssignableFrom(propType))
            {
                // If IList, add the members as we create them.
                JsonClassInfo collectionClassInfo = options.GetOrAddClass(propType);
                IList         collection          = (IList)collectionClassInfo.CreateObject();
                return(collection);
            }
            else
            {
                ThrowHelper.ThrowJsonReaderException_DeserializeUnableToConvertValue(propType, reader, state);
                return(null);
            }
        }