summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2018-08-18 23:11:02 +0200
committerMarkus Mittendrein <git@maxmitti.tk>2018-08-18 23:33:27 +0200
commit4338534c9cdacf98c310ab625a1d17988dde1949 (patch)
tree213b60d796a33efeb2649fbadb6dff62ab7d8ff2
parent88552afbb4b41b6f859e7051cc0e4b0efbecea78 (diff)
downloadcc4group-4338534c9cdacf98c310ab625a1d17988dde1949.tar.gz
cc4group-4338534c9cdacf98c310ab625a1d17988dde1949.zip
Add possibility to leave data ownership to the caller of setEntryData and remove possibility to specify entry data with createFile
-rw-r--r--src/cc4group.c45
-rw-r--r--src/cc4group.h7
-rw-r--r--src/cppc4group.cpp10
-rw-r--r--src/cppc4group.hpp6
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);
};