summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2018-10-02 16:03:48 +0200
committerMarkus Mittendrein <git@maxmitti.tk>2018-10-02 16:03:48 +0200
commit37c25a56195ebbe422358fcf537d631ef6445450 (patch)
treebac35266f75cb5f60bfb7dbdd5159d28b2f7bf12
parent4dcfb134c3ae43f4f1325228a86137df00e27693 (diff)
downloadcc4group-37c25a56195ebbe422358fcf537d631ef6445450.tar.gz
cc4group-37c25a56195ebbe422358fcf537d631ef6445450.zip
Add a more flexible enum to choose the memory management mode for setEntryData instead of the freeData boolean
-rw-r--r--src/cc4group.c34
-rw-r--r--src/cc4group.h8
-rw-r--r--src/cppc4group.cpp50
-rw-r--r--src/cppc4group.hpp8
4 files changed, 77 insertions, 23 deletions
diff --git a/src/cc4group.c b/src/cc4group.c
index 8fd57d5..98e9af0 100644
--- a/src/cc4group.c
+++ b/src/cc4group.c
@@ -90,6 +90,13 @@ struct CC4Group_t {
} error;
};
+typedef enum {
+ Take,
+ Copy,
+ Reference
+} CC4Group_MemoryManagement;
+
+
static const C4GroupEntryData* cc4group_getEntryByPath(const CC4Group* const this, const char* const entryPath);
static const C4GroupEntryData* cc4group_getDirectoryByPath(CC4Group* const this, const char* const entryPath);
static const C4GroupEntryData* cc4group_getFileByPath(CC4Group* const this, const char* const entryPath);
@@ -1553,7 +1560,7 @@ static bool cc4group_createFile(CC4Group* const this, const char* const path)
return true;
}
-static bool cc4group_setEntryData(CC4Group* const this, const char* const entryPath, const void* const data, size_t const size, bool const freeData)
+static bool cc4group_setEntryData(CC4Group* const this, const char* const entryPath, const void* const data, size_t const size, int const memoryManagement)
{
assert(this);
assert(entryPath);
@@ -1569,11 +1576,24 @@ static bool cc4group_setEntryData(CC4Group* const this, const char* const entryP
free(entry->data);
}
- if(data != NULL)
+ if(data != NULL && size != 0)
{
- entry->data = (void*)data;
+ if(memoryManagement == Copy)
+ {
+ entry->data = malloc(size);
+ if(entry->data == NULL)
+ {
+ SET_ERRNO_ERROR("malloc: allocating memory for copying the file data");
+ return false;
+ }
+ memcpy(entry->data, data, size);
+ }
+ else
+ {
+ entry->data = (void*)data;
+ }
entry->core.Size = size;
- entry->freeData = freeData;
+ entry->freeData = memoryManagement != Reference;
}
else
{
@@ -1626,6 +1646,12 @@ CC4Group_API cc4group = {
.Auto = cc4group_createTmpMemoryAuto
},
+ .MemoryManagement = {
+ .Take = Take,
+ .Copy = Copy,
+ .Reference = Reference
+ },
+
.getErrorMessage = cc4group_getErrorMessage,
.getErrorCode = cc4group_getErrorCode,
.getErrorMethod = cc4group_getErrorMethod,
diff --git a/src/cc4group.h b/src/cc4group.h
index a6dcd37..82eddf6 100644
--- a/src/cc4group.h
+++ b/src/cc4group.h
@@ -63,6 +63,12 @@ typedef struct {
CC4Group_TmpMemoryStrategy Auto;
} const TmpMemoryStrategies;
+ struct {
+ int Take; // cc4group will free the data when its not needed anymore; e.g. in the destructor or when setting the file's data again
+ int Copy; // cc4group will copy the data to use it
+ int Reference; // cc4group will use the data as is (i.e. store the pointer and use it); the caller must guarantee it's validity throughout the groups lifetime (or until the file's data is set to a new pointer)
+ } const MemoryManagement;
+
void (*setTmpMemoryStrategy)(const CC4Group_TmpMemoryStrategy strategy);
// group metadata handling
@@ -83,7 +89,7 @@ typedef struct {
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);
+ bool (*setEntryData)(CC4Group* const this, const char* const entryPath, const void* const data, size_t const size, int const memoryManagementMode);
} const CC4Group_API;
#ifndef CC4GROUP_DYNAMIC_LOAD
diff --git a/src/cppc4group.cpp b/src/cppc4group.cpp
index 0619f75..4cc0d08 100644
--- a/src/cppc4group.cpp
+++ b/src/cppc4group.cpp
@@ -26,6 +26,36 @@ struct CppC4Group::Private {
}
};
+namespace {
+ CC4Group_TmpMemoryStrategy convertTmpMemoryStrategy(const CppC4Group::TmpMemoryStrategy strategy)
+ {
+ switch(strategy)
+ {
+ case CppC4Group::Auto:
+ return cc4group.TmpMemoryStrategies.Auto;
+ case CppC4Group::File:
+ return cc4group.TmpMemoryStrategies.File;
+ case CppC4Group::Memory:
+ return cc4group.TmpMemoryStrategies.Memory;
+ }
+ return cc4group.TmpMemoryStrategies.Auto;
+ }
+
+ int convertMemoryManagement(const CppC4Group::MemoryManagement management)
+ {
+ switch(management)
+ {
+ case CppC4Group::Take:
+ return cc4group.MemoryManagement.Take;
+ case CppC4Group::Copy:
+ return cc4group.MemoryManagement.Copy;
+ case CppC4Group::Reference:
+ return cc4group.MemoryManagement.Reference;
+ }
+ return cc4group.MemoryManagement.Copy;
+ }
+}
+
CppC4Group::CppC4Group() : p{new CppC4Group::Private{}}
{
@@ -97,21 +127,7 @@ std::string CppC4Group::getErrorCauser()
void CppC4Group::setTmpMemoryStrategy(const CppC4Group::TmpMemoryStrategy strategy)
{
- auto ccStrategy = cc4group.TmpMemoryStrategies.Auto;
- switch(strategy)
- {
- case Auto:
- ccStrategy = cc4group.TmpMemoryStrategies.Auto;
- break;
- case File:
- ccStrategy = cc4group.TmpMemoryStrategies.File;
- break;
- case Memory:
- ccStrategy = cc4group.TmpMemoryStrategies.Memory;
- break;
- }
-
- cc4group.setTmpMemoryStrategy(ccStrategy);
+ cc4group.setTmpMemoryStrategy(convertTmpMemoryStrategy(strategy));
}
bool CppC4Group::setMaker(const std::string& maker, const std::string& path, const bool recursive)
@@ -209,7 +225,7 @@ bool CppC4Group::createFile(const std::string& path)
return cc4group.createFile(p->g, path.c_str());
}
-bool CppC4Group::setEntryData(const std::__cxx11::string& path, const void*const data, const size_t size, const bool freeData)
+bool CppC4Group::setEntryData(const std::__cxx11::string& path, const void*const data, const size_t size, const MemoryManagement management)
{
- return cc4group.setEntryData(p->g, path.c_str(), data, size, freeData);
+ return cc4group.setEntryData(p->g, path.c_str(), data, size, convertMemoryManagement(management));
}
diff --git a/src/cppc4group.hpp b/src/cppc4group.hpp
index 1367bc7..67d350d 100644
--- a/src/cppc4group.hpp
+++ b/src/cppc4group.hpp
@@ -36,6 +36,12 @@ public:
Auto
};
+ enum MemoryManagement {
+ Take,
+ Copy,
+ Reference
+ };
+
static void setTmpMemoryStrategy(const TmpMemoryStrategy strategy);
public:
@@ -70,5 +76,5 @@ public:
bool createFile(const std::string& path);
- bool setEntryData(const std::string& path, const void* const data = nullptr, const size_t size = 0, const bool freeData = true);
+ bool setEntryData(const std::string& path, const void* const data = nullptr, const size_t size = 0, const MemoryManagement management = Copy);
};