private async Task <SaveResult> SaveAndReplaceStateAsync(IFileState fileState, IFileSystem destinationFileSystem, UPath savePath, SaveInfo saveInfo) { // 1. Save state to a temporary destination var temporaryContainer = _streamMonitor.CreateTemporaryFileSystem(); var saveStateResult = await TrySaveState(fileState.PluginState as ISaveFiles, temporaryContainer, savePath, 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(); fileState.StreamManager.ReleaseAll(); // 3. Replace files in destination file system var moveResult = await MoveFiles(fileState, temporaryContainer, destinationFileSystem); if (!moveResult.IsSuccessful) { return(moveResult); } // 4. Release temporary destination _streamMonitor.ReleaseTemporaryFileSystem(temporaryContainer); return(SaveResult.SuccessfulResult); }
public FormInfo(IFileState fileState, IFormCommunicator formCommunicator, IProgressContext progress, ILogger logger) { FileState = fileState; FormCommunicator = formCommunicator; Progress = progress; Logger = logger; }
public VirtualLoadInfo(IFileState parentFileState, IArchiveState archiveState, ArchiveFileInfo afi, IFilePlugin plugin) : this(parentFileState, archiveState, afi) { ContractAssertions.IsNotNull(plugin, nameof(plugin)); Plugin = plugin; }
private async Task <SaveResult> ReloadInternalAsync(IFileState fileState, IFileSystem destinationFileSystem, UPath savePath, SaveInfo saveInfo) { // 1. Reload current state var temporaryStreamProvider = fileState.StreamManager.CreateTemporaryStreamProvider(); var internalDialogManager = new InternalDialogManager(saveInfo.DialogManager, fileState.DialogOptions); var loadContext = new LoadContext(temporaryStreamProvider, saveInfo.Progress, internalDialogManager); var reloadResult = await TryLoadStateAsync(fileState.PluginState, destinationFileSystem, savePath.ToAbsolute(), loadContext); if (!reloadResult.IsSuccessful) { return(new SaveResult(reloadResult.Exception)); } // 2. Set new file input, if state was loaded from a physical medium if (!fileState.HasParent) { fileState.SetNewFileInput(destinationFileSystem, savePath); } // 3. Reload all child states foreach (var archiveChild in fileState.ArchiveChildren) { var destination = archiveChild.FileSystem.Clone(archiveChild.StreamManager); var reloadChildResult = await ReloadInternalAsync(archiveChild, destination, archiveChild.FilePath, saveInfo); if (!reloadChildResult.IsSuccessful) { return(reloadChildResult); } } return(SaveResult.SuccessfulResult); }
public void Save(Stream output, IFileManager fileManager) { var images = (_state.PluginState as IImageState).Images; using var bw = new BinaryWriterX(output); // Create header var header = new TotxHeader { width = (short)images[0].ImageSize.Width, height = (short)images[0].ImageSize.Height }; // Prepare image info images[0].ImageInfo.ImageSize = images[0].ImageInfo.PadSize.Build(images[0].ImageSize); // Write CTPK var ctpkStream = _state.StateChanged ? fileManager.SaveStream(_state).Result.SavedStream[0].Stream : _state.FileSystem.OpenFile(_state.FilePath); ctpkStream.Position = 0; output.Position = 0x80; ctpkStream.CopyTo(output); // Write header output.Position = 0; bw.WriteType(header); // Finalize file manager fileManager.Close(_state); _state = null; }
/// <summary> /// Represents an open file in the runtime of Kuriimu. /// </summary> /// <param name="filePlugin">The entry class of the plugin for this file.</param> /// <param name="pluginState">The plugin state of this file.</param> /// <param name="parentFileState">The parent state for this file.</param> /// <param name="fileSystem">The file system around the initially opened file.</param> /// <param name="filePath">The path of the file to be opened in the file system.</param> /// <param name="streamManager">The stream manager used for this opened state.</param> /// <param name="fileManager">The plugin manager for this state.</param> public DefaultFileState(IFilePlugin filePlugin, IPluginState pluginState, IFileState parentFileState, IFileSystem fileSystem, UPath filePath, IStreamManager streamManager, IFileManager fileManager) { ContractAssertions.IsNotNull(filePlugin, nameof(filePlugin)); ContractAssertions.IsNotNull(pluginState, nameof(pluginState)); ContractAssertions.IsNotNull(fileSystem, nameof(fileSystem)); ContractAssertions.IsNotNull(streamManager, nameof(streamManager)); ContractAssertions.IsNotNull(fileManager, nameof(fileManager)); if (filePath == UPath.Empty || filePath.IsDirectory) { throw new InvalidOperationException($"'{filePath}' has to be a path to a file."); } if (!fileSystem.FileExists(filePath)) { throw FileSystemExceptionHelper.NewFileNotFoundException(filePath); } FilePlugin = filePlugin; PluginState = pluginState; FilePath = filePath; FileSystem = fileSystem; StreamManager = streamManager; FileManager = fileManager; ParentFileState = parentFileState; ArchiveChildren = new List <IFileState>(); }
public LoadResult(IFileState fileState) : this(LoadStatus.Successful) { ContractAssertions.IsNotNull(fileState, nameof(fileState)); LoadedFileState = fileState; }
private async Task <IImageState> LoadKtx(Stream fileStream, UPath filePath, IFileManager pluginManager) { var imgData = new SubStream(fileStream, _header.tableDataOffset, _header.imgDataSize); _dataCompressionFormat = Level5Compressor.PeekCompressionMethod(imgData); var ktxFile = new MemoryStream(); Level5Compressor.Decompress(imgData, ktxFile); ktxFile.Position = 0; var loadResult = await pluginManager.LoadFile(new StreamFile(ktxFile, filePath.GetNameWithoutExtension() + ".ktx"), KtxPluginId); if (!loadResult.IsSuccessful) { throw new InvalidOperationException(loadResult.Message); } if (!(loadResult.LoadedFileState.PluginState is IImageState)) { throw new InvalidOperationException("The embedded KTX version is not supported."); } _ktxState = loadResult.LoadedFileState; return((IImageState)_ktxState.PluginState); }
public ContextNode Add(IContext parentContext, IFileState stateInfo) { var newNode = new ContextNode(parentContext, this, stateInfo); Children.Add(newNode); return(newNode); }
public FormCommunicator(IFileState fileState, IMainForm mainForm) { ContractAssertions.IsNotNull(fileState, nameof(fileState)); ContractAssertions.IsNotNull(mainForm, nameof(mainForm)); _fileState = fileState; _mainForm = mainForm; }
/// <summary> /// Create a <see cref="AfiFileSystem"/> based on the given <see cref="IFileState"/>. /// </summary> /// <param name="fileState"><see cref="IFileState"/> to create the file system from.</param> /// <param name="path">The path of the virtual file system.</param> /// <returns>The created <see cref="IFileSystem"/> for this state.</returns> public static IFileSystem CreateAfiFileSystem(IFileState fileState, UPath path) { if (!(fileState.PluginState is IArchiveState)) { throw new InvalidOperationException("This state is not an archive."); } return(CreateAfiFileSystem(fileState, path, fileState.StreamManager)); }
public TextContext(IFileState stateInfo, IContext parentContext, IProgressContext progressContext) : base(progressContext) { ContractAssertions.IsNotNull(stateInfo, nameof(stateInfo)); ContractAssertions.IsNotNull(parentContext, nameof(parentContext)); _stateInfo = stateInfo; _parentContext = parentContext; }
private ContextNode(IContext parentContext, ContextNode parentNode, IFileState parentState) : this() { ContractAssertions.IsNotNull(parentContext, nameof(parentContext)); ContractAssertions.IsNotNull(parentNode, nameof(parentNode)); ContractAssertions.IsNotNull(parentState, nameof(parentState)); _parentNode = parentNode; _parentContext = parentContext; StateInfo = parentState; }
public CloseResult Close(IFileState fileState) { ContractAssertions.IsElementContained(_loadedFiles, fileState, "loadedFiles", nameof(fileState)); var closeResult = _parentFileManager.Close(fileState); _loadedFiles.Remove(fileState); return(closeResult); }
public ImageContext(IFileState stateInfo, IContext parentContext, IProgressContext progressContext) : base(progressContext) { ContractAssertions.IsNotNull(stateInfo, nameof(stateInfo)); ContractAssertions.IsNotNull(parentContext, nameof(parentContext)); _stateInfo = stateInfo; _imageState = _stateInfo.PluginState as IImageState; _parentContext = parentContext; }
/// <summary> /// Create a <see cref="AfiFileSystem"/> based on the given <see cref="IArchiveState"/>. /// </summary> /// <param name="fileState"><see cref="IFileState"/> to create the file system from.</param> /// <param name="path">The path of the virtual file system.</param> /// <param name="streamManager">The stream manager for this file system.</param> /// <returns>The created <see cref="IFileSystem"/> for this state.</returns> public static IFileSystem CreateAfiFileSystem(IFileState fileState, UPath path, IStreamManager streamManager) { var fileSystem = (IFileSystem) new AfiFileSystem(fileState, streamManager); if (path != UPath.Empty && path != UPath.Root) { fileSystem = new SubFileSystem(fileSystem, path); } return(fileSystem); }
public ArchiveContext(ContextNode contextNode, IContext parentContext, IInternalFileManager pluginManager, IProgressContext progressContext) : base(pluginManager, contextNode, progressContext) { ContractAssertions.IsNotNull(contextNode, nameof(contextNode)); ContractAssertions.IsNotNull(parentContext, nameof(parentContext)); _stateInfo = contextNode.StateInfo; _archiveState = _stateInfo.PluginState as IArchiveState; _archiveFileSystem = FileSystemFactory.CreateAfiFileSystem(_stateInfo); _parentContext = parentContext; }
public VirtualLoadInfo(IFileState parentFileState, IArchiveState archiveState, ArchiveFileInfo afi) { ContractAssertions.IsNotNull(parentFileState, nameof(parentFileState)); ContractAssertions.IsNotNull(archiveState, nameof(archiveState)); ContractAssertions.IsNotNull(afi, nameof(afi)); ContractAssertions.IsElementContained(archiveState.Files, afi, nameof(archiveState), nameof(afi)); ParentFileState = parentFileState; ArchiveState = archiveState; Afi = afi; }
/// <summary> /// Replace files in destination file system. /// </summary> /// <param name="fileState">The state to save in the destination.</param> /// <param name="sourceFileSystem">The file system to take the files from.</param> /// <param name="destinationFileSystem">The file system to replace the files in.</param> private async Task <SaveResult> MoveFiles(IFileState fileState, IFileSystem sourceFileSystem, IFileSystem destinationFileSystem) { if (fileState.HasParent) { // Put source filesystem into final destination var replaceResult = await TryReplaceFiles(sourceFileSystem, destinationFileSystem, fileState.ParentFileState.StreamManager); return(replaceResult); } // Put source filesystem into final destination var copyResult = await TryCopyFiles(sourceFileSystem, destinationFileSystem); return(copyResult); }
public IList <IKanvasImage> Load(Stream input, IFileManager fileManager) { using var br = new BinaryReaderX(input, true, ByteOrder.BigEndian); // Read FBRC tree _root = FabNode.Read(br); var dataNode = _root.Nodes.FirstOrDefault(x => x.Type == "PDAT"); // Read CTPK var result = fileManager.LoadFile(new StreamFile(dataNode.Data, "file.ctpk"), CtpkId).Result; if (!result.IsSuccessful) { throw new InvalidOperationException(result.Message); } _ctpkState = result.LoadedFileState; return((_ctpkState.PluginState as IImageState).Images); }
protected async Task SaveFile(IFileState fileState) { SaveResult saveResult; try { saveResult = await FileManager.SaveFile(fileState); } catch (Exception e) { Logger.Fatal(e, "Saving file '{0}' threw an error.", fileState.FilePath.FullName); return; } if (!saveResult.IsSuccessful) { Logger.Error("Could not save '{0}'.", fileState.FilePath.FullName); } }
private async Task <SaveResult> SaveInternalAsync(IFileState fileState, IFileSystem destinationFileSystem, UPath savePath, SaveInfo saveInfo, bool isStart = true) { // 1. Check if state is saveable and if the contents are changed if (!(fileState.PluginState.CanSave) || !fileState.StateChanged) { return(new SaveResult(true, "The file had no changes and was not saved.")); } // 2. Save child states foreach (var archiveChild in fileState.ArchiveChildren) { var childDestination = archiveChild.FileSystem.Clone(archiveChild.StreamManager); var saveChildResult = await SaveInternalAsync(archiveChild, childDestination, archiveChild.FilePath, saveInfo, false); if (!saveChildResult.IsSuccessful) { return(saveChildResult); } } // 3. Save and replace state var saveAndReplaceResult = await SaveAndReplaceStateAsync(fileState, destinationFileSystem, savePath, saveInfo); if (!saveAndReplaceResult.IsSuccessful) { return(saveAndReplaceResult); } // If this was not the first call into the save action, return a successful result if (!isStart) { return(SaveResult.SuccessfulResult); } // 4. Reload the current state and all its children var reloadResult = await ReloadInternalAsync(fileState, destinationFileSystem, savePath, saveInfo); return(reloadResult); }
public void Save(Stream output, IFileManager fileManager) { var imageState = _ctpkState.PluginState as IImageState; var buffer = new byte[4]; // Save CTPK var ctpkStream = _ctpkState.StateChanged ? fileManager.SaveStream(_ctpkState).Result.SavedStream[0].Stream : _ctpkState.FileSystem.OpenFile(_ctpkState.FilePath); // Set saved CTPK var dataNode = _root.Nodes.FirstOrDefault(x => x.Type == "PDAT"); dataNode.Data = ctpkStream; // Save node tree using var bw = new BinaryWriterX(output, ByteOrder.BigEndian); _root.Write(bw); // Clean CTPK state fileManager.Close(_ctpkState); _ctpkState = null; }
private async Task SaveFileInternal(IFileState selectedState, string savePathArgument) { if (!(selectedState.PluginState is ISaveFiles)) { Console.WriteLine($"File '{selectedState.FilePath}' is not savable."); return; } if (!selectedState.StateChanged) { Console.WriteLine($"File '{selectedState.FilePath.ToRelative()}' has no changes."); return; } SaveResult saveResult; try { saveResult = await(string.IsNullOrEmpty(savePathArgument) ? PluginManager.SaveFile(selectedState) : PluginManager.SaveFile(selectedState, savePathArgument)); } catch (Exception e) { Console.WriteLine($"Save Error: {e.Message}"); return; } if (!saveResult.IsSuccessful) { Console.WriteLine($"Save Error: {saveResult.Message}"); return; } Console.WriteLine($"Saved '{selectedState.FilePath.ToRelative()}' successfully."); }
public IList <IKanvasImage> Load(Stream input, IFileManager fileManager) { using var br = new BinaryReaderX(input); // Read header var header = br.ReadType <TotxHeader>(); // Read CTPK var ctpkState = fileManager.LoadFile(new StreamFile(new SubStream(input, 0x80, input.Length - 0x80), "file.ctpk"), CtpkId).Result; if (!ctpkState.IsSuccessful) { throw new InvalidOperationException(ctpkState.Message); } _state = ctpkState.LoadedFileState; var images = (_state.PluginState as IImageState).Images; // Edit image info images[0].ImageInfo.ImageSize = new Size(header.width, header.height); images[0].ImageInfo.PadSize.ToMultiple(8); return(images); }
public void RegisterStateInfo(IFileState fileState) { ContractAssertions.IsNotNull(fileState, nameof(fileState)); _fileState = fileState; }
public FileStateChangedEventArgs(IFileState state) { FileState = state; }
/// <inheritdoc /> public Task <SaveResult> SaveAsync(IFileState fileState, IFileSystem fileSystem, UPath savePath, SaveInfo saveInfo) { return(SaveInternalAsync(fileState, fileSystem, savePath, saveInfo)); }
/// <inheritdoc /> public bool IsClosing(IFileState fileState) { return(_parentFileManager.IsClosing(fileState)); }
public Task <SaveStreamResult> SaveStream(IFileState fileState) { return(_parentFileManager.SaveStream(fileState)); }