Example #1
0
        public void TestExtensions()
        {
            {
                var path = new UPath("/a/b/c/d.txt");
                Assert.Equal(new UPath("/a/b/c"), path.GetDirectory());
                Assert.Equal("d.txt", path.GetName());
                Assert.Equal("d", path.GetNameWithoutExtension());
                Assert.Equal(".txt", path.GetExtensionWithDot());
                var newPath = path.ChangeExtension(".zip");
                Assert.Equal("/a/b/c/d.zip", newPath.FullName);
                Assert.Equal(new UPath("a/b/c/d.txt"), path.ToRelative());
                Assert.Equal(path, path.AssertAbsolute());
                Assert.Throws <ArgumentNullException>(() => new UPath().AssertNotNull());
                Assert.Throws <ArgumentException>(() => new UPath("not_absolute").AssertAbsolute());
            }

            {
                var path = new UPath("d.txt");
                Assert.Equal(UPath.Empty, path.GetDirectory());
                Assert.Equal("d.txt", path.GetName());
                Assert.Equal("d", path.GetNameWithoutExtension());
                Assert.Equal(".txt", path.GetExtensionWithDot());
                var newPath = path.ChangeExtension(".zip");
                Assert.Equal("d.zip", newPath.FullName);
                Assert.Equal(new UPath("d.txt"), path.ToRelative());
            }
        }
Example #2
0
        public FileOpenedEventArgs(UPath fullPath)
        {
            fullPath.AssertNotNull(nameof(fullPath));
            fullPath.AssertAbsolute(nameof(fullPath));

            OpenedPath = fullPath;
        }
Example #3
0
        /// <summary>
        /// Finds the list of <see cref="FileSystemEntry"/> for each file or directory found at the specified path for each registered filesystems (in order).
        /// The type of the first entry (file or directory) dictates the type of the following entries in the list (e.g if a file is coming first, only files will be showned for the specified path).
        /// </summary>
        /// <param name="path">To check for an entry</param>
        /// <returns>A list of file entries for the specified path</returns>
        public List <FileSystemEntry> FindFileSystemEntries(UPath path)
        {
            path.AssertAbsolute();
            var paths = new List <FileSystemPath>();

            FindPaths(path, SearchTarget.Both, paths);
            var result = new List <FileSystemEntry>(paths.Count);

            if (paths.Count == 0)
            {
                return(result);
            }

            var isFile = paths[0].IsFile;

            foreach (var pathItem in paths)
            {
                if (pathItem.IsFile == isFile)
                {
                    if (isFile)
                    {
                        result.Add(new FileEntry(pathItem.FileSystem, pathItem.Path));
                    }
                    else
                    {
                        result.Add(new DirectoryEntry(pathItem.FileSystem, pathItem.Path));
                    }
                }
            }
            return(result);
        }
Example #4
0
        public bool TryCopyFile(FileEntry fromFile, UPath outputPath)
        {
            if (fromFile == null)
            {
                throw new ArgumentNullException(nameof(fromFile));
            }
            outputPath.AssertAbsolute(nameof(outputPath));

            var outputFile = new FileEntry(Site.OutputFileSystem, outputPath);

            TrackDestination(outputFile, fromFile);

            if (!outputFile.Exists || (fromFile.LastWriteTime > outputFile.LastWriteTime))
            {
                CreateDirectory(outputFile.Directory);

                if (Site.CanTrace())
                {
                    Site.Trace($"Copy file from [{fromFile} to [{outputPath}]");
                }

                fromFile.CopyTo(outputFile.FullName, true);
                return(true);
                // Update statistics
                //stat.Static = true;
                //stat.OutputBytes += fromFile.Length;
            }
            return(false);
        }
Example #5
0
 private void AssertMountName(UPath name)
 {
     name.AssertAbsolute(nameof(name));
     if (name == UPath.Root)
     {
         throw new ArgumentException("The mount name cannot be a `/` root filesystem", nameof(name));
     }
 }
