private static bool AddIndexer(string path, int length, ref int index, PropertyRouteBuilder builder)
        {
            if ((index >= length) || (path[index] != '['))
            {
                return(false);
            }

            var currentIndex = index + 1;
            var startIndex   = currentIndex;

            while (currentIndex < length)
            {
                var c = path[currentIndex];

                if (c == ']')
                {
                    Debug.Assert(startIndex < length);
                    Debug.Assert(startIndex <= currentIndex);

                    var value = path.Substring(startIndex, currentIndex - startIndex).Trim();
                    if (value.Length <= 0)
                    {
                        return(false);
                    }

                    // The value is parsed twice in order to get a standard name that could be used as a key for further use.
                    var parametersList = IndexerParametersParser.Parse(value);
                    var parameters     = IndexerParametersParser.Parse(parametersList);
                    if (string.IsNullOrEmpty(parameters))
                    {
                        return(false);
                    }

                    builder.PushDescendant(new PropertyRouteSegment(PropertyRouteSegmentType.Indexer, parameters));
                    index = currentIndex + 1;

                    return(true);
                }
                else if (PropertyRouteParser.ReservedSymbols.IndexOf(c) >= 0)
                {
                    return(false);
                }

                currentIndex++;
            }

            return(false);
        }
Beispiel #2
0
        internal static IndexerDescriptor Create(PropertyInfo propertyInfo, object[] parameterNames, object[] parameterValues)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }

            if (parameterNames == null)
            {
                throw new ArgumentNullException("parameterNames");
            }

            if (parameterNames.Length <= 0)
            {
                throw new ArgumentException("The indexer must contain at least one index.", "parameterNames");
            }

            if (parameterValues == null)
            {
                throw new ArgumentNullException("parameterValues");
            }

            if (parameterValues.Length <= 0)
            {
                throw new ArgumentException("The indexer must contain at least one index.", "parameterValues");
            }

            var parameters = propertyInfo.GetIndexParameters();

            if ((parameters == null) || (parameters.Length <= 0))
            {
                throw new ArgumentException("The target property is not a valid indexer.", "propertyInfo");
            }

            var attributes = (from entry in propertyInfo.GetCustomAttributes(true)
                              let attr = (entry as Attribute)
                                         where (attr != null)
                                         select attr).ToArray();
            var parametersList = IndexerParametersParser.Parse(parameterNames);
            var indexerName    = propertyInfo.Name;

            return(new IndexerDescriptor(indexerName, parametersList, parameterValues, propertyInfo, attributes));
        }
        internal static IEnumerable <string> Parse(string value)
        {
            var parameters = (value != null) ? value.Trim() : string.Empty;
            var length     = parameters.Length;

            if (length <= 0)
            {
                return(Enumerable.Empty <string>());
            }

            var values = new List <string>();
            var state  = ParserState.Start;
            var index  = 0;

            while (index < length)
            {
                var c = parameters[index];

                switch (state)
                {
                case ParserState.Start:
                {
                    if (char.IsWhiteSpace(c))
                    {
                        index++;
                    }
                    else
                    {
                        state = ParserState.FindValue;
                    }
                }
                break;

                case ParserState.FindValue:
                {
                    if (char.IsWhiteSpace(c))
                    {
                        index++;
                    }
                    else if (c == IndexerParametersParser.Separator)
                    {
                        // A parameter is missing.
                        return(Enumerable.Empty <string>());
                    }
                    else if (c == IndexerParametersParser.DoubleQuote)
                    {
                        state = ParserState.ExtractString;
                    }
                    else
                    {
                        state = ParserState.ExtractValue;
                    }
                }
                break;

                case ParserState.FindSeparator:
                {
                    if (char.IsWhiteSpace(c))
                    {
                        index++;
                    }
                    else if (c == IndexerParametersParser.Separator)
                    {
                        index++;
                        state = ParserState.FindValue;
                    }
                    else
                    {
                        // Unexpected character.
                        return(Enumerable.Empty <string>());
                    }
                }
                break;

                case ParserState.ExtractString:
                {
                    if (!IndexerParametersParser.AddString(parameters, length, ref index, values))
                    {
                        return(Enumerable.Empty <string>());
                    }

                    state = ParserState.FindSeparator;
                }
                break;

                case ParserState.ExtractValue:
                {
                    if (!IndexerParametersParser.AddValue(parameters, length, ref index, values))
                    {
                        return(Enumerable.Empty <string>());
                    }

                    state = ParserState.FindSeparator;
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }

            if (state != ParserState.FindSeparator)
            {
                return(Enumerable.Empty <string>());
            }

            return(values);
        }