Beispiel #1
0
            /// <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);
            }
Beispiel #2
0
            /// <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);
            }
Beispiel #3
0
        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);
        }
Beispiel #4
0
            /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <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);
        }
Beispiel #10
0
        /// <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)));
        }
Beispiel #11
0
 /// <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));
 }
Beispiel #12
0
            /// <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();
                }
            }
Beispiel #13
0
        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);
        }