summaryrefslogtreecommitdiffstats
path: root/src/cppc4group.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cppc4group.cpp')
-rw-r--r--src/cppc4group.cpp81
1 files changed, 66 insertions, 15 deletions
diff --git a/src/cppc4group.cpp b/src/cppc4group.cpp
index 2d85537..329d6de 100644
--- a/src/cppc4group.cpp
+++ b/src/cppc4group.cpp
@@ -39,6 +39,66 @@ struct CppC4Group::Private {
}
};
+struct CppC4Group::MemoryManagement::Private {
+ bool predefined;
+ MemoryManagementStrategy strategy;
+
+ Start start;
+ End end;
+};
+
+CppC4Group::MemoryManagement::MemoryManagement(MemoryManagementStrategy strategy) : p{new Private{true, strategy}}
+{
+
+}
+
+CppC4Group::MemoryManagement::MemoryManagement(Start&& start, End&& end) : p{new Private{false, {}, start, end}}
+{
+
+}
+
+CppC4Group::MemoryManagement::~MemoryManagement()
+{
+ delete p;
+}
+
+CppC4Group::MemoryManagement::MemoryManagementStrategy CppC4Group::MemoryManagement::operator()() const
+{
+ if(p->predefined)
+ {
+ return p->strategy;
+ }
+ else
+ {
+ struct CustomMemoryManagement {
+ CC4Group_MemoryManagement_t realMemoryManagement;
+
+ Start start;
+ End end;
+
+ static void* callStart(void* const data, size_t const size, void* const arg)
+ {
+ return reinterpret_cast<CustomMemoryManagement*>(arg)->start(data, size);
+ }
+
+ static void callEndAndCleanup(void* const data, void* const arg)
+ {
+ auto customMemoryManagement = reinterpret_cast<CustomMemoryManagement*>(arg);
+ customMemoryManagement->end(data);
+ delete customMemoryManagement;
+ }
+ };
+
+ auto customManagement = new CustomMemoryManagement{{CustomMemoryManagement::callStart, CustomMemoryManagement::callEndAndCleanup}, p->start, p->end};
+ customManagement->realMemoryManagement.arg = static_cast<void*>(customManagement);
+ return reinterpret_cast<MemoryManagementStrategy>(&customManagement->realMemoryManagement);
+ }
+}
+
+const CppC4Group::MemoryManagement CppC4Group::MemoryManagement::Take{reinterpret_cast<MemoryManagement::MemoryManagementStrategy>(cc4group.MemoryManagement.Take)};
+const CppC4Group::MemoryManagement CppC4Group::MemoryManagement::Copy{reinterpret_cast<MemoryManagement::MemoryManagementStrategy>(cc4group.MemoryManagement.Copy)};
+const CppC4Group::MemoryManagement CppC4Group::MemoryManagement::Reference{reinterpret_cast<MemoryManagement::MemoryManagementStrategy>(cc4group.MemoryManagement.Reference)};
+
namespace {
CC4Group_TmpMemoryStrategy convertTmpMemoryStrategy(const CppC4Group::TmpMemoryStrategy strategy)
{
@@ -54,22 +114,13 @@ namespace {
return cc4group.TmpMemoryStrategies.Auto;
}
- CC4Group_MemoryManagement convertMemoryManagement(const CppC4Group::MemoryManagement management)
+ CC4Group_MemoryManagement convertMemoryManagement(const CppC4Group::MemoryManagement& memoryManagement)
{
- 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;
+ return reinterpret_cast<CC4Group_MemoryManagement>(memoryManagement());
}
}
-CppC4Group::CppC4Group() : p{new CppC4Group::Private{}}
+CppC4Group::CppC4Group() : p{new Private{}}
{
}
@@ -110,12 +161,12 @@ bool CppC4Group::openFilePointer(FILE* file)
return cc4group.openFilePointer(p->g, file);
}
-bool CppC4Group::openMemory(const void* const data, const size_t size, const MemoryManagement management)
+bool CppC4Group::openMemory(const void* const data, const size_t size, const MemoryManagement& management)
{
return cc4group.openMemory(p->g, data, size, convertMemoryManagement(management));
}
-bool CppC4Group::openWithReadCallback(const ReadCallback callback, void* const callbackArg, const MemoryManagement management, SetupCallback initCallback, SetupCallback deinitCallback)
+bool CppC4Group::openWithReadCallback(const ReadCallback callback, void* const callbackArg, const MemoryManagement& management, SetupCallback initCallback, SetupCallback deinitCallback)
{
return cc4group.openWithReadCallback(p->g, callback, callbackArg, convertMemoryManagement(management), initCallback, deinitCallback);
}
@@ -311,7 +362,7 @@ bool CppC4Group::createFile(const std::string& path)
return cc4group.createFile(p->g, path.c_str());
}
-bool CppC4Group::setEntryData(const std::string& path, const void*const data, const size_t size, const MemoryManagement management)
+bool CppC4Group::setEntryData(const std::string& path, const void*const data, const size_t size, const MemoryManagement& management)
{
return cc4group.setEntryData(p->g, path.c_str(), data, size, convertMemoryManagement(management));
}