summaryrefslogtreecommitdiffstats
path: root/src/cc4group.c
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2020-04-20 21:51:58 +0200
committerMarkus Mittendrein <git@maxmitti.tk>2020-04-20 21:52:07 +0200
commit4ded6e352ee0fb5d96d2e1b9f051aac1f07b4886 (patch)
tree8d29721809a690acbbaa2efb56402f55eb6436c1 /src/cc4group.c
parentd42414b65cdb0156a5a2064a08c894c19370d7a7 (diff)
downloadcc4group-4ded6e352ee0fb5d96d2e1b9f051aac1f07b4886.tar.gz
cc4group-4ded6e352ee0fb5d96d2e1b9f051aac1f07b4886.zip
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
Diffstat (limited to 'src/cc4group.c')
-rw-r--r--src/cc4group.c86
1 files changed, 74 insertions, 12 deletions
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,