private IFile OpenFile(UPath file) { if (file.GetName() == ".manifest") { throw new UnauthorizedAccessException("Unable to open manifest file."); } return(new File(this, new FileEntry(this.RootFileSystem, file), this.GetGuid(file.GetName()))); }
public static void SetPath(this IFileRef self, FileEntry file) { UPath value = file.Path; self.dir = "" + value.GetDirectory(); self.fileName = value.GetName(); }
public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext) { Stream dataStream; Stream indexStream; switch (filePath.GetName()) { case "mcb1.bln": dataStream = await fileSystem.OpenFileAsync(filePath); indexStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "mcb0.bln"); break; default: indexStream = await fileSystem.OpenFileAsync(filePath); dataStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "mcb1.bln"); break; } if (dataStream == null || indexStream == null) { throw new InvalidOperationException("This is no Bln archive."); } Files = _bln.Load(indexStream, dataStream); }
internal (Guid guid, bool isLink) RetrieveManifestRecord(UPath file, bool updateLink) { this.CheckDeleted(); var fileName = file.GetName(); lock (this.DatabaseLock) { return(this.Manifest.Query <(Guid, bool)>(conn => { var record = conn.Query <ManifestRecord>(@"SELECT uuid, is_link FROM directory_manifest WHERE filename = @fileName", new { fileName }); if (!record.Any() || updateLink) { // New file encountered. bool isLink = this.CheckIsLink(file); Guid guid = record.Any() ? new Guid(record.First().uuid) : Guid.NewGuid(); conn.Execute(@"INSERT OR REPLACE INTO directory_manifest (uuid, is_link, filename) VALUES (@guid, @isLink, @fileName)", new { guid, fileName, isLink }); record = conn.Query <ManifestRecord>(@"SELECT uuid, is_link FROM directory_manifest WHERE filename = @fileName", new { fileName }); } var _record = record.First(); return (new Guid(_record.uuid), _record.is_link); })); } }
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()); } }
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(); }
/// <summary> /// Determines whether the specified mount name is mounted. /// </summary> /// <param name="name">The mount name.</param> /// <returns><c>true</c> if the specified name is mounted; otherwise, <c>false</c>.</returns> public bool IsMounted(UPath name) { AssertMountName(name); var mountName = name.GetName(); lock (_mounts) { return(_mounts.ContainsKey(mountName)); } }
public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext) { var texPath = savePath; var pltPath = $"{savePath.GetDirectory()}/../Palettes(NW4R)/{savePath.GetName()}"; var texStream = fileSystem.OpenFile(texPath, FileMode.Create, FileAccess.Write); var pltStream = Images[0].ImageInfo.HasPaletteInformation ? fileSystem.OpenFile(pltPath, FileMode.Create, FileAccess.Write) : null; _img.Save(texStream, pltStream, Images[0].ImageInfo); return(Task.CompletedTask); }
public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext) { var texPath = filePath; var pltPath = $"{filePath.GetDirectory()}/../Palettes(NW4R)/{filePath.GetName()}"; var texStream = await fileSystem.OpenFileAsync(texPath); var pltStream = fileSystem.FileExists(pltPath) ? await fileSystem.OpenFileAsync(pltPath) : null; Images = new List <IKanvasImage> { new KanvasImage(EncodingDefinition, _img.Load(texStream, pltStream)) }; }
/// <summary> /// Unmounts the specified mount name and its attached filesystem. /// </summary> /// <param name="name">The mount name.</param> /// <exception cref="System.ArgumentException">The mount with the name `{mountName}` was not found</exception> public void Unmount(UPath name) { AssertMountName(name); var mountName = name.GetName(); lock (_mounts) { if (!_mounts.Remove(mountName)) { throw new ArgumentException("The mount with the name `{mountName}` was not found"); } } }
internal void UpdateLinkCache(UPath filePath, bool isLink) { this.CheckDeleted(); lock (this.DatabaseLock) { this.Manifest.Execute(connection => { connection.Execute( @"UPDATE directory_manifest SET is_link = @isLink WHERE filename = @file", new { isLink, file = filePath.GetName() }); }); } }
private IFile OpenFile(UPath file, bool updateLink) { this.CheckDeleted(); if (file.GetName() == ".manifest") { throw new UnauthorizedAccessException("Unable to open manifest file."); } (Guid guid, bool isLink) = this.RetrieveManifestRecord(file, updateLink); return(isLink switch { false => new File(this, new FileEntry(this.RootFileSystem, file), guid), true => new Link(this, new FileEntry(this.RootFileSystem, file), guid) });
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(); }
private void SaveFileAs() { var sfd = new SaveFileDialog { InitialDirectory = _openedFile.GetDirectory().FullName, FileName = _openedFile.GetName() }; if (sfd.ShowDialog() != DialogResult.OK) { MessageBox.Show("An error occurred when selecting a save path.", "Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } SaveFile(sfd.FileName); }
public Task <LoadResult> LoadFile(string file, Guid pluginId, LoadFileContext loadFileContext) { // 1. Get UPath var path = new UPath(file); // If file is already loaded if (IsLoaded(path)) { return(Task.FromResult(new LoadResult(GetLoadedFile(path)))); } // 2. Create file system action var fileSystemAction = new Func <IStreamManager, IFileSystem>(streamManager => FileSystemFactory.CreatePhysicalFileSystem(path.GetDirectory(), streamManager)); // 3. Load file // Physical files don't have a parent, if loaded like this return(LoadFile(fileSystemAction, path.GetName(), null, pluginId, loadFileContext)); }
public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext) { Stream texStream; Stream texListStream; if (filePath.GetName() == "textures") { texStream = await fileSystem.OpenFileAsync(filePath); texListStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "texture_table"); } else { texStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "textures"); texListStream = await fileSystem.OpenFileAsync(filePath); } Files = _arc.Load(texStream, texListStream); }
public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext) { Stream texStream; Stream texListStream; if (savePath.GetName() == "textures") { texStream = fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write); texListStream = fileSystem.OpenFile(savePath.GetDirectory() / "texture_table", FileMode.Create, FileAccess.Write); } else { texStream = fileSystem.OpenFile(savePath.GetDirectory() / "textures", FileMode.Create, FileAccess.Write); texListStream = fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write); } _arc.Save(texStream, texListStream, Files); return(Task.CompletedTask); }
private IFile OpenFile(UPath file, Guid inheritGuid) { this.CheckDeleted(); if (this.ContainsDirectory(file.GetName())) { throw new IOException("Tried to open a directory as a file."); } var fileEntry = new FileEntry(this.RootFileSystem, file); var rawInfo = new FileInfo(this.RootFileSystem.ConvertPathToInternal(fileEntry.Path)); if (this.FileGuidProvider.TryGetGuid(rawInfo, out Guid guid)) { return(new File(this, fileEntry, guid)); } guid = inheritGuid; if (rawInfo.Exists) { this.FileGuidProvider.SetGuid(rawInfo, guid); } return(new File(this, fileEntry, guid)); }
/// <summary> /// Mounts a filesystem for the specified mount name. /// </summary> /// <param name="name">The mount name.</param> /// <param name="fileSystem">The file system.</param> /// <exception cref="System.ArgumentNullException">fileSystem</exception> /// <exception cref="System.ArgumentException"> /// Cannot recursively mount the filesystem to self - fileSystem /// or /// There is already a mount with the same name: `{mountName}` - name /// </exception> public void Mount(UPath name, IFileSystem fileSystem) { if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } if (fileSystem == this) { throw new ArgumentException("Cannot recursively mount the filesystem to self", nameof(fileSystem)); } AssertMountName(name); var mountName = name.GetName(); lock (_mounts) { if (_mounts.ContainsKey(mountName)) { throw new ArgumentException("There is already a mount with the same name: `{mountName}`", nameof(name)); } _mounts.Add(mountName, fileSystem); } }
public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext) { Stream dataOutput; Stream indexOutput; switch (savePath.GetName()) { case "mcb1.bln": dataOutput = fileSystem.OpenFile(savePath, FileMode.Create); indexOutput = fileSystem.OpenFile(savePath.GetDirectory() / "mcb0.bln", FileMode.Create); break; default: indexOutput = fileSystem.OpenFile(savePath, FileMode.Create); dataOutput = fileSystem.OpenFile(savePath.GetDirectory() / "mcb1.bln", FileMode.Create); break; } _bln.Save(indexOutput, dataOutput, Files); return(Task.CompletedTask); }
private static bool SpecialDirectoryExists(UPath path) { // /drive or / can be read if (path == PathDrivePrefixOnWindows || path == UPath.Root) { return(true); } // If /xxx, invalid (parent folder is /) var parentDirectory = path.GetDirectory(); if (parentDirectory == UPath.Root) { return(false); } var dirName = path.GetName(); // Else check that we have a valid drive path (e.g /drive/c) return(parentDirectory == PathDrivePrefixOnWindows && dirName.Length == 1 && DriveInfo.GetDrives().Any(p => char.ToLowerInvariant(p.Name[0]) == char.ToLowerInvariant(dirName[0]))); }
private async Task <SaveResult> ReloadInternalAsync(IStateInfo stateInfo, IFileSystem destinationFileSystem, UPath savePath, IProgressContext progress) { // 1. Reload current state var temporaryStreamProvider = stateInfo.StreamManager.CreateTemporaryStreamProvider(); savePath = stateInfo.HasParent ? savePath : savePath.GetName(); var internalDialogManager = new InternalDialogManager(_dialogManager, stateInfo.DialogOptions); var loadContext = new LoadContext(temporaryStreamProvider, progress, internalDialogManager); var reloadResult = await TryLoadStateAsync(stateInfo.PluginState, destinationFileSystem, savePath, loadContext); if (!reloadResult.IsSuccessful) { return(new SaveResult(reloadResult.Exception)); } // 2. Set new file input, if state was loaded from a physical medium if (!stateInfo.HasParent) { stateInfo.SetNewFileInput(destinationFileSystem, savePath); } // 3. Reload all child states foreach (var archiveChild in stateInfo.ArchiveChildren) { var destination = CreateDestinationFileSystem(archiveChild, archiveChild.FilePath); var reloadChildResult = await ReloadInternalAsync(archiveChild, destination, archiveChild.FilePath, progress); if (!reloadChildResult.IsSuccessful) { return(reloadChildResult); } } return(SaveResult.SuccessfulResult); }
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; } } }
private void ExtractImage(string imageIndexArgument, UPath filePath) { if (!int.TryParse(imageIndexArgument, out var imageIndex)) { Console.WriteLine($"'{imageIndexArgument}' is not a valid number."); return; } if (imageIndex >= _imageState.Images.Count) { Console.WriteLine($"Index '{imageIndex}' was out of bounds."); return; } var destinationFileSystem = FileSystemFactory.CreateSubFileSystem(filePath.GetDirectory().FullName, new StreamManager()); ExtractImageInternal(_imageState.Images[imageIndex], destinationFileSystem, filePath.GetName()); }
private async Task <SaveResult> SaveAndReplaceStateAsync(IStateInfo stateInfo, IFileSystem destinationFileSystem, UPath savePath, SaveInfo saveInfo) { var saveState = stateInfo.PluginState as ISaveFiles; // 1. Save state to a temporary destination var temporaryContainer = _streamMonitor.CreateTemporaryFileSystem(); var saveStateResult = await TrySaveState(saveState, temporaryContainer, savePath.GetName(), saveInfo); if (!saveStateResult.IsSuccessful) { return(saveStateResult); } // TODO: If reload fails then the original files get closed already, which makes future save actions impossible due to disposed streams // 2. Dispose of all streams in this state _streamMonitor.GetStreamManager(temporaryContainer).ReleaseAll(); stateInfo.StreamManager.ReleaseAll(); // 3. Replace files in destination file system var moveResult = await MoveFiles(stateInfo, temporaryContainer, destinationFileSystem); if (!moveResult.IsSuccessful) { return(moveResult); } // 4. Release temporary destination _streamMonitor.ReleaseTemporaryFileSystem(temporaryContainer); return(SaveResult.SuccessfulResult); }
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()); } } }
private void ListFiles(IFileSystem fileSystem, UPath listPath, int iteration = 0) { var prefix = new string(' ', iteration * 2); Console.WriteLine(prefix + (iteration == 0 ? _stateInfo.FilePath.ToRelative() : listPath.GetName())); // Print files foreach (var file in fileSystem.EnumeratePaths(listPath, "*", SearchOption.TopDirectoryOnly, SearchTarget.File)) { Console.WriteLine(prefix + " " + file.GetName()); } // Print directories foreach (var dir in fileSystem.EnumeratePaths(listPath, "*", SearchOption.AllDirectories, SearchTarget.Directory)) { if (listPath != dir && listPath == dir.GetDirectory()) { ListFiles(fileSystem, dir, iteration + 1); } } }
public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext) { var fileStream = await fileSystem.OpenFileAsync(filePath); Files = _hfs.Load(fileStream, filePath.GetName()); }