diff options
| -rw-r--r-- | src/cc4group.c | 45 | ||||
| -rw-r--r-- | src/cc4group.h | 7 | ||||
| -rw-r--r-- | src/cppc4group.cpp | 10 | ||||
| -rw-r--r-- | src/cppc4group.hpp | 6 |
4 files changed, 41 insertions, 27 deletions
diff --git a/src/cc4group.c b/src/cc4group.c index 199dcdc..5109b0a 100644 --- a/src/cc4group.c +++ b/src/cc4group.c @@ -46,6 +46,7 @@ static bool cc4group_getEntryData(const CC4Group* const this, const char* const struct list_GroupEntryList; typedef struct C4GroupEntryData_t { C4GroupEntryCore core; + bool freeData; union { uint8_t* data; // if the entry is a directory, the beginning of the data contains the header @@ -164,7 +165,7 @@ static bool buildChildren(CC4Group* const this, C4GroupEntryData* const entry, s return false; } - C4GroupEntryData* childEntry = &GroupEntryListAppend(entry->children, (C4GroupEntryData){.core = *core, .data = childData + core->Offset, .children = NULL, .parent = entry})->value; + C4GroupEntryData* childEntry = &GroupEntryListAppend(entry->children, (C4GroupEntryData){.core = *core, .data = childData + core->Offset, .freeData = false, .children = NULL, .parent = entry})->value; if(core->Directory) { @@ -183,6 +184,11 @@ static void deleteChildren(GroupEntryList* const entries) { ForeachGroupEntry(entries) { + if(entry->value.freeData && entry->value.data != NULL) + { + free(entry->value.data); + } + if(entry->value.core.Directory) { deleteChildren(entry->value.children); @@ -561,6 +567,8 @@ static void cc4group_init(CC4Group* const this) this->path = ""; this->subPath = ""; + this->root.data = NULL; + this->root.freeData = false; this->root.parent = NULL; this->root.children = NULL; this->root.core.Directory = true; @@ -1463,6 +1471,7 @@ static C4GroupEntryData* cc4group_createEntry(CC4Group* const this, const char* C4GroupEntryData entry; entry.data = NULL; + entry.freeData = false; entry.children = GroupEntryListNew(); C4GroupEntryCore_init(&entry.core); @@ -1503,7 +1512,7 @@ static bool cc4group_createDirectory(CC4Group* const this, const char* const pat return true; } -static bool cc4group_createFile(CC4Group* const this, const char* const path, void* const data, size_t const size) +static bool cc4group_createFile(CC4Group* const this, const char* const path) { assert(this); assert(path); @@ -1515,39 +1524,43 @@ static bool cc4group_createFile(CC4Group* const this, const char* const path, vo return false; } - if(size != 0 && data != NULL) - { - entry->core.Size = size; - entry->data = data; - - AddCleanupJob(free, data); - } - return true; } -static bool cc4group_setEntryData(const CC4Group* const this, const char* const entryPath, void* const data, size_t const size) +static bool cc4group_setEntryData(CC4Group* const this, const char* const entryPath, const void* const data, size_t const size, bool const freeData) { assert(this); assert(entryPath); C4GroupEntryData* entry = (C4GroupEntryData*)cc4group_getEntryByPath(this, entryPath); - if(entry == NULL || entry->core.Directory) + if(entry == NULL) { + SET_MESSAGE_ERROR("The desired target file does not exist"); return false; } - if(data != NULL && size != 0) + if(entry->core.Directory) { - entry->data = data; - entry->core.Size = size; + SET_MESSAGE_ERROR("The desired target file is a directory"); + return false; + } - AddCleanupJob(free, data); + if(entry->freeData && entry->data != NULL) + { + free(entry->data); + } + + if(data != NULL) + { + entry->data = (void*)data; + entry->core.Size = size; + entry->freeData = freeData; } else { entry->data = NULL; entry->core.Size = 0; + entry->freeData = false; } return true; diff --git a/src/cc4group.h b/src/cc4group.h index ef3a55d..aab776c 100644 --- a/src/cc4group.h +++ b/src/cc4group.h @@ -80,9 +80,10 @@ typedef struct { bool (*createDirectory)(CC4Group* const this, const char* const path); // ownership of the data is taken by the group - bool (*createFile)(CC4Group* const this, const char* const path, void* const data, size_t const size); - // ownership of the data is taken by the group - bool (*setEntryData)(const CC4Group* const this, const char* const entryPath, void* const data, size_t const size); + bool (*createFile)(CC4Group* const this, const char* const path); + // ownership of the data is taken by the group if freeData is true + // if freeData is false, the caller must guarantee that the pointer is valid as long as it is used in the group (i.e. until the pointer is changed through another call to setEntryData or the group is destructed) + bool (*setEntryData)(CC4Group* const this, const char* const entryPath, const void* const data, size_t const size, bool const freeData); } const CC4Group_API; #ifndef CC4GROUP_DYNAMIC_LOAD diff --git a/src/cppc4group.cpp b/src/cppc4group.cpp index 4585621..fa64771 100644 --- a/src/cppc4group.cpp +++ b/src/cppc4group.cpp @@ -7,7 +7,7 @@ CppC4Group::Data::Data() : data{nullptr}, size{0} } -CppC4Group::Data::Data(const void* data, size_t size) : data{data}, size{size} +CppC4Group::Data::Data(const void* const data, const size_t size) : data{data}, size{size} { } @@ -204,12 +204,12 @@ bool CppC4Group::createDirectory(const std::string& path) return cc4group.createDirectory(p->g, path.c_str()); } -bool CppC4Group::createFile(const std::string& path, void* data, size_t size) +bool CppC4Group::createFile(const std::string& path) { - return cc4group.createFile(p->g, path.c_str(), data, size); + return cc4group.createFile(p->g, path.c_str()); } -bool CppC4Group::setEntryData(const std::string& path, void* data, size_t size) +bool CppC4Group::setEntryData(const std::__cxx11::string& path, const void*const data, const size_t size, const bool freeData) { - return cc4group.setEntryData(p->g, path.c_str(), data, size); + return cc4group.setEntryData(p->g, path.c_str(), data, size, freeData); } diff --git a/src/cppc4group.hpp b/src/cppc4group.hpp index 2e75462..1367bc7 100644 --- a/src/cppc4group.hpp +++ b/src/cppc4group.hpp @@ -15,7 +15,7 @@ public: size_t size; Data(); - Data(const void* data, size_t size); + Data(const void* const data, const size_t size); }; struct EntryInfo { @@ -68,7 +68,7 @@ public: bool createDirectory(const std::string& path); - bool createFile(const std::string& path, void* data = nullptr, size_t size = 0); + bool createFile(const std::string& path); - bool setEntryData(const std::string& path, void* data = nullptr, size_t size = 0); + bool setEntryData(const std::string& path, const void* const data = nullptr, const size_t size = 0, const bool freeData = true); }; |
