Skip to content

Commit

Permalink
Merge pull request #18 from Strongleong/better_backups
Browse files Browse the repository at this point in the history
Better backups handling
  • Loading branch information
romibi authored Jan 15, 2022
2 parents ce414ce + 69e2b61 commit 7f5f220
Showing 1 changed file with 44 additions and 37 deletions.
81 changes: 44 additions & 37 deletions ScrapPackedLibrary/ScrapPackedFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ public class ScrapPackedFile
public string fileName { get; private set; }
PackedMetaData metaData;

// Todo: if we use MakeBackup multiple times before DeleteBackup or RestoreBackup
// this could be an issue: maybe use a map original-filname -> backup filename
private string backupFileEnding = "";
private Dictionary<string, string> backups = new Dictionary<string, string>();

public ScrapPackedFile(string p_fileName, bool p_canCreate = false)
{
Expand Down Expand Up @@ -109,7 +107,8 @@ private PackedFileIndexData ReadFileMetaData(FileStream p_fsPacked)

return new PackedFileIndexData(fileName, fileSize, fileOffset);
}


// todo: deprecate this
public List<string> GetFileNames()
{
// todo refactor list output
Expand All @@ -121,7 +120,6 @@ public List<string> GetFileNames()
return list;
}

// todo: deprecate this
public List<IDictionary<string, string>> GetFileList()
{
// todo refactor list output
Expand Down Expand Up @@ -188,7 +186,7 @@ private void AddFile(string p_externalPath, string p_packedPath)
if (metaData.fileByPath.ContainsKey(packedPath))
RemoveFile(packedPath);

var newFileIndexData = new PackedFileIndexData(p_externalPath, packedPath, (UInt32) newFile.Length);
var newFileIndexData = new PackedFileIndexData(p_externalPath, packedPath, (UInt32)newFile.Length);
metaData.fileList.Add(newFileIndexData);
metaData.fileByPath.Add(packedPath, newFileIndexData);
}
Expand All @@ -214,7 +212,7 @@ private void RenameFile(string p_oldFileName, string p_newFileName)

private void RenameDirectory(string p_oldPath, string p_newPath)
{
if (p_oldPath == "/")
if (p_oldPath == "/")
p_oldPath = "";

var fileList = GetFolderContent(p_oldPath);
Expand Down Expand Up @@ -253,12 +251,12 @@ private void RemoveDirectory(string p_Name)
throw new ArgumentException($"Unable to remove {p_Name}: folder does not exists in {fileName}");

foreach (var file in fileList)
RemoveFile(file.FilePath);
RemoveFile(file.FilePath);
}

public void Extract(string p_packedPath, string p_destinationPath)
{
if (p_packedPath.EndsWith("/") || p_packedPath.Length==0)
if (p_packedPath.EndsWith("/") || p_packedPath.Length == 0)
ExtractDirectory(p_packedPath, p_destinationPath);
else
ExtractFile(p_packedPath, p_destinationPath);
Expand Down Expand Up @@ -313,12 +311,12 @@ private void ExtractFile(string p_packedPath, string p_destinationPath, FileStre

fsPacked.Seek(fileMetaData.OriginalOffset, SeekOrigin.Begin);
fsPacked.Read(readBytes, 0, (int)fileMetaData.FileSize);

fsExtractFile.Write(readBytes);
}
catch (Exception ex)
{
if (backupFileEnding != "")
if (backups.ContainsKey(p_destinationPath))
RestoreBackup(p_destinationPath);
throw ex;
}
Expand All @@ -329,7 +327,7 @@ private void ExtractFile(string p_packedPath, string p_destinationPath, FileStre
}
catch (Exception ex)
{
if (backupFileEnding != "")
if (backups.ContainsKey(p_destinationPath))
RestoreBackup(p_destinationPath);
throw ex;
}
Expand All @@ -338,63 +336,72 @@ private void ExtractFile(string p_packedPath, string p_destinationPath, FileStre
if (p_PackedFileStream == null)
fsPacked.Close();
}
if (backupFileEnding != "")
DeleteBackup(p_destinationPath);
if (backups.ContainsKey(p_destinationPath))
DeleteBackup(p_destinationPath);
}

private void MakeBackup(string filePath, bool temp = false)
{
// todo: test of this
if (!File.Exists(filePath))
throw new FileNotFoundException($"Unable to backup '{filePath}': file does not exists");

Debug.Assert(backupFileEnding == "", $"Unable to backup '{filePath}': 'backupEnding' is not empty ('{backupFileEnding}').\r\n" +
$"Can track only one backup at a time for now.");


string backupPath = filePath;
if (temp)
{
string randomId;
do
{
backupFileEnding = $".{Guid.NewGuid().ToString().Substring(0,5)}.tmp";
randomId = $".{Guid.NewGuid().ToString().Substring(0, 5)}.tmp";
}
while (File.Exists(backupFileEnding + ".bak"));
while (File.Exists(backupPath + randomId + ".bak"));
backupPath += randomId;
}

backupFileEnding += ".bak";
backupPath += ".bak";

if (filePath == fileName)
fileName = filePath + backupFileEnding;
fileName = backupPath;

File.Move(filePath, filePath + backupFileEnding, true);
backups.Add(filePath, backupPath);
File.Move(filePath, backupPath, true);
}

private void RestoreBackup(string filePath)
{
string backupPath = filePath + backupFileEnding;
// todo: test of this
if (!backups.ContainsKey(filePath))
throw new FileNotFoundException($"File '{filePath}' does not have any backups to restore");

string backupPath = backups[filePath];

if (!File.Exists(backupPath))
throw new FileNotFoundException($"File '{filePath}' was previously backed up to `{backupPath}` but that backup does not exist anymore.\r\n" +
$"Is there a bug somwhere in `MakeBackup()` or was the file deleted externally?"); // unreachble?

if (filePath == fileName)
fileName = backupPath.Replace(".bak", "");

// todo: test of this
if (backupFileEnding == "" || !File.Exists(backupPath))
throw new FileNotFoundException($"File '{filePath}' does not have any backups to restore");

backupFileEnding = "";
backups.Remove(filePath);
File.Move(backupPath, filePath, true);
}

private void DeleteBackup(string filePath)
{
string backupPath = filePath + backupFileEnding;
// todo: test of this
if (!backups.ContainsKey(filePath))
throw new FileNotFoundException($"File '{filePath}' does not have any backups to delete");

string backupPath = backups[filePath];

if (!File.Exists(backupPath))
throw new FileNotFoundException($"File '{filePath}' have a record of backup `{backupPath}` but it is not exists as file.\r\n" +
$"There is a bug somwhere in `MakeBackup()`"); // unreachble

if (filePath == fileName)
fileName = backupPath.Replace(".bak", "");

// todo: test of this
if (backupFileEnding == "" || !File.Exists(backupPath))
throw new FileNotFoundException($"File '{filePath}' does not have any backups to delete");

backupFileEnding = "";
backups.Remove(filePath);
File.Delete(backupPath);
}

Expand Down Expand Up @@ -458,11 +465,11 @@ private FileStream TryMakeFile(string outputPath)
Debug.Assert(!outputPath.EndsWith(Path.DirectorySeparatorChar), "Output path cannot be only folder name.");

string dirName = Path.GetDirectoryName(outputPath);
if (dirName == null)
if (dirName == null)
throw new IOException($"Unable to create file {outputPath}: unexpected error.");

else if (dirName != "") // if dirName is not the same dir as the working dir.
Directory.CreateDirectory(dirName);
Directory.CreateDirectory(dirName);

return new FileStream(outputPath, FileMode.Create);
}
Expand Down

0 comments on commit 7f5f220

Please sign in to comment.