protected override void ReadObjectProperties(JsonReader reader, Expression result, Dictionary <string, Property> properties, JsonSerializer serializer)
        {
            if (result is ConstantExpression constantExpression)
            {
                reader.CheckNotNull(nameof(reader)).AssertProperty(nameof(ConstantExpression.Type));
                var typeInfo = reader.Read <TypeInfo>(serializer);
                constantExpression.Type = typeInfo ?? throw reader.CreateException($"{nameof(ConstantExpression.Type)} must not be null.");

                reader.Advance();
                if (reader.IsProperty(ValueTypePropertyName))
                {
                    typeInfo = reader.Read <TypeInfo>(serializer);
                    reader.Advance();
                }

                reader.AssertProperty(nameof(ConstantExpression.Value), false);
                var value = reader.Read(typeInfo, serializer);
                constantExpression.Value = value;

                reader.AssertEndObject();
            }
            else
            {
                base.ReadObjectProperties(reader, result, properties, serializer);
            }
        }
        private static GeographyPoint ReadCoordinates(JsonReader coordinatesReader)
        {
            coordinatesReader.ExpectAndAdvance(JsonToken.StartArray);

            double ReadFloatOrInt()
            {
                switch (coordinatesReader.TokenType)
                {
                case JsonToken.Integer:
                    return(coordinatesReader.ExpectAndAdvance <long>(JsonToken.Integer));

                // Treat all other cases as Float and let ExpectAndAdvance() handle any errors.
                default:
                    return(coordinatesReader.ExpectAndAdvance <double>(JsonToken.Float));
                }
            }

            double longitude = ReadFloatOrInt();
            double latitude  = ReadFloatOrInt();

            // Skip remaining coordinates, e.g. z and m.
            while (coordinatesReader.TokenType != JsonToken.EndArray)
            {
                coordinatesReader.Advance();
            }

            coordinatesReader.ExpectAndAdvance(JsonToken.EndArray);

            return(GeographyPoint.Create(latitude, longitude));
        }
 /// <summary>
 /// Reads the properties of JSON objects, enforcing the presence of required properties and ignoring the order of properties,
 /// and then advances the given reader to the next token after the end of the object.
 /// </summary>
 /// <param name="reader">The JSON reader to use to read an object.</param>
 /// <param name="requiredProperties">
 /// The names of all JSON properties that are expected to be present in the parsed object.
 /// </param>
 /// <param name="readProperty">
 /// A callback that reads a property value with the given name from the given <see cref="JsonReader" />. It must
 /// advance the reader to the name of the next property, or the end of the object if there are no more properties to read.
 /// </param>
 /// <remarks>
 /// This method will advance the reader to the next position after the end of the object.
 /// </remarks>
 public static void ReadObjectAndAdvance(
     this JsonReader reader,
     IEnumerable <string> requiredProperties,
     Action <JsonReader, string> readProperty)
 {
     reader.ReadObject(requiredProperties, readProperty);
     reader.Advance();
 }
Exemple #4
0
        protected override void ReadObjectProperties(JsonReader reader, VariableQueryArgumentList result, Dictionary <string, Property> properties, JsonSerializer serializer)
        {
            TypeInfo?elementTypeInfo;

            void SetResult(List <object?>?values = null)
            {
                reader.AssertEndObject();
                result.CheckNotNull(nameof(result)).ElementType = elementTypeInfo;
                result.Values = values ?? new List <object?>();
            }

            reader.CheckNotNull(nameof(reader)).AssertProperty(nameof(VariableQueryArgumentList.ElementType));
            elementTypeInfo = reader.Read <TypeInfo>(serializer) ?? throw reader.CreateException($"{nameof(VariableQueryArgumentList.ElementType)} must not be null.");

            reader.Advance();
            if (reader.TokenType == JsonToken.Null)
            {
                SetResult();
                return;
            }

            if (reader.TokenType != JsonToken.StartArray)
            {
                throw reader.CreateException($"Expected array");
            }

            bool TryReadNextItem(out object?value)
            {
                if (!reader.TryRead(elementTypeInfo !, serializer, out value))
                {
                    // TODO: is max length quota required?
                    if (reader.TokenType == JsonToken.EndArray)
                    {
                        return(false);
                    }

                    throw reader.CreateException("Unexpected token structure.");
                }

                return(true);
            }

            var values = new List <object?>();

            while (TryReadNextItem(out object?value))
            {
                values.Add(value);
            }

            SetResult(values);
        }
        public override object ReadJson(
            JsonReader reader,
            Type objectType,
            object existingValue,
            JsonSerializer serializer)
        {
            // Check for null first.
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var book = new T();

            reader.ExpectAndAdvance(JsonToken.StartObject);

            while (reader.TokenType != JsonToken.EndObject)
            {
                string propertyName = reader.ExpectAndAdvance <string>(JsonToken.PropertyName);
                switch (propertyName)
                {
                case "ISBN":
                    book.InternationalStandardBookNumber = serializer.Deserialize <string>(reader);
                    break;

                case "Title":
                    book.Name = serializer.Deserialize <string>(reader);
                    break;

                case "Author":
                    book.AuthorName = serializer.Deserialize <string>(reader);
                    break;

                case "PublishDate":
                    book.PublishDateTime = serializer.Deserialize <DateTime?>(reader);
                    break;

                default:
                    // Ignore properties we don't understand.
                    break;
                }

                reader.Advance();
            }

            return(book);
        }
        public override object ReadJson(
            JsonReader reader,
            Type objectType,
            object existingValue,
            JsonSerializer serializer)
        {
            // Check for null first.
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var author = new TAuthor {
                FullName = string.Empty
            };

            reader.ExpectAndAdvance(JsonToken.StartObject);

            while (reader.TokenType != JsonToken.EndObject)
            {
                string propertyName = reader.ExpectAndAdvance <string>(JsonToken.PropertyName);
                switch (propertyName)
                {
                case "FirstName":
                    author.FullName = serializer.Deserialize <string>(reader) + author.FullName;
                    break;

                case "LastName":
                    string lastName  = serializer.Deserialize <string>(reader);
                    string separator = string.IsNullOrWhiteSpace(lastName) ? string.Empty : " ";
                    author.FullName += separator + lastName;
                    break;

                default:
                    // Ignore properties we don't understand.
                    break;
                }

                reader.Advance();
            }

            return(author);
        }
        public override object ReadJson(
            JsonReader reader,
            Type objectType,
            object existingValue,
            JsonSerializer serializer)
        {
            // Check for null first.
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            reader.ExpectAndAdvance(JsonToken.StartObject);
            reader.ExpectAndAdvance(JsonToken.PropertyName, "type");
            reader.ExpectAndAdvance(JsonToken.String, "Point");
            reader.ExpectAndAdvance(JsonToken.PropertyName, "coordinates");
            reader.ExpectAndAdvance(JsonToken.StartArray);
            double longitude = reader.ExpectAndAdvance <double>(JsonToken.Float);
            double latitude  = reader.ExpectAndAdvance <double>(JsonToken.Float);

            reader.ExpectAndAdvance(JsonToken.EndArray);

            if (reader.TokenType == JsonToken.PropertyName && reader.Value.Equals("crs"))
            {
                reader.Advance();
                reader.ExpectAndAdvance(JsonToken.StartObject);
                reader.ExpectAndAdvance(JsonToken.PropertyName, "type");
                reader.ExpectAndAdvance(JsonToken.String, "name");
                reader.ExpectAndAdvance(JsonToken.PropertyName, "properties");
                reader.ExpectAndAdvance(JsonToken.StartObject);
                reader.ExpectAndAdvance(JsonToken.PropertyName, "name");
                reader.ExpectAndAdvance(JsonToken.String, "EPSG:4326");
                reader.ExpectAndAdvance(JsonToken.EndObject);
                reader.ExpectAndAdvance(JsonToken.EndObject);
            }

            reader.Expect(JsonToken.EndObject);
            return(GeographyPoint.Create(latitude, longitude));
        }
        protected override void ReadObjectProperties(JsonReader reader, DynamicObject result, Dictionary <string, Property> properties, JsonSerializer serializer)
        {
            reader.Advance();

            TypeInfo?typeInfo = null;

            void SetResult(IEnumerable <DynamicProperty>?properties = null)
            {
                reader.AssertEndObject();

                result.Type = typeInfo;
                if (properties?.Any() == true)
                {
                    result.Properties = new PropertySet(properties);
                }
            }

            if (reader.IsProperty(nameof(DynamicObject.Type)))
            {
                typeInfo = reader.Read <TypeInfo?>(serializer);
                reader.Advance();
            }

            if (reader.IsProperty("Value"))
            {
                var value = reader.Read(typeInfo, serializer);
                SetResult(new[] { new DynamicProperty(string.Empty, value) });
                return;
            }

            if (reader.IsProperty("Values"))
            {
                reader.Advance();
                if (reader.TokenType == JsonToken.Null)
                {
                    SetResult();
                    return;
                }

                if (reader.TokenType != JsonToken.StartArray)
                {
                    throw reader.CreateException($"Expected array");
                }

                var elementType = TypeHelper.GetElementType(typeInfo?.Type) ?? typeof(object);
                bool TryReadNextItem(out object?value)
                {
                    if (!reader.TryRead(elementType, serializer, out value))
                    {
                        // TODO: is max length quota required?
                        if (reader.TokenType == JsonToken.EndArray)
                        {
                            return(false);
                        }

                        throw reader.CreateException("Unexpected token structure.");
                    }

                    return(true);
                }

                var values = new List <object?>();
                while (TryReadNextItem(out var item))
                {
                    values.Add(item);
                }

                if (values.Any(x => x != null && (elementType == typeof(object) || !elementType.IsAssignableFrom(x.GetType()))) &&
                    values.All(x => x is null || x is string))
                {
                    elementType = typeof(string);
                }

                var valueArray = CastCollectionToArrayOfType(elementType, values);
                SetResult(new[] { new DynamicProperty(string.Empty, valueArray) });
                return;
            }

            if (reader.IsProperty(nameof(DynamicObject.Properties)))
            {
                reader.Advance();
                if (reader.TokenType == JsonToken.Null)
                {
                    SetResult();
                    return;
                }

                if (reader.TokenType != JsonToken.StartArray)
                {
                    throw reader.CreateException("Expected array");
                }

                var propertySet = new List <DynamicProperty>();

                bool NextItem()
                {
                    // TODO: is max length quota required?
                    reader.Advance();
                    return(reader.TokenType != JsonToken.EndArray);
                }

                while (NextItem())
                {
                    reader.AssertStartObject(false);

                    reader.AssertProperty(nameof(DynamicProperty.Name));
                    var name = reader.ReadAsString() ?? throw reader.CreateException("Property name must not be null");

                    reader.AssertProperty(nameof(Type));
                    var type = reader.Read <TypeInfo?>(serializer);

                    reader.AssertProperty(nameof(DynamicProperty.Value));
                    var value = reader.Read(type, serializer);

                    reader.AssertEndObject();
                    propertySet.Add(new DynamicProperty(name, value));
                }

                SetResult(propertySet);
                return;
            }

            throw reader.CreateException($"Unexpected token {reader.TokenType}");
        }
Exemple #9
0
        protected override void ReadObjectProperties(JsonReader reader, DynamicObject result, Dictionary <string, Property> properties, JsonSerializer serializer)
        {
            reader.CheckNotNull(nameof(reader)).Advance();
            result.CheckNotNull(nameof(result));
            serializer.CheckNotNull(nameof(serializer));

            TypeInfo?typeInfo = null;

            void SetResult(IEnumerable <DynamicProperty>?properties = null)
            {
                reader.AssertEndObject();

                result.Type = typeInfo;
                if (properties?.Any() is true)
                {
                    result.Properties = new PropertySet(properties);
                }
            }

            if (reader.IsProperty(nameof(DynamicObject.Type)))
            {
                typeInfo = reader.Read <TypeInfo?>(serializer);
                reader.Advance();
            }

            bool IsProperty(string property, out bool isDynamicValueType)
            {
                isDynamicValueType = false;

                if (reader.IsProperty(property))
                {
                    return(true);
                }

                if (reader.IsProperty($"Dynamic{property}"))
                {
                    isDynamicValueType = true;
                    return(true);
                }

                return(false);
            }

            if (IsProperty(ValueProperty, out var isDynamicValue))
            {
                var value = isDynamicValue
                    ? reader.Read <DynamicObject>(serializer)
                    : reader.Read(typeInfo, serializer);
                SetResult(new[] { new DynamicProperty(string.Empty, value) });
                return;
            }

            if (IsProperty(ValuesProperty, out isDynamicValue))
            {
                reader.Advance();
                if (reader.TokenType == JsonToken.Null)
                {
                    SetResult();
                    return;
                }

                if (reader.TokenType != JsonToken.StartArray)
                {
                    throw reader.CreateException($"Expected array");
                }

                var elementType = TypeHelper.GetElementType(typeInfo?.ToType()) ?? typeof(object);
                bool TryReadNextItem(out object?value)
                {
                    var itemType = isDynamicValue ? typeof(DynamicObject) : elementType;

                    if (!reader.TryRead(itemType, serializer, out value))
                    {
                        if (reader.TokenType == JsonToken.EndArray)
                        {
                            return(false);
                        }

                        throw reader.CreateException("Unexpected token structure.");
                    }

                    return(true);
                }

                var values = new List <object?>();
                while (TryReadNextItem(out var item))
                {
                    values.Add(item);
                }

                if (isDynamicValue)
                {
                    elementType = typeof(object);
                }
                else if (values.Any(x => x is not null && (elementType == typeof(object) || !elementType.IsInstanceOfType(x))) &&
                         values.All(x => x is null || x is string))
                {
                    elementType = typeof(string);
                }

                var valueArray = values.CastCollectionToArrayOfType(elementType);
                SetResult(new[] { new DynamicProperty(string.Empty, valueArray) });
                return;
            }

            if (reader.IsProperty(nameof(DynamicObject.Properties)))
            {
                reader.Advance();
                if (reader.TokenType == JsonToken.Null)
                {
                    SetResult();
                    return;
                }

                if (reader.TokenType != JsonToken.StartArray)
                {
                    throw reader.CreateException("Expected array");
                }

                var propertySet = new List <DynamicProperty>();

                bool NextItem()
                {
                    reader.Advance();
                    return(reader.TokenType != JsonToken.EndArray);
                }

                while (NextItem())
                {
                    reader.AssertStartObject(false);

                    reader.AssertProperty(nameof(DynamicProperty.Name));
                    var name = reader.ReadAsString() ?? throw reader.CreateException("Property name must not be null");

                    reader.AssertProperty(nameof(Type));
                    var type = reader.Read <TypeInfo?>(serializer);

                    reader.AssertProperty(nameof(DynamicProperty.Value));
                    var value = reader.Read(type, serializer);

                    reader.AssertEndObject();
                    propertySet.Add(new DynamicProperty(name, value));
                }

                SetResult(propertySet);
                return;
            }

            throw reader.CreateException($"Unexpected token {reader.TokenType}");
        }