/// <summary> /// /// </summary> /// <param name="kfi"></param> /// <param name="leaveFileStreamOpen"></param> /// <param name="firstIteration"></param> /// <returns></returns> private bool CloseFile(KoreFileInfo kfi, bool leaveFileStreamOpen, bool firstIteration) { if (kfi.ChildKfi != null && kfi.ChildKfi.Count > 0) { foreach (var child in kfi.ChildKfi) { CloseFile(child, false, false); } } if (OpenFiles.Contains(kfi)) { OpenFiles.Remove(kfi); } kfi.Adapter.Dispose(); if (!leaveFileStreamOpen) { kfi.StreamFileInfo.FileData.Close(); } if (kfi.Adapter is IMultipleFiles multFileAdapter) { multFileAdapter.FileSystem.Dispose(); } if (firstIteration) { if (kfi.ParentKfi != null) { kfi.ParentKfi.ChildKfi.Remove(kfi); } } return(true); }
private FullPathNode CreateFullPathTree(KoreFileInfo kfi) { var newNode = new FullPathNode(kfi.FullPath); if (kfi.ChildKfi != null) { foreach (var child in kfi.ChildKfi) { newNode.Nodes.Add(CreateFullPathTree(child)); } } return(newNode); }
private KoreFileInfo ReopenFiles(KoreFileInfo kfi, FullPathNode fullPathTree, string tempFolder, bool isChild) { var guid = Guid.NewGuid().ToString(); // Open this file KoreFileInfo newKfi = null; if (isChild) { var parentFiles = (kfi.Adapter as IArchiveAdapter).Files; var foundAfi = parentFiles.FirstOrDefault(x => x.FileName == fullPathTree.FullPath.Remove(0, kfi.FullPath.Length + 1)); if (foundAfi == null) { throw new InvalidOperationException($"While reopening files, the ArchiveFileInfo with FullPath \"{fullPathTree.FullPath}\" couldn't be found."); } newKfi = LoadFile(new KoreLoadInfo(foundAfi.FileData, foundAfi.FileName) { LeaveOpen = true, Adapter = kfi.Adapter, FileSystem = new VirtualFileSystem(kfi.Adapter as IArchiveAdapter, tempFolder) }); newKfi.ParentKfi = kfi; newKfi.ChildKfi = new List <KoreFileInfo>(); } else { var openedFile = File.Open(fullPathTree.FullPath, FileMode.Open); newKfi = LoadFile(new KoreLoadInfo(openedFile, fullPathTree.FullPath) { LeaveOpen = true, Adapter = kfi.Adapter, FileSystem = new PhysicalFileSystem(Path.GetDirectoryName(fullPathTree.FullPath)) }); newKfi.ChildKfi = new List <KoreFileInfo>(); } // Open Childs foreach (var child in fullPathTree.Nodes) { newKfi.ChildKfi.Add(ReopenFiles(newKfi, child, tempFolder, true)); } return(newKfi); }
//public void SaveFile(KoreSaveInfo ksi) //{ // // Save data with the adapter // var guid = Guid.NewGuid().ToString(); // var fs = new PhysicalFileSystem(Path.Combine(tempFolder, guid)); // if (kfi.Adapter is IMultipleFiles multFileAdapter) // multFileAdapter.FileSystem = fs; // kfi.Adapter.LeaveOpen = false; // var streaminfo = new StreamInfo { FileData = fs.CreateFile(Path.GetFileName(kfi.StreamFileInfo.FileName)), FileName = Path.GetFileName(kfi.StreamFileInfo.FileName) }; // (kfi.Adapter as ISaveFiles).Save(streaminfo, ksi.Version); // // Replace files in adapter // if (kfi.ParentKfi != null) // { // var parentArchiveAdapter = kfi.ParentKfi.Adapter as IArchiveAdapter; // RecursiveUpdate(parentArchiveAdapter, fs, Path.Combine(Path.GetFullPath(tempFolder), guid)); // } // else // { // // TODO: Implement save if no parent is given // // Get intial directory // var initialDir = Path.GetDirectoryName(ksi.Kfi.FullPath); // // Close current initial file // ksi.Kfi.StreamFileInfo.FileData.Close(); // // Close current FileSystem, if set // if (ksi.Kfi is IMultipleFiles multFileAdapter2 && multFileAdapter2.FileSystem != null) // multFileAdapter2.FileSystem.Dispose(); // // All open filestreams of the initial file should be closed by now // if (string.IsNullOrEmpty(ksi.NewSaveLocation)) // { // // Move saved files to intial location // SaveFileSystem(fs, initialDir); // } // else // { // } // // Reopen // } // // Update archive file states in this level // if (kfi.Adapter is IArchiveAdapter archiveAdapter) // foreach (var afi in archiveAdapter.Files) // afi.State = ArchiveFileState.Archived; // // Update archive file states up the parent tree // if (kfi.ParentKfi != null) // kfi.UpdateState(ArchiveFileState.Replaced); //} /// <summary> /// Closes an open file. /// </summary> /// <param name="kfi">The file to be closed.</param> /// <returns>True if file was closed, False otherwise.</returns> public bool CloseFile(KoreFileInfo kfi, bool leaveFileStreamOpen = false) { return(CloseFile(kfi, leaveFileStreamOpen, true)); }
// TODO: We want to somehow reflect these names and also possibly return a class holding the Type and a DisplayName vs. the plain interface name. /// <summary> /// Load a file using Kore. /// </summary> /// <param name="kli"></param> /// <returns></returns> public KoreFileInfo LoadFile(KoreLoadInfo kli) { if (kli.Adapter == null) { // Select adapter automatically var adapter = SelectAdapter(kli); // Ask the user to select a plugin directly. adapter = adapter ?? SelectAdapterManually(); if (adapter == null) { return(null); } kli.Adapter = adapter; } // Instantiate a new instance of the adapter kli.Adapter = PluginLoader.CreateAdapter <ILoadFiles>(PluginLoader.GetMetadata <PluginInfoAttribute>(kli.Adapter).ID); // Load files(s) kli.FileData.Position = 0; var streamInfo = new StreamInfo { FileData = kli.FileData, FileName = kli.FileName }; try { if (kli.Adapter is IMultipleFiles multiFileAdapter) { multiFileAdapter.FileSystem = kli.FileSystem; } kli.Adapter.LeaveOpen = kli.LeaveOpen; kli.Adapter.Load(streamInfo); } catch (Exception ex) { var pi = PluginLoader.GetMetadata <PluginInfoAttribute>(kli.Adapter); throw new LoadFileException($"The {pi?.Name} plugin failed to load \"{Path.GetFileName(kli.FileName)}\".{Environment.NewLine}{Environment.NewLine}" + $"{ex.Message}{Environment.NewLine}{Environment.NewLine}" + $"{ex.StackTrace}"); } // Check if the stream still follows the LeaveOpen restriction if (!kli.FileData.CanRead && kli.LeaveOpen) { throw new InvalidOperationException($"Plugin with ID {PluginLoader.GetMetadata<PluginInfoAttribute>(kli.Adapter).ID} closed the streams while loading the file."); } // Create a KoreFileInfo to keep track of the now open file. var kfi = new KoreFileInfo { StreamFileInfo = streamInfo, HasChanges = false, Adapter = kli.Adapter }; if (kli.TrackFile) { OpenFiles.Add(kfi); } return(kfi); }
public KoreSaveInfo(KoreFileInfo kfi, string tempFolder) { Kfi = kfi; TempFolder = tempFolder; }