diff options
Diffstat (limited to 'src/cc4group.c')
| -rw-r--r-- | src/cc4group.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/src/cc4group.c b/src/cc4group.c index b00cc45..f257d6b 100644 --- a/src/cc4group.c +++ b/src/cc4group.c @@ -98,6 +98,9 @@ struct CC4Group_t { char* lastFormattedMessage; } error; + + size_t referenceCounter; + CC4Group* parent; }; static bool cc4group_applyMemoryManagementStart(CC4Group_MemoryManagement const management, const uint8_t** data, size_t size) @@ -951,6 +954,9 @@ static void cc4group_init(CC4Group* const this) { assert(this); + this->referenceCounter = 1; + this->parent = NULL; + this->uncompressedData = NULL; this->uncompressedSize = 0; @@ -1144,6 +1150,16 @@ static bool cc4group_openExisting(CC4Group* const this, const char* const path) return cc4group_uncompressGroupFromFile(this, path); } +static void cc4group_unreference(CC4Group* const this) +{ + assert(this); + + if(--this->referenceCounter == 0) + { + cc4group_delete(this); + } +} + static void cc4group_delete(CC4Group* const this) { assert(this); @@ -1578,6 +1594,12 @@ static bool cc4group_saveIt(CC4Group* const this, const char* const path, bool c assert(this); assert(path); + if(this->parent != NULL) + { + SET_MESSAGE_ERROR("Saving is currently not implemented for groups opened with openAsChild"); + return false; + } + bool success = false; int file = open(path, O_WRONLY | O_BINARY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), 0644); @@ -2047,6 +2069,38 @@ static bool cc4group_setExecutable(CC4Group* const this, bool const executable, return true; } +static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const path) +{ + assert(this); + + const C4GroupEntryData* entry = cc4group_getDirectoryByPath(this, path, false); + + if(entry == NULL) + { + return NULL; + } + + CC4Group* child = cc4group_new(); + if(child == NULL) + { + SET_ERRNO_ERROR("malloc: allocating the child group object"); + return NULL; + } + + memcpy(&child->root.core, &entry->core, sizeof(child->root.core)); + child->root.data = entry->data; + child->root.core.Directory = 1; + child->root.core.FileName[0] = '\0'; + child->root.children = entry->children; + child->parent = this; + + ++this->referenceCounter; + + CleanUpJobListAppend(child->cleanupJobs, (CC4Group_CleanupJob){.func = (CC4Group_CleanupFunc)cc4group_unreference, .data = this}); + + return child; +} + CC4Group_API cc4group = { .MemoryManagement = { .Take = Take, @@ -2065,7 +2119,7 @@ CC4Group_API cc4group = { .new = cc4group_new, - .delete = cc4group_delete, + .delete = cc4group_unreference, .create = cc4group_create, @@ -2107,5 +2161,8 @@ CC4Group_API cc4group = { .getErrorMessage = cc4group_getErrorMessage, .getErrorCode = cc4group_getErrorCode, .getErrorMethod = cc4group_getErrorMethod, - .getErrorCauser = cc4group_getErrorCauser + .getErrorCauser = cc4group_getErrorCauser, + + + .openAsChild = cc4group_openAsChild }; |