Example #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SubFileSystem"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system to create a view from.</param>
 /// <param name="subPath">The sub path view to create filesystem.</param>
 /// <param name="owned">True if <paramref name="fileSystem"/> should be disposed when this instance is disposed.</param>
 /// <exception cref="DirectoryNotFoundException">If the directory subPath does not exist in the delegate FileSystem</exception>
 public SubFileSystem(IFileSystem fileSystem, UPath subPath, bool owned = true) : base(fileSystem, owned)
 {
     SubPath = subPath.AssertAbsolute(nameof(subPath));
     if (!fileSystem.DirectoryExists(SubPath))
     {
         throw NewDirectoryNotFoundException(SubPath);
     }
 }
Example #7
0
        public FileRenamedEventArgs(IFileSystem fileSystem, WatcherChangeTypes changeType, UPath fullPath, UPath oldFullPath)
            : base(fileSystem, changeType, fullPath)
        {
            fullPath.AssertNotNull(nameof(oldFullPath));
            fullPath.AssertAbsolute(nameof(oldFullPath));

            OldFullPath = oldFullPath;
            OldName     = oldFullPath.GetName();
        }
Example #8
0
        /// <summary>
        /// Validates the specified path (Check that it is absolute by default)
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="name">The name.</param>
        /// <param name="allowNull">if set to <c>true</c> the path is allowed to be null. <c>false</c> otherwise.</param>
        /// <returns>The path validated</returns>
        protected UPath ValidatePath(UPath path, string name = "path", bool allowNull = false)
        {
            if (allowNull && path.IsNull)
            {
                return(path);
            }
            path.AssertAbsolute(name);

            return(ValidatePathImpl(path, name));
        }
Example #9
0
        public FileSystemWatcher(IFileSystem fileSystem, UPath path)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            path.AssertAbsolute();

            FileSystem = fileSystem;
            Path       = path;
        }
Example #10
0
        private void AssertMountName(UPath name)
        {
            name.AssertAbsolute();
            if (name == UPath.Root)
            {
                throw new ArgumentException("The mount name cannot be a `/` root filesystem", nameof(name));
            }

            if (name.GetDirectory() != UPath.Root)
            {
                throw new ArgumentException("The mount name cannot contain subpath and must contain only a root path e.g `/mount`", nameof(name));
            }
        }
Example #11
0
        /// <summary>
        /// Finds the first <see cref="FileSystemEntry"/> from this aggregate system found at the specified path for each registered filesystems (in order).
        /// The type of the first entry (file or directory) dictates the type of the following entries in the list (e.g if a file is coming first, only files will be showned for the specified path).
        /// </summary>
        /// <param name="path">To check for an entry</param>
        /// <returns>A file system entry or null if it was not found.</returns>
        public FileSystemEntry?FindFirstFileSystemEntry(UPath path)
        {
            path.AssertAbsolute();
            var entry = TryGetPath(path);

            if (!entry.HasValue)
            {
                return(null);
            }

            var pathItem = entry.Value;

            return(pathItem.IsFile ? (FileSystemEntry) new FileEntry(pathItem.FileSystem, pathItem.Path) : new DirectoryEntry(pathItem.FileSystem, pathItem.Path));
        }
Example #12
0
        public FileChangedEventArgs(IFileSystem fileSystem, WatcherChangeTypes changeType, UPath fullPath)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            fullPath.AssertNotNull(nameof(fullPath));
            fullPath.AssertAbsolute(nameof(fullPath));

            FileSystem = fileSystem;
            ChangeType = changeType;
            FullPath   = fullPath;
            Name       = fullPath.GetName();
        }
