예제 #1
0
        public static PathInfo Parse(string path)
        {
            if (path == "null")
            {
                return(Empty);
            }

            var originalPath  = path;
            var pathType      = GetPathType(path);
            var pathSubstring = new Substring(path);

            var isValidHelperLiteral = true;
            var isVariable           = pathType == PathType.Variable;
            var isInversion          = pathType == PathType.Inversion;
            var isBlockHelper        = pathType == PathType.BlockHelper;

            if (isVariable || isBlockHelper || isInversion)
            {
                isValidHelperLiteral = isBlockHelper || isInversion;
                pathSubstring        = new Substring(pathSubstring, 1);
            }

            var segments           = new List <PathSegment>();
            var pathParts          = Substring.Split(pathSubstring, '/');
            var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathParts);

            while (extendedEnumerator.MoveNext())
            {
                var segment = extendedEnumerator.Current.Value;
                if (segment.Length == 2 && segment[0] == '.' && segment[1] == '.')
                {
                    isValidHelperLiteral = false;
                    segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>()));
                    continue;
                }

                if (segment.Length == 1 && segment[0] == '.')
                {
                    isValidHelperLiteral = false;
                    segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>()));
                    continue;
                }

                var chainSegments = GetPathChain(segment);
                if (chainSegments.Length > 1)
                {
                    isValidHelperLiteral = false;
                }

                segments.Add(new PathSegment(segment, chainSegments));
            }

            if (isValidHelperLiteral && segments.Count > 1)
            {
                isValidHelperLiteral = false;
            }

            return(new PathInfo(pathType, originalPath, isValidHelperLiteral, segments.ToArray()));
        }
예제 #2
0
        public static PathInfo Parse(string path)
        {
            if (path == "null")
            {
                return(new PathInfo(PathType.Empty, path, false, 0, null));
            }

            var originalPath  = path;
            var pathSubstring = new Substring(path);

            var isValidHelperLiteral = true;
            var pathType             = GetPathType(pathSubstring);
            var isVariable           = pathType == PathType.Variable;
            var isInversion          = pathType == PathType.Inversion;
            var isBlockHelper        = pathType == PathType.BlockHelper;

            if (isVariable || isBlockHelper || isInversion)
            {
                isValidHelperLiteral = isBlockHelper || isInversion;
                pathSubstring        = new Substring(pathSubstring, 1);
            }

            var contextChangeCount = 0;
            var segments           = new List <PathSegment>();
            var pathParts          = Substring.Split(pathSubstring, '/');

            if (pathParts.Count > 1)
            {
                isValidHelperLiteral = false;
            }
            for (var index = 0; index < pathParts.Count; index++)
            {
                var segment = pathParts[index];
                if (segment.Length == 2 && segment[0] == '.' && segment[1] == '.')
                {
                    contextChangeCount++;
                    isValidHelperLiteral = false;
                    segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>()));
                    continue;
                }

                if (segment.Length == 1 && segment[0] == '.')
                {
                    isValidHelperLiteral = false;
                    segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>()));
                    continue;
                }

                var chainSegments = GetPathChain(segment).ToArray();
                if (chainSegments.Length > 1)
                {
                    isValidHelperLiteral = false;
                }

                segments.Add(new PathSegment(segment, chainSegments));
            }

            return(new PathInfo(pathType, originalPath, isValidHelperLiteral, contextChangeCount, segments));
        }
예제 #3
0
        public void Split(string input, char splitChar, string[] expected)
        {
            var substring = new Substring(input);
            var split     = Substring.Split(substring, splitChar);

            for (var index = 0; index < expected.Length; index++)
            {
                Assert.True(split[index] == expected[index]);
            }
        }
예제 #4
0
        public void Split(string input, char splitChar, string[] expected)
        {
            var substring = new Substring(input);
            var split     = Substring.Split(substring, splitChar);

            var index = 0;

            while (split.MoveNext())
            {
                Assert.Equal(split.Current, expected[index++]);
            }
        }
예제 #5
0
        private static ChainSegment[] GetPathChain(Substring segmentString)
        {
            var insideEscapeBlock  = false;
            var pathChainParts     = Substring.Split(segmentString, '.', StringSplitOptions.RemoveEmptyEntries);
            var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathChainParts);

            if (!extendedEnumerator.Any && segmentString == ".")
            {
                return new[] { ChainSegment.This }
            }
            ;

            var chainSegments = new List <ChainSegment>();

            while (extendedEnumerator.MoveNext())
            {
                var next = extendedEnumerator.Current.Value;

                if (insideEscapeBlock)
                {
                    if (next.EndsWith(']'))
                    {
                        insideEscapeBlock = false;
                    }

                    chainSegments[chainSegments.Count - 1] = ChainSegment.Create($"{chainSegments[chainSegments.Count - 1]}.{next.ToString()}");
                    continue;
                }

                if (next.StartsWith('['))
                {
                    insideEscapeBlock = true;
                }

                if (next.EndsWith(']'))
                {
                    insideEscapeBlock = false;
                }

                chainSegments.Add(ChainSegment.Create(next.ToString()));
            }

            return(chainSegments.ToArray());
        }
예제 #6
0
        private static IReadOnlyList <ChainSegment> GetPathChain(Substring segmentString)
        {
            var insideEscapeBlock = false;
            var pathChainParts    = Substring.Split(segmentString, '.', StringSplitOptions.RemoveEmptyEntries);

            if (pathChainParts.Count == 0 && segmentString == ".")
            {
                return new[] { ChainSegment.Create("this") }
            }
            ;

            var chainSegments = new List <ChainSegment>();

            var count = pathChainParts.Count;

            for (int index = 0; index < count; index++)
            {
                var next = pathChainParts[index];
                if (insideEscapeBlock)
                {
                    if (next.EndsWith(']'))
                    {
                        insideEscapeBlock = false;
                    }

                    chainSegments[chainSegments.Count - 1] = ChainSegment.Create($"{chainSegments[chainSegments.Count - 1]}.{next.ToString()}");
                    continue;
                }

                if (next.StartsWith('['))
                {
                    insideEscapeBlock = true;
                }

                if (next.EndsWith(']'))
                {
                    insideEscapeBlock = false;
                }

                chainSegments.Add(ChainSegment.Create(next.ToString()));
            }

            return(chainSegments);
        }
예제 #7
0
        public static PathInfo Parse(string path)
        {
            if (path == "null")
            {
                return(Empty);
            }

            var originalPath  = path;
            var pathType      = GetPathType(path);
            var pathSubstring = new Substring(path);

            var isValidHelperLiteral = true;
            var isVariable           = pathType == PathType.Variable;
            var isInversion          = pathType == PathType.Inversion;
            var isBlockHelper        = pathType == PathType.BlockHelper;

            if (isVariable || isBlockHelper || isInversion)
            {
                isValidHelperLiteral = isBlockHelper || isInversion;
                pathSubstring        = new Substring(pathSubstring, 1);
            }

            var segments           = new List <PathSegment>();
            var pathParts          = Substring.Split(pathSubstring, '/');
            var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathParts);

            using var container = StringBuilderPool.Shared.Use();
            var buffer = container.Value;

            while (extendedEnumerator.MoveNext())
            {
                var segment = extendedEnumerator.Current.Value;
                if (buffer.Length != 0)
                {
                    buffer.Append('/');
                    buffer.Append(in segment);
                    if (Substring.LastIndexOf(segment, ']', out var index) &&
                        !Substring.LastIndexOf(segment, '[', index, out _))
                    {
                        var chainSegment = GetPathChain(buffer.ToString());
                        if (chainSegment.Length > 1)
                        {
                            isValidHelperLiteral = false;
                        }

                        segments.Add(new PathSegment(segment, chainSegment));
                        buffer.Length = 0;
                        continue;
                    }
                }

                if (Substring.LastIndexOf(segment, '[', out var startIndex) &&
                    !Substring.LastIndexOf(segment, ']', startIndex, out _))
                {
                    buffer.Append(in segment);
                    continue;
                }

                switch (segment.Length)
                {
                case 2 when segment[0] == '.' && segment[1] == '.':
예제 #8
0
        // #############################################################################################
        // Internals
        // #############################################################################################

        /** ****************************************************************************************
         * Internal, recursive helper of #Find.
         *
         * @param       domainPath  Path to search.
         * @param       sensitivity Denotes if domain name search is treated case sensitive or not.
         * @param       maxCreate   The maximum number of sub domains that are created if not
         *                          found at the end of the path.
         * @param[out]  wasCreated  Output parameter that is set \c true if domain was not found
         *                          and hence created.
         * @return The domain found or created.
         ******************************************************************************************/
        protected Domain findRecursive(Substring domainPath, Case sensitivity,
                                       int maxCreate, ref bool wasCreated)
        {
            //--- get act sub-name and rest of path
            domainPath.Consume(PathSeparator);
            int endSubName = domainPath.IndexOf(PathSeparator);

            ALIB.ASSERT_ERROR(endSubName != 0, "Internal Error");

            // find end of actual domain name and save rest
            Substring restOfDomainPath = tSubstring2;

            restOfDomainPath.SetNull();
            if (endSubName > 0)
            {
                domainPath.Split(endSubName, restOfDomainPath, 1);
            }

            // search sub-domain
            Domain subDomain = null;

            // "."
            if (domainPath.Equals("."))
            {
                subDomain = this;
            }

            // ".."
            else if (domainPath.Equals(".."))
            {
                subDomain = Parent != null ? Parent : this;
            }


            // search in sub-domain
            else
            {
                int  i;
                bool fixedOnce = false;
                for (;;)
                {
                    for (i = 0; i < SubDomains.Count; i++)
                    {
                        int comparison = SubDomains[i].Name.CompareTo(domainPath, sensitivity);
                        if (comparison >= 0)
                        {
                            if (comparison == 0)
                            {
                                subDomain = SubDomains[i];
                            }
                            break;
                        }
                    }

                    // domain found?
                    if (subDomain != null)
                    {
                        break;
                    }

                    // try and fix name
                    if (!fixedOnce)
                    {
                        fixedOnce = true;

                        bool illegalCharacterFound = false;
                        for (int cp = 0; cp < domainPath.Length(); ++cp)
                        {
                            char c = domainPath.CharAt(cp);
                            if (c < '-' || c > 'z' ||
                                c == '<' || c == '>' ||
                                c == '[' || c == ']' ||
                                c == '=' || c == '?' || c == ';' || c == ':' ||
                                c == '\\' || c == '\'' || c == '.' || c == ','
                                )
                            {
                                illegalCharacterFound = true;
                                domainPath.Buf[domainPath.Start + cp] = '#';
                            }
                        }

                        if (illegalCharacterFound)
                        {
                            continue;
                        }
                    }

                    // create
                    if (maxCreate == 0)
                    {
                        return(null);
                    }
                    wasCreated = true;
                    SubDomains.Insert(i, subDomain = new Domain(this, new AString(domainPath)));
                    maxCreate--;
                    if (maxCreate == 0)
                    {
                        return(subDomain);
                    }

                    break;
                }
            }
            // recursion?
            if (restOfDomainPath.IsNotEmpty())
            {
                domainPath.Set(restOfDomainPath);
                return(subDomain.findRecursive(domainPath, sensitivity, maxCreate, ref wasCreated));
            }

            // that's it
            return(subDomain);
        }