Exemple #1
0
        /// <summary>
        /// Implementation of parsing, returning the error message for a FormatException if parsing fails.
        /// </summary>
        private string TryParseNameInternal(string name, out TemplatedResourceName result)
        {
            GaxPreconditions.CheckNotNull(name, nameof(name));
            string serviceName = null;

            if (name.StartsWith("//"))
            {
                int nameEnd = name.IndexOf('/', 2);
                // Can't call ValidateServiceName as we don't want to throw...
                if (nameEnd == 2)
                {
                    result = null;
                    return("Service name cannot be empty");
                }
                // It's *just about* plausible to have a template of ** and a value of "//service".
                if (nameEnd == -1)
                {
                    serviceName = name.Substring(2);
                    name        = "";
                }
                else
                {
                    serviceName = name.Substring(2, nameEnd - 2);
                    name        = name.Substring(nameEnd + 1);
                }
            }
            string[] nameSegments = name == "" ? new string[0] : name.Split(s_slashSplit);
            if (_hasPathWildcard)
            {
                // The path wildcard can be empty...
                if (nameSegments.Length < _segments.Count - 1)
                {
                    result = null;
                    return("Name does not match template: too few segments");
                }
            }
            else if (nameSegments.Length != _segments.Count)
            {
                result = null;
                return("Name does not match template: incorrect number of segments");
            }
            string[] resourceIds      = new string[ParameterCount];
            int      resourceIdIndex  = 0;
            int      nameSegmentIndex = 0;

            foreach (var segment in _segments)
            {
                switch (segment.Kind)
                {
                case SegmentKind.Literal:
                    var nameSegment = nameSegments[nameSegmentIndex++];
                    if (nameSegment != segment.Value)
                    {
                        result = null;
                        return($"Name does not match template in literal segment: '{nameSegment}' != '{segment.Value}'");
                    }
                    break;

                case SegmentKind.Wildcard:
                    // Could use segment.ValidateWildcard, but the exception wouldn't be as clean.
                    var value = nameSegments[nameSegmentIndex++];
                    if (value == "")
                    {
                        result = null;
                        return("Name does not match template: wildcard segment is empty");
                    }
                    resourceIds[resourceIdIndex++] = value;
                    break;

                case SegmentKind.PathWildcard:
                    // Work out how many segments to consume based on the number of segments in the template and the
                    // actual number of segments in the specified name
                    int count = nameSegments.Length - _segments.Count + 1;
                    // Make the common case more efficient
                    if (count == 1)
                    {
                        resourceIds[resourceIdIndex++] = nameSegments[nameSegmentIndex++];
                    }
                    else
                    {
                        resourceIds[resourceIdIndex++] = string.Join("/", nameSegments.Skip(nameSegmentIndex).Take(count));
                        nameSegmentIndex += count;
                    }
                    break;
                }
            }
            result = TemplatedResourceName.CreateWithShallowCopy(this, serviceName, resourceIds);
            return(null); // Success!
        }
Exemple #2
0
 /// <summary>
 /// Attempts to parse the given resource name against this template, returning <c>null</c> on failure.
 /// </summary>
 /// <remarks>
 /// Although this method returns <c>null</c> if a name is passed in which doesn't match the template,
 /// it still throws <see cref="ArgumentNullException"/> if <paramref name="name"/> is null, as this would
 /// usually indicate a programming error rather than a data error.
 /// </remarks>
 /// <param name="name">The resource name to parse against this template. Must not be null.</param>
 /// <param name="result">When this method returns, the parsed resource name or <c>null</c> if parsing fails.</param>
 /// <returns><c>true</c> if the name was parsed successfully; <c>false</c> otherwise.</returns>
 public bool TryParseName(string name, out TemplatedResourceName result)
 {
     return(TryParseNameInternal(name, out result) == null);
 }