/// <summary>
        /// Parses typed literals.
        /// </summary>
        /// <param name="lexer">The lexer to use.</param>
        /// <param name="targetType">Expected type to be parsed.</param>
        /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param>
        /// <returns>The literal token produced by building the given literal.</returns>
        private static LiteralQueryToken ParseTypedLiteral(ExpressionLexer lexer, Type targetType, string targetTypeName)
        {
            Debug.Assert(lexer != null, "lexer != null");

            object targetValue;

            if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(lexer.CurrentToken.Text, targetType, out targetValue))
            {
                string message = Strings.UriQueryExpressionParser_UnrecognizedLiteral(
                    targetTypeName,
                    lexer.CurrentToken.Text,
                    lexer.CurrentToken.Position,
                    lexer.ExpressionText);
                throw ParseError(message);
            }

            LiteralQueryToken result = new LiteralQueryToken()
            {
                Value        = targetValue,
                OriginalText = lexer.CurrentToken.Text
            };

            lexer.NextToken();
            return(result);
        }
        /// <summary>
        /// Try to parse a string value into a non-negative integer.
        /// </summary>
        /// <param name="text">The string value to parse.</param>
        /// <param name="nonNegativeInteger">The non-negative integer value parsed from the <paramref name="text"/>.</param>
        /// <returns>True if <paramref name="text"/> could successfully be parsed into a non-negative integer; otherwise returns false.</returns>
        internal static bool TryUriStringToNonNegativeInteger(string text, out int nonNegativeInteger)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(text != null, "text != null");

            object valueAsObject;

            if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(text, typeof(int), out valueAsObject))
            {
                nonNegativeInteger = -1;
                return(false);
            }

            nonNegativeInteger = (int)valueAsObject;

            if (nonNegativeInteger < 0)
            {
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Parses the <paramref name="queryUri"/> and returns a new instance of <see cref="QueryDescriptorQueryToken"/>
        /// describing the query specified by the uri.
        /// </summary>
        /// <param name="queryUri">The absolute URI which holds the query to parse. This must be a path relative to the <paramref name="serviceBaseUri"/>.</param>
        /// <param name="serviceBaseUri">The base URI of the service.</param>
        /// <param name="maxDepth">The maximum depth of any single query part. Security setting to guard against DoS attacks causing stack overflows and such.</param>
        /// <returns>A new instance of <see cref="QueryDescriptorQueryToken"/> which represents the query specified in the <paramref name="queryUri"/>.</returns>
        public static QueryDescriptorQueryToken ParseUri(Uri queryUri, Uri serviceBaseUri, int maxDepth)
        {
            ExceptionUtils.CheckArgumentNotNull(queryUri, "queryUri");
            if (!queryUri.IsAbsoluteUri)
            {
                throw new ArgumentException(Strings.QueryDescriptorQueryToken_UriMustBeAbsolute(queryUri), "queryUri");
            }

            ExceptionUtils.CheckArgumentNotNull(serviceBaseUri, "serviceBaseUri");
            if (!serviceBaseUri.IsAbsoluteUri)
            {
                throw new ArgumentException(Strings.QueryDescriptorQueryToken_UriMustBeAbsolute(serviceBaseUri), "serviceBaseUri");
            }

            if (maxDepth <= 0)
            {
                throw new ArgumentException(Strings.QueryDescriptorQueryToken_MaxDepthInvalid, "maxDepth");
            }

            QueryDescriptorQueryToken queryDescriptor = new QueryDescriptorQueryToken();

            UriQueryPathParser pathParser = new UriQueryPathParser(maxDepth);

            queryDescriptor.Path = pathParser.ParseUri(queryUri, serviceBaseUri);

            List <QueryOptionQueryToken> queryOptions = HttpUtils.ParseQueryOptions(queryUri);

            string filter = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FilterQueryOption);

            if (filter != null)
            {
                UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth);
                queryDescriptor.Filter = expressionParser.ParseFilter(filter);
            }

            string orderBy = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.OrderByQueryOption);

            if (orderBy != null)
            {
                UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth);
                queryDescriptor.OrderByTokens = expressionParser.ParseOrderBy(orderBy);
            }

            string skip = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SkipQueryOption);

            if (skip != null)
            {
                int skipValue;
                if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(skip, out skipValue))
                {
                    throw new ODataException(Strings.QueryDescriptorQueryToken_InvalidSkipQueryOptionValue(skip));
                }

                queryDescriptor.Skip = skipValue;
            }

            string top = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.TopQueryOption);

            if (top != null)
            {
                int topValue;
                if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(top, out topValue))
                {
                    throw new ODataException(Strings.QueryDescriptorQueryToken_InvalidTopQueryOptionValue(top));
                }

                queryDescriptor.Top = topValue;
            }

            // the remaining query options are stored on the query descriptor
            queryDescriptor.QueryOptions = queryOptions.Count == 0 ? null : new ReadOnlyCollection <QueryOptionQueryToken>(queryOptions);

            return(queryDescriptor);
        }
示例#4
0
        /// <summary>Parses a token that starts with a digit.</summary>
        /// <returns>The kind of token recognized.</returns>
        private ExpressionTokenKind ParseFromDigit()
        {
            Debug.Assert(Char.IsDigit(this.ch), "Char.IsDigit(this.ch)");
            ExpressionTokenKind result;
            char startChar = this.ch;

            this.NextChar();
            if (startChar == '0' && this.ch == 'x' || this.ch == 'X')
            {
                result = ExpressionTokenKind.BinaryLiteral;
                do
                {
                    this.NextChar();
                }while (UriPrimitiveTypeParser.IsCharHexDigit(this.ch));
            }
            else
            {
                result = ExpressionTokenKind.IntegerLiteral;
                while (Char.IsDigit(this.ch))
                {
                    this.NextChar();
                }

                if (this.ch == '.')
                {
                    result = ExpressionTokenKind.DoubleLiteral;
                    this.NextChar();
                    this.ValidateDigit();

                    do
                    {
                        this.NextChar();
                    }while (Char.IsDigit(this.ch));
                }

                if (this.ch == 'E' || this.ch == 'e')
                {
                    result = ExpressionTokenKind.DoubleLiteral;
                    this.NextChar();
                    if (this.ch == '+' || this.ch == '-')
                    {
                        this.NextChar();
                    }

                    this.ValidateDigit();
                    do
                    {
                        this.NextChar();
                    }while (Char.IsDigit(this.ch));
                }

                if (this.ch == 'M' || this.ch == 'm')
                {
                    result = ExpressionTokenKind.DecimalLiteral;
                    this.NextChar();
                }
                else
                if (this.ch == 'd' || this.ch == 'D')
                {
                    result = ExpressionTokenKind.DoubleLiteral;
                    this.NextChar();
                }
                else if (this.ch == 'L' || this.ch == 'l')
                {
                    result = ExpressionTokenKind.Int64Literal;
                    this.NextChar();
                }
                else if (this.ch == 'f' || this.ch == 'F')
                {
                    result = ExpressionTokenKind.SingleLiteral;
                    this.NextChar();
                }
            }

            return(result);
        }