/// <summary> /// Tries to convert the given text into this parser's expected type. Conversion only, formatting should already have been removed. /// </summary> /// <param name="text">The text to convert.</param> /// <param name="targetValue">The target value.</param> /// <returns> /// Whether or not conversion was successful. /// </returns> internal override bool TryConvert(string text, out object targetValue) { DebugUtils.CheckNoExternalCallers(); // must be of even length. if ((text.Length % 2) != 0) { targetValue = null; return(false); } byte[] result = new byte[text.Length / 2]; int resultIndex = 0; int textIndex = 0; while (resultIndex < result.Length) { char ch0 = text[textIndex]; char ch1 = text[textIndex + 1]; if (!UriPrimitiveTypeParser.IsCharHexDigit(ch0) || !UriPrimitiveTypeParser.IsCharHexDigit(ch1)) { targetValue = null; return(false); } result[resultIndex] = (byte)((byte)(HexCharToNibble(ch0) << 4) + HexCharToNibble(ch1)); textIndex += 2; resultIndex++; } targetValue = result; return(true); }
/// <summary> /// Tries to remove formatting specific to this parser's expected type. /// </summary> /// <param name="text">The text to remove formatting from.</param> /// <returns>Whether or not the expected formatting was found and succesfully removed.</returns> internal virtual bool TryRemoveFormatting(ref string text) { DebugUtils.CheckNoExternalCallers(); if (this.prefix != null) { if (!UriPrimitiveTypeParser.TryRemovePrefix(this.prefix, ref text)) { return(false); } } bool shouldBeQuoted = this.prefix != null || ValueOfTypeCanContainQuotes(this.expectedType); if (shouldBeQuoted && !UriPrimitiveTypeParser.TryRemoveQuotes(ref text)) { return(false); } if (this.suffix != null) { // we need to try to remove the literal even if it isn't required. if (!TryRemoveLiteralSuffix(this.suffix, ref text) && this.suffixRequired) { return(false); } } return(true); }
private object ParseTypedLiteral(IEdmPrimitiveTypeReference targetTypeReference) { object obj2; if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(this.CurrentToken.Text, targetTypeReference, out obj2)) { throw ParseError(Microsoft.Data.OData.Strings.UriQueryExpressionParser_UnrecognizedLiteral(targetTypeReference.FullName(), this.CurrentToken.Text, this.CurrentToken.Position, this.ExpressionText)); } this.NextToken(); return(obj2); }
/// <summary> /// Tries to remove formatting specific to this parser's expected type. /// </summary> /// <param name="text">The text to remove formatting from.</param> /// <returns> /// Whether or not the expected formatting was found and succesfully removed. /// </returns> internal override bool TryRemoveFormatting(ref string text) { DebugUtils.CheckNoExternalCallers(); if (!UriPrimitiveTypeParser.TryRemovePrefix(ExpressionConstants.LiteralPrefixBinary, ref text) && !UriPrimitiveTypeParser.TryRemovePrefix(ExpressionConstants.LiteralPrefixShortBinary, ref text)) { return(false); } if (!UriPrimitiveTypeParser.TryRemoveQuotes(ref text)) { return(false); } return(true); }
/// <summary> /// Parses typed literals. /// </summary> /// <param name="targetTypeReference">Expected type to be parsed.</param> /// <returns>The literal token produced by building the given literal.</returns> private object ParseTypedLiteral(IEdmPrimitiveTypeReference targetTypeReference) { object targetValue; if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(this.CurrentToken.Text, targetTypeReference, out targetValue)) { string message = o.Strings.UriQueryExpressionParser_UnrecognizedLiteral( targetTypeReference.FullName(), this.CurrentToken.Text, this.CurrentToken.Position, this.ExpressionText); throw ParseError(message); } this.NextToken(); return(targetValue); }
/// <summary> /// Parses typed literals. /// </summary> /// <param name="expressionLexer">The expression lexer.</param> /// <param name="targetTypeReference">Expected type to be parsed.</param> /// <returns>The literal token produced by building the given literal.</returns> private static object ParseTypedLiteral(this ExpressionLexer expressionLexer, IEdmPrimitiveTypeReference targetTypeReference) { object targetValue; if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(expressionLexer.CurrentToken.Text, targetTypeReference, out targetValue)) { string message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral( targetTypeReference.FullName(), expressionLexer.CurrentToken.Text, expressionLexer.CurrentToken.Position, expressionLexer.ExpressionText); throw new ODataException(message); } expressionLexer.NextToken(); return(targetValue); }
/// <summary> /// Parses typed literals. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <param name="targetTypeReference">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 LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmPrimitiveTypeReference targetTypeReference, string targetTypeName) { Debug.Assert(lexer != null, "lexer != null"); object targetValue; if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(lexer.CurrentToken.Text, targetTypeReference, out targetValue)) { string message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText); throw ParseError(message); } LiteralToken result = new LiteralToken(targetValue, 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, EdmCoreModel.Instance.GetInt32(false), out valueAsObject)) { nonNegativeInteger = -1; return(false); } nonNegativeInteger = (int)valueAsObject; if (nonNegativeInteger < 0) { return(false); } return(true); }
/// <summary>Parses a token that starts with a digit.</summary> /// <returns>The kind of token recognized.</returns> private ExpressionTokenKind ParseFromDigit() { Debug.Assert(this.IsValidDigit, "this.IsValidDigit"); ExpressionTokenKind result; char startChar = this.ch.Value; this.NextChar(); if (startChar == '0' && this.ch == 'x' || this.ch == 'X') { result = ExpressionTokenKind.BinaryLiteral; do { this.NextChar(); }while (this.ch.HasValue && UriPrimitiveTypeParser.IsCharHexDigit(this.ch.Value)); } else { result = ExpressionTokenKind.IntegerLiteral; while (this.IsValidDigit) { this.NextChar(); } if (this.ch == '.') { result = ExpressionTokenKind.DoubleLiteral; this.NextChar(); this.ValidateDigit(); do { this.NextChar(); }while (this.IsValidDigit); } 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 (this.IsValidDigit); } 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); }
/// <summary> /// Parses the <paramref name="queryUri"/> and returns a new instance of <see cref="SyntacticTree"/> /// 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="SyntacticTree"/> which represents the query specified in the <paramref name="queryUri"/>.</returns> public static SyntacticTree ParseUri(Uri queryUri, Uri serviceBaseUri, int maxDepth) { ExceptionUtils.CheckArgumentNotNull(queryUri, "queryUri"); if (!queryUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(queryUri), "queryUri"); } ExceptionUtils.CheckArgumentNotNull(serviceBaseUri, "serviceBaseUri"); if (!serviceBaseUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(serviceBaseUri), "serviceBaseUri"); } if (maxDepth <= 0) { throw new ArgumentException(Strings.SyntacticTree_MaxDepthInvalid, "maxDepth"); } UriPathParser pathParser = new UriPathParser(maxDepth); var path = pathParser.ParsePathIntoSegments(queryUri, serviceBaseUri); List <CustomQueryOptionToken> queryOptions = UriUtils.ParseQueryOptions(queryUri); QueryToken filter = null; string filterQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FilterQueryOption); if (filterQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); filter = expressionParser.ParseFilter(filterQuery); } IEnumerable <OrderByToken> orderByTokens = null; string orderByQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.OrderByQueryOption); if (orderByQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); orderByTokens = expressionParser.ParseOrderBy(orderByQuery); } SelectToken select = null; string selectQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SelectQueryOption); if (selectQuery != null) { ISelectExpandTermParser selectParser = SelectExpandTermParserFactory.Create(selectQuery); select = selectParser.ParseSelect(); } ExpandToken expand = null; string expandQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.ExpandQueryOption); if (expandQuery != null) { ISelectExpandTermParser expandParser = SelectExpandTermParserFactory.Create(expandQuery); expand = expandParser.ParseExpand(); } int? skip = null; string skipQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SkipQueryOption); if (skipQuery != null) { int skipValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(skipQuery, out skipValue)) { throw new ODataException(Strings.SyntacticTree_InvalidSkipQueryOptionValue(skipQuery)); } skip = skipValue; } int? top = null; string topQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.TopQueryOption); if (topQuery != null) { int topValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(topQuery, out topValue)) { throw new ODataException(Strings.SyntacticTree_InvalidTopQueryOptionValue(topQuery)); } top = topValue; } string inlineCountQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.InlineCountQueryOption); InlineCountKind?inlineCount = QueryTokenUtils.ParseInlineCountKind(inlineCountQuery); string format = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FormatQueryOption); return(new SyntacticTree( path, filter, orderByTokens, select, expand, skip, top, inlineCount, format, queryOptions.Count == 0 ? null : new ReadOnlyCollection <CustomQueryOptionToken>(queryOptions))); }
/// <summary> /// Tries to remove formatting specific to this parser's expected type. /// </summary> /// <param name="text">The text to remove formatting from.</param> /// <returns> /// Whether or not the expected formatting was found and succesfully removed. /// </returns> internal override bool TryRemoveFormatting(ref string text) { DebugUtils.CheckNoExternalCallers(); return(UriPrimitiveTypeParser.TryRemoveQuotes(ref text)); }
/// <summary>Returns the 4 bits that correspond to the specified character.</summary> /// <param name="c">Character in the 0-F range to be converted.</param> /// <returns>The 4 bits that correspond to the specified character.</returns> /// <exception cref="FormatException">Thrown when 'c' is not in the '0'-'9','a'-'f' range.</exception> private static byte HexCharToNibble(char c) { Debug.Assert(UriPrimitiveTypeParser.IsCharHexDigit(c), String.Format(CultureInfo.InvariantCulture, "{0} is not a hex digit.", c)); switch (c) { case '0': return(0); case '1': return(1); case '2': return(2); case '3': return(3); case '4': return(4); case '5': return(5); case '6': return(6); case '7': return(7); case '8': return(8); case '9': return(9); case 'a': case 'A': return(10); case 'b': case 'B': return(11); case 'c': case 'C': return(12); case 'd': case 'D': return(13); case 'e': case 'E': return(14); case 'f': case 'F': return(15); default: throw new InvalidOperationException(); } }
private ExpressionTokenKind ParseFromDigit() { ExpressionTokenKind integerLiteral; char ch = this.ch; this.NextChar(); if (((ch == '0') && (this.ch == 'x')) || (this.ch == 'X')) { integerLiteral = ExpressionTokenKind.BinaryLiteral; do { this.NextChar(); }while (UriPrimitiveTypeParser.IsCharHexDigit(this.ch)); return(integerLiteral); } integerLiteral = ExpressionTokenKind.IntegerLiteral; while (char.IsDigit(this.ch)) { this.NextChar(); } if (this.ch == '.') { integerLiteral = ExpressionTokenKind.DoubleLiteral; this.NextChar(); this.ValidateDigit(); do { this.NextChar(); }while (char.IsDigit(this.ch)); } if ((this.ch == 'E') || (this.ch == 'e')) { integerLiteral = 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')) { integerLiteral = ExpressionTokenKind.DecimalLiteral; this.NextChar(); return(integerLiteral); } if ((this.ch == 'd') || (this.ch == 'D')) { integerLiteral = ExpressionTokenKind.DoubleLiteral; this.NextChar(); return(integerLiteral); } if ((this.ch == 'L') || (this.ch == 'l')) { integerLiteral = ExpressionTokenKind.Int64Literal; this.NextChar(); return(integerLiteral); } if ((this.ch == 'f') || (this.ch == 'F')) { integerLiteral = ExpressionTokenKind.SingleLiteral; this.NextChar(); } return(integerLiteral); }