예제 #1
0
        public void AddDirectory(string path)
        {
            var fixedPath = FixPath(path, true);
            var separator = Path.DirectorySeparatorChar.ToString();

            lock (files)
            {
                if (FileExists(fixedPath) &&
                    (GetFile(fixedPath).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    throw CommonExceptions.AccessDenied(fixedPath);
                }

                var lastIndex = 0;
                var isUnc     =
                    StringOperations.StartsWith(fixedPath, @"\\") ||
                    StringOperations.StartsWith(fixedPath, @"//");

                if (isUnc)
                {
                    //First, confirm they aren't trying to create '\\server\'
                    lastIndex = StringOperations.IndexOf(fixedPath, separator, 2);

                    if (lastIndex < 0)
                    {
                        throw CommonExceptions.InvalidUncPath(nameof(path));
                    }

                    /*
                     * Although CreateDirectory(@"\\server\share\") is not going to work in real code, we allow it here for the purposes of setting up test doubles.
                     * See PR https://github.com/System-IO-Abstractions/System.IO.Abstractions/pull/90 for conversation
                     */
                }

                while ((lastIndex = StringOperations.IndexOf(fixedPath, separator, lastIndex + 1)) > -1)
                {
                    var segment = fixedPath.Substring(0, lastIndex + 1);
                    if (!Directory.Exists(segment))
                    {
                        SetEntry(segment, new MockDirectoryData());
                    }
                }

                var s = StringOperations.EndsWith(fixedPath, separator) ? fixedPath : fixedPath + separator;
                SetEntry(s, new MockDirectoryData());
            }
        }
예제 #2
0
        public override string GetFullPath(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path), StringResources.Manager.GetString("VALUE_CANNOT_BE_NULL"));
            }

            if (path.Length == 0)
            {
                throw CommonExceptions.PathIsNotOfALegalForm(nameof(path));
            }

            path = path.Replace(AltDirectorySeparatorChar, DirectorySeparatorChar);

            bool isUnc =
                mockFileDataAccessor.StringOperations.StartsWith(path, @"\\") ||
                mockFileDataAccessor.StringOperations.StartsWith(path, @"//");

            string root = GetPathRoot(path);

            bool hasTrailingSlash = path.Length > 1 && path[path.Length - 1] == DirectorySeparatorChar;

            string[] pathSegments;

            if (root.Length == 0)
            {
                // relative path on the current drive or volume
                path         = mockFileDataAccessor.Directory.GetCurrentDirectory() + DirectorySeparatorChar + path;
                pathSegments = GetSegments(path);
            }
            else if (isUnc)
            {
                // unc path
                pathSegments = GetSegments(path);
                if (pathSegments.Length < 2)
                {
                    throw CommonExceptions.InvalidUncPath(nameof(path));
                }
            }
            else if (mockFileDataAccessor.StringOperations.Equals(@"\", root) ||
                     mockFileDataAccessor.StringOperations.Equals(@"/", root))
            {
                // absolute path on the current drive or volume
                pathSegments = GetSegments(GetPathRoot(mockFileDataAccessor.Directory.GetCurrentDirectory()), path);
            }
            else
            {
                pathSegments = GetSegments(path);
            }

            // unc paths need at least two segments, the others need one segment
            var isUnixRooted = mockFileDataAccessor.StringOperations.StartsWith(
                mockFileDataAccessor.Directory.GetCurrentDirectory(),
                string.Format(CultureInfo.InvariantCulture, "{0}", DirectorySeparatorChar));

            var minPathSegments = isUnc
                ? 2
                : isUnixRooted ? 0 : 1;

            var stack = new Stack <string>();

            foreach (var segment in pathSegments)
            {
                if (mockFileDataAccessor.StringOperations.Equals("..", segment))
                {
                    // only pop, if afterwards are at least the minimal amount of path segments
                    if (stack.Count > minPathSegments)
                    {
                        stack.Pop();
                    }
                }
                else if (mockFileDataAccessor.StringOperations.Equals(".", segment))
                {
                    // ignore .
                }
                else
                {
                    stack.Push(segment);
                }
            }

            var fullPath = string.Join(string.Format(CultureInfo.InvariantCulture, "{0}", DirectorySeparatorChar), stack.Reverse().ToArray());

            if (hasTrailingSlash)
            {
                fullPath += DirectorySeparatorChar;
            }

            if (isUnixRooted && !isUnc)
            {
                fullPath = DirectorySeparatorChar + fullPath;
            }
            else if (isUnixRooted)
            {
                fullPath = @"//" + fullPath;
            }
            else if (isUnc)
            {
                fullPath = @"\\" + fullPath;
            }

            return(fullPath);
        }