/// <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); }
/// <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); }