Exemple #1
0
        /// <summary>Tries to create a key segment for the given filter if it is non empty.</summary>
        /// <param name="previous">Segment on which to compose.</param>
        /// <param name="parenthesisExpression">Parenthesis expression of segment.</param>
        /// <param name="keySegment">The key segment that was created if the key was non-empty.</param>
        /// <returns>Whether the key was non-empty.</returns>
        internal static bool TryCreateKeySegmentFromParentheses(ODataPathSegment previous, string parenthesisExpression, out ODataPathSegment keySegment)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(parenthesisExpression != null, "parenthesisExpression != null");
            Debug.Assert(previous != null, "segment!= null");

            ExceptionUtil.ThrowSyntaxErrorIfNotValid(!previous.SingleResult);

            SegmentArgumentParser key;

            ExceptionUtil.ThrowSyntaxErrorIfNotValid(SegmentArgumentParser.TryParseKeysFromUri(parenthesisExpression, out key));

            // People/NS.Employees() is OK, just like People() is OK
            if (key.IsEmpty)
            {
                keySegment = null;
                return(false);
            }

            keySegment = CreateKeySegment(previous, key);
            return(true);
        }
Exemple #2
0
        /// <summary>Attempts to parse key values from the specified text.</summary>
        /// <param name='text'>Text to parse (not null).</param>
        /// <param name="allowNamedValues">Set to true if the parser should accept named values
        ///     so syntax like Name='value'. If this is false, the parsing will fail on such constructs.</param>
        /// <param name="allowNull">Set to true if the parser should accept null values.
        ///     If set to false, the parser will fail on null values.</param>
        /// <param name='instance'>After invocation, the parsed key instance.</param>
        /// <returns>
        /// true if the key instance was parsed; false if there was a
        /// syntactic error.
        /// </returns>
        /// <remarks>
        /// The returned instance contains only string values. To get typed values, a call to
        /// TryConvertValues is necessary.
        /// </remarks>
        private static bool TryParseFromUri(string text, bool allowNamedValues, bool allowNull, out SegmentArgumentParser instance)
        {
            Debug.Assert(text != null, "text != null");

            Dictionary <string, string> namedValues = null;
            List <string>   positionalValues        = null;
            ExpressionLexer lexer        = new ExpressionLexer(text, true, false);
            ExpressionToken currentToken = lexer.CurrentToken;

            if (currentToken.Kind == ExpressionTokenKind.End)
            {
                instance = Empty;
                return(true);
            }

            instance = null;
            do
            {
                if (currentToken.Kind == ExpressionTokenKind.Identifier && allowNamedValues)
                {
                    // Name-value pair.
                    if (positionalValues != null)
                    {
                        // We cannot mix named and non-named values.
                        return(false);
                    }

                    string identifier = lexer.CurrentToken.GetIdentifier();
                    lexer.NextToken();
                    if (lexer.CurrentToken.Kind != ExpressionTokenKind.Equal)
                    {
                        return(false);
                    }

                    lexer.NextToken();
                    if (!lexer.CurrentToken.IsKeyValueToken)
                    {
                        return(false);
                    }

                    string namedValue = lexer.CurrentToken.Text;
                    CreateIfNull(ref namedValues);
                    if (namedValues.ContainsKey(identifier))
                    {
                        // Duplicate name.
                        return(false);
                    }

                    namedValues.Add(identifier, namedValue);
                }
                else if (currentToken.IsKeyValueToken || (allowNull && currentToken.Kind == ExpressionTokenKind.NullLiteral))
                {
                    // Positional value.
                    if (namedValues != null)
                    {
                        // We cannot mix named and non-named values.
                        return(false);
                    }

                    CreateIfNull(ref positionalValues);
                    positionalValues.Add(lexer.CurrentToken.Text);
                }
                else
                {
                    return(false);
                }

                // Read the next token. We should be at the end, or find
                // we have a comma followed by something.
                lexer.NextToken();
                currentToken = lexer.CurrentToken;
                if (currentToken.Kind == ExpressionTokenKind.Comma)
                {
                    lexer.NextToken();
                    currentToken = lexer.CurrentToken;
                    if (currentToken.Kind == ExpressionTokenKind.End)
                    {
                        // Trailing comma.
                        return(false);
                    }
                }
            }while (currentToken.Kind != ExpressionTokenKind.End);

            instance = new SegmentArgumentParser(namedValues, positionalValues, false);
            return(true);
        }
Exemple #3
0
 /// <summary>Attempts to parse nullable values (only positional values, no name-value pairs) from the specified text.</summary>
 /// <param name='text'>Text to parse (not null).</param>
 /// <param name='instance'>After invocation, the parsed key instance.</param>
 /// <returns>
 /// true if the given values were parsed; false if there was a
 /// syntactic error.
 /// </returns>
 /// <remarks>
 /// The returned instance contains only string values. To get typed values, a call to
 /// TryConvertValues is necessary.
 /// </remarks>
 internal static bool TryParseNullableTokens(string text, out SegmentArgumentParser instance)
 {
     DebugUtils.CheckNoExternalCallers();
     return(TryParseFromUri(text, false /*allowNamedValues*/, true /*allowNull*/, out instance));
 }