Example #13
0
        /// <summary>
        /// Attempts to find information about the mount that a given path maps to.
        /// </summary>
        /// <param name="path">The path to search for.</param>
        /// <param name="name">The mount name that the <paramref name="path"/> belongs to.</param>
        /// <param name="fileSystem">The mounted filesystem that the <paramref name="path"/> is located in.</param>
        /// <param name="fileSystemPath">The path inside of <paramref name="fileSystem"/> that refers to the file at <paramref name="path"/>.</param>
        /// <returns>True if the <paramref name="path"/> was found in a mounted filesystem.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="path"/> must not be null.</exception>
        /// <exception cref="System.ArgumentException">The <paramref name="path"/> must be absolute.</exception>
        public bool TryGetMount(UPath path, out UPath name, out IFileSystem fileSystem, out UPath fileSystemPath)
        {
            path.AssertNotNull();
            path.AssertAbsolute();

            var fs = TryGetMountOrNext(ref path, out name);

            if (fs == null || name.IsNull)
            {
                name           = null;
                fileSystem     = null;
                fileSystemPath = null;
                return(false);
            }

            fileSystem     = fs;
            fileSystemPath = path;
            return(true);
        }
Example #14
0
        private SearchPattern(ref UPath path, ref string searchPattern)
        {
            path.AssertAbsolute();
            if (searchPattern == null)
            {
                throw new ArgumentNullException(nameof(searchPattern));
            }

            _exactMatch = null;
            _regexMatch = null;

            //Optimized path, most common case
            if (searchPattern == "*" && path == UPath.Root)
            {
                return;
            }

            if (searchPattern.StartsWith("/"))
            {
                throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`");
            }

            searchPattern = searchPattern.Replace('\\', '/');

            // If the path contains any directory, we need to concatenate the directory part with the input path
            if (searchPattern.IndexOf('/') > 0)
            {
                var pathPattern = new UPath(searchPattern);
                var directory   = pathPattern.GetDirectory();
                if (!directory.IsNull && !directory.IsEmpty)
                {
                    path /= directory;
                }
                searchPattern = pathPattern.GetName();

                // If the search pattern is again a plain any, optimized path
                if (searchPattern == "*")
                {
                    return;
                }
            }

            var           startIndex = 0;
            StringBuilder builder    = null;

            try
            {
                int nextIndex;
                while ((nextIndex = searchPattern.IndexOfAny(SpecialChars, startIndex)) >= 0)
                {
                    if (builder == null)
                    {
                        builder = new StringBuilder();
                        builder.Append("^");
                    }

                    var lengthToEscape = nextIndex - startIndex;
                    if (lengthToEscape > 0)
                    {
                        var toEscape = Regex.Escape(searchPattern.Substring(startIndex, lengthToEscape));
                        builder.Append(toEscape);
                    }

                    var c = searchPattern[nextIndex];
                    var regexPatternPart = c == '*' ? ".*" : ".";
                    builder.Append(regexPatternPart);

                    startIndex = nextIndex + 1;
                }
                if (builder == null)
                {
                    _exactMatch = searchPattern;
                }
                else
                {
                    var length = searchPattern.Length - startIndex;
                    if (length > 0)
                    {
                        var toEscape = Regex.Escape(searchPattern.Substring(startIndex, length));
                        builder.Append(toEscape);
                    }

                    builder.Append("$");

                    var regexPattern = builder.ToString();
                    _regexMatch = new Regex(regexPattern);
                }
            }
            finally
            {
                if (builder != null)
                {
                    builder.Length = 0;
                }
            }
        }
Example #15
0
        private SearchPattern(ref UPath path, ref string searchPattern)
        {
            path.AssertAbsolute();
            if (searchPattern == null)
            {
                throw new ArgumentNullException(nameof(searchPattern));
            }

            _exactMatch = null;
            _regexMatch = null;

            //Optimized path, most common case
            if (searchPattern == "*" && path == UPath.Root)
            {
                return;
            }

            if (searchPattern.StartsWith("/"))
            {
                throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`");
            }

            // Normalize path separators
            searchPattern = searchPattern.Replace('\\', '/');

            // If the path contains any directory, we need to concatenate the directory part with the input path (?)
            if (searchPattern.IndexOf('/') > 0)
            {
                var pathPattern = new UPath(searchPattern);
                var directory   = pathPattern.GetDirectory();
                if (!directory.IsNull && !directory.IsEmpty)
                {
                    path /= directory;
                }
                searchPattern = pathPattern.GetName();

                // If the search pattern is again a plain any, optimized path
                if (searchPattern == "*")
                {
                    return;
                }
            }

            var  regexBuilder      = new StringBuilder("^");
            bool containsWildcards = false;

            // Loop through parts of searchPattern separated by wildcards
            for (int index = 0, nextWildcard = 0; nextWildcard != -1; index = nextWildcard + 1)
            {
                // Next wildcard occurence
                nextWildcard = searchPattern.IndexOfAny(WildcardChars, index);

                // Escape & append text up to next wildcard
                // If no new wildcard, append up to end of string
                var endOfPart = nextWildcard != -1 ? nextWildcard : searchPattern.Length;
                regexBuilder.Append(Regex.Escape(searchPattern.Substring(index, endOfPart - index)));

                // Convert & append wildcard, if applicable
                if (nextWildcard != -1)
                {
                    var wc = searchPattern[nextWildcard];
                    var regexPatternPart = wc switch
                    {
                        '*' => ".*",
                        '?' => ".",
                        _ => throw new ArgumentException($"Unknown wildcard: {wc}")
                    };
                    regexBuilder.Append(regexPatternPart);
                    containsWildcards = true;
                }
            }

            regexBuilder.Append("$");

            if (!containsWildcards)
            {
                _exactMatch = searchPattern;
            }
            else
            {
                _regexMatch = new Regex(regexBuilder.ToString());
            }
        }
    }
Example #16
0
        public bool TryCopyContentToOutput(ContentObject fromFile, UPath outputPath)
        {
            if (fromFile == null)
            {
                throw new ArgumentNullException(nameof(fromFile));
            }
            outputPath.AssertAbsolute();

            var clock = Stopwatch.StartNew();

            var outputFile = new FileEntry(Site.OutputFileSystem, outputPath);
            var outputDir  = outputFile.Directory;

            if (outputDir == null)
            {
                throw new ArgumentException("Output directory cannot be empty", nameof(outputPath));
            }
            TrackDestination(outputFile, fromFile.SourceFile);

            var stat = Site.Statistics.GetContentStat(fromFile);

            CreateDirectory(outputDir);

            try
            {
                // If the file has a content, we will use this instead
                if (fromFile.Content != null)
                {
                    if (Site.CanTrace())
                    {
                        Site.Trace($"Write file [{outputFile}]");
                    }

                    using (var writer = new StreamWriter(outputFile.Open(FileMode.Create, FileAccess.Write)))
                    {
                        writer.Write(fromFile.Content);
                        writer.Flush();

                        // Update statistics
                        stat.Static       = false;
                        stat.OutputBytes += writer.BaseStream.Length;
                    }
                }
                // If the source file is not newer than the destination file, don't overwrite it
                else if (fromFile.SourceFile != null && (!outputFile.Exists || (fromFile.ModifiedTime > outputFile.LastWriteTime)))
                {
                    if (Site.CanTrace())
                    {
                        Site.Trace($"Write file [{outputFile}]");
                    }

                    // If the output file is readonly, make sure that it is not readonly before overwriting
                    if (outputFile.Exists && (outputFile.Attributes & FileAttributes.ReadOnly) != 0)
                    {
                        outputFile.Attributes = outputFile.Attributes & ~FileAttributes.ReadOnly;
                    }

                    fromFile.SourceFile.CopyTo(outputFile, true);

                    // Don't copy readonly attributes for output folder
                    outputFile.Attributes = fromFile.SourceFile.Attributes & ~FileAttributes.ReadOnly;

                    // Update statistics
                    stat.Static       = true;
                    stat.OutputBytes += fromFile.Length;
                }
            }
            catch (Exception ex)
            {
                Site.Error(fromFile.SourceFile != null
                    ? $"Unable to copy file [{fromFile.SourceFile}] to [{outputFile}]. Reason:{ex.GetReason()}"
                    : $"Unable to copy file to [{outputFile}]. Reason:{ex.GetReason()}");
                return(false);
            }
            finally
            {
                stat.OutputTime += clock.Elapsed;
            }

            return(true);
        }