From 4ded6e352ee0fb5d96d2e1b9f051aac1f07b4886 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Mon, 20 Apr 2020 21:51:58 +0200 Subject: Rework group saving save / saveParent write back to the original group saveParent saves changes in child groups (openAsChild) by saving the top-most parent saveAs / saveAsOverwrite resembles the old save / saveOverwrite For all other saving methods, groups opend with openAsChild are saved as if there was no parent --- src/cc4group.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 12 deletions(-) (limited to 'src/cc4group.c') diff --git a/src/cc4group.c b/src/cc4group.c index 0483eea..5cbce53 100644 --- a/src/cc4group.c +++ b/src/cc4group.c @@ -124,6 +124,8 @@ struct CC4Group_t { } readState; bool lazy; + const char* path; + bool subRooted; }; typedef struct { @@ -1062,6 +1064,7 @@ static bool cc4group_setSubRoot(CC4Group* const this, const char* const subPath) this->realRoot = this->root; this->root = *subRoot; + this->subRooted = true; } return true; @@ -1179,6 +1182,14 @@ ret: if(success) { success = cc4group_setSubRoot(this, subPath); + if(success && subPath != NULL && *subPath != '\0') + { + if(this->path != NULL) + { + free((void*)this->path); + } + this->path = cc4group_absolutePath(tmpPath); + } } free(tmpPath); @@ -1193,6 +1204,8 @@ static void cc4group_init(CC4Group* const this) this->referenceCounter = 1; this->parent = NULL; this->lazy = true; + this->path = NULL; + this->subRooted = false; this->uncompressedData = NULL; this->uncompressedSize = 0; @@ -1700,7 +1713,10 @@ static bool cc4group_openExisting(CC4Group* const this, const char* const path) SET_BINARY(STDIN_FILENO); return cc4group_openFd(this, STDIN_FILENO); } - else if(cc4group_isDirectory(path)) + + this->path = cc4group_absolutePath(path); + + if(cc4group_isDirectory(path)) { return cc4group_openDirectory(this, path); } @@ -1739,6 +1755,11 @@ static void cc4group_delete(CC4Group* const this) free(this->error.lastFormattedMessage); } + if(this->path != NULL) + { + free((void*)this->path); + } + free(this); } @@ -2501,12 +2522,6 @@ static bool cc4group_saveWithWriteCallback(CC4Group* const this, CC4Group_WriteC maxBlockSize = 1024 * 1024; } - if(this->parent != NULL) - { - SET_MESSAGE_ERROR("Saving is currently not implemented for groups opened with openAsChild"); - return false; - } - WriteCallback callback = { .callback = writeCallback, .arg = arg, @@ -2617,7 +2632,7 @@ static bool cc4group_saveToFd(CC4Group* const this, int fd) return cc4group_saveWithWriteCallback(this, cc4group_writeToFdCallback, &fd, 0); } -static bool cc4group_save(CC4Group* const this, const char* const path) +static bool cc4group_saveAs(CC4Group* const this, const char* const path) { assert(this); assert(path); @@ -2658,11 +2673,11 @@ static bool cc4group_save(CC4Group* const this, const char* const path) return success; } -static bool cc4group_saveOverwrite(CC4Group* const this, const char* const path) +static bool cc4group_saveAsOverwrite(CC4Group* const this, const char* const path) { if(strcmp(path, "-") == 0) { - return cc4group_save(this, path); + return cc4group_saveAs(this, path); } char tmpFileName[tmpFileNameLength]; @@ -2704,6 +2719,52 @@ ret: return success; } +static bool cc4group_save(CC4Group* const this) +{ + assert(this); + if(this->path == NULL) + { + SET_MESSAGE_ERROR("This group was not opened from an existing on disk group. cc4group.save can not be used."); + return false; + } + + if(this->parent != NULL) + { + SET_MESSAGE_ERROR("Refusing to save a group opened with openAsChild. cc4group.saveParent might be used."); + return false; + } + + if(this->subRooted) + { + SET_MESSAGE_ERROR("Refusing to save a group opened with a path inside the actual group. cc4group.saveParent might be used."); + return false; + } + + return cc4group_saveAsOverwrite(this, this->path); +} + +static bool cc4group_saveParent(CC4Group* const this) +{ + CC4Group* root = this; + while(root->parent) + { + root = root->parent; + } + + if(root->subRooted) + { + C4GroupEntryData tmp = root->root; + root->root = root->realRoot; + root->subRooted = false; + bool success = cc4group_save(root); + root->root = tmp; + root->subRooted = true; + return success; + } + + return cc4group_save(root); +} + static bool cc4group_getEntryInfoForEntry(CC4Group* const this, const C4GroupEntryData* const entry, CC4Group_EntryInfo* const info, bool const lazy) { C4GroupHeader* header = NULL; @@ -3334,9 +3395,10 @@ CC4Group_API cc4group = { .openFilePointer = cc4group_openFilePointer, .openWithReadCallback = cc4group_uncompressGroup, - .save = cc4group_save, - .saveOverwrite = cc4group_saveOverwrite, + .saveParent = cc4group_saveParent, + .saveAs = cc4group_saveAs, + .saveAsOverwrite = cc4group_saveAsOverwrite, .saveToFd = cc4group_saveToFd, .saveToFilePointer = cc4group_saveToFilePointer, .saveWithWriteCallback = cc4group_saveWithWriteCallback, -- cgit v1.2.3-54-g00ecf