XenAdmin.Actions.ZipStatusReportAction.SanitizeTarName C# (CSharp) Method

SanitizeTarName() private static method

Maps file/directory names that are illegal under Windows to 'sanitized' versions. The usedNames parameter ensures this is done consistently within a directory tree. The dictionary is used by SanitizeTarName() to ensure names are consistently sanitized. e.g.: dir1: -> dir1_ dir1? -> dir1_ (1) dir1_ -> dir1_ (2) dir1:/file -> dir1_/file dir1?/file -> dir1_ (1)/file Pass the same dictionary to each invocation to get unique outputs within the same tree.
private static SanitizeTarName ( string path, string>.Dictionary usedNames ) : string
path string
usedNames string>.Dictionary
return string
        private static string SanitizeTarName(string path, Dictionary<string, string> usedNames)
        {
            string sanitizedPath = "";
            Stack<string> bitsToEscape = new Stack<string>();
            // Trim any trailing slashes (usually indicates path is a directory)
            path = path.TrimEnd(new char[] { '/' });
            // Take members off the end of the path until we have a name that already is
            // a key in our dictionary, or until we have the empty string.
            while (!usedNames.ContainsKey(path) && path.Length > 0)
            {
                string[] bits = path.Split(new char[] { '/' });
                string lastBit = bits[bits.Length - 1];
                int lengthOfLastBit = lastBit.Length;
                bitsToEscape.Push(lastBit);
                path = path.Substring(0, path.Length - lengthOfLastBit);
                path = path.TrimEnd(new char[] { '/' });
            }

            if (usedNames.ContainsKey(path))
            {
                sanitizedPath = usedNames[path];
            }

            // Now for each member in the path, look up the escaping of that member if it exists; otherwise
            // generate a new, unique escaping. Then append the escaped member to the end of the sanitized
            // path and continue.
            foreach (string member in bitsToEscape)
            {
                System.Diagnostics.Trace.Assert(member.Length > 0);
                string sanitizedMember = SanitizeTarPathMember(member);
                sanitizedPath = Path.Combine(sanitizedPath, sanitizedMember);
                path = path + Path.DirectorySeparatorChar + member;

                // Note: even if sanitizedMember == member, we must add it to the dictionary, since
                // tar permits names that differ only in case, while Windows does not. We must e.g.:
                // abc -> abc
                // aBC -> aBC (1)

                if (usedNames.ContainsKey(path))
                {
                    // We have already generated an escaping for this path prefix: use it
                    sanitizedPath = usedNames[path];
                    continue;
                }

                // Generate the unique mapping
                string pre = sanitizedPath;
                int i = 1;
                while (DictionaryContainsIgnoringCase(usedNames, sanitizedPath))
                {
                    sanitizedPath = string.Format("{0} ({1})", pre, i);
                    i++;
                }

                usedNames.Add(path, sanitizedPath);
            }
            return sanitizedPath;
        }