summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt11
-rw-r--r--src/cppc4group.cpp214
-rw-r--r--src/cppc4group.hpp74
3 files changed, 299 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 47da632..879b985 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,9 @@ project(cc4group)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
if(${CMAKE_C_COMPILER_ID} MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wcast-align -Werror")
endif()
@@ -16,11 +19,19 @@ set(cc4group_SRC
src/c4groupentrycore.c
)
+set(cppc4group_SRC
+ src/cppc4group.cpp
+)
+
add_library(cc4group STATIC ${cc4group_SRC})
target_link_libraries(cc4group PRIVATE ZLIB::ZLIB)
target_include_directories(cc4group PRIVATE ZLIB::ZLIB)
set_property(TARGET cc4group PROPERTY POSITION_INDEPENDENT_CODE ON)
+add_library(cppc4group STATIC ${cc4group_SRC} ${cppc4group_SRC})
+target_link_libraries(cppc4group PRIVATE ZLIB::ZLIB)
+set_property(TARGET cppc4group PROPERTY POSITION_INDEPENDENT_CODE ON)
+
add_library(cc4group_dyn SHARED ${cc4group_SRC})
target_link_libraries(cc4group_dyn PRIVATE ZLIB::ZLIB)
target_include_directories(cc4group_dyn PRIVATE ZLIB::ZLIB)
diff --git a/src/cppc4group.cpp b/src/cppc4group.cpp
new file mode 100644
index 0000000..9a97f10
--- /dev/null
+++ b/src/cppc4group.cpp
@@ -0,0 +1,214 @@
+#include "cppc4group.hpp"
+
+#include "cc4group.h"
+
+CppC4Group::Data::Data() : data{nullptr}, size{0}
+{
+
+}
+
+CppC4Group::Data::Data(const void* data, size_t size) : data{data}, size{size}
+{
+
+}
+
+struct CppC4Group::Private {
+ CC4Group* g;
+
+ Private() : g{cc4group.new_()}
+ {
+
+ }
+
+ ~Private()
+ {
+ cc4group.delete_(g);
+ }
+};
+
+CppC4Group::CppC4Group() : p{new CppC4Group::Private{}}
+{
+
+}
+
+CppC4Group::~CppC4Group()
+{
+
+}
+
+void CppC4Group::create()
+{
+ cc4group.create(p->g);
+}
+
+bool CppC4Group::openExisting(const std::string& path)
+{
+ return cc4group.openExisting(p->g, path.c_str());
+}
+
+bool CppC4Group::save(const std::string& path, const bool overwrite)
+{
+ return (overwrite ? cc4group.saveOverwrite : cc4group.save)(p->g, path.c_str());
+}
+
+bool CppC4Group::extractAll(const std::string& path)
+{
+ return cc4group.extractAll(p->g, path.c_str());
+}
+
+bool CppC4Group::extractSingle(const std::string& entryPath, const std::string& targetPath)
+{
+ return cc4group.extractSingle(p->g, entryPath.c_str(), targetPath.c_str());
+}
+
+std::optional<CppC4Group::Data> CppC4Group::getEntryData(const std::string& path)
+{
+ const void* data;
+ size_t size;
+ if(cc4group.getEntryData(p->g, path.c_str(), &data, &size))
+ {
+ return {{data, size}};
+ }
+ else
+ {
+ return {};
+ }
+}
+
+std::string CppC4Group::getErrorMessage()
+{
+ return cc4group.getErrorMessage(p->g);
+}
+
+int32_t CppC4Group::getErrorCode()
+{
+ return cc4group.getErrorCode(p->g);
+}
+
+std::string CppC4Group::getErrorMethod()
+{
+ return cc4group.getErrorMethod(p->g);
+}
+
+std::string CppC4Group::getErrorCauser()
+{
+ return cc4group.getErrorCauser(p->g);
+}
+
+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);
+}
+
+bool CppC4Group::setMaker(const std::string& maker, const std::string& path, const bool recursive)
+{
+ return cc4group.setMaker(p->g, maker.c_str(), path.c_str(), recursive);
+}
+
+bool CppC4Group::setCreation(const int32_t creation, const std::string& path, const bool recursive)
+{
+ return cc4group.setCreation(p->g, creation, path.c_str(), recursive);
+}
+
+bool CppC4Group::setOfficial(const bool official, const std::string& path, const bool recursive)
+{
+ return cc4group.setOfficial(p->g, official, path.c_str(), recursive);
+}
+
+bool CppC4Group::setExecutable(const bool executable, const std::string& path)
+{
+ return cc4group.setExecutable(p->g, executable, path.c_str());
+}
+
+namespace {
+ CppC4Group::EntryInfo& fillEntryInfo(CppC4Group::EntryInfo& info, const CC4Group_EntryInfo& entryInfo)
+ {
+ info.fileName = entryInfo.fileName;
+ info.modified = entryInfo.modified;
+ info.author = entryInfo.author;
+ info.size = entryInfo.size;
+ info.totalSize = entryInfo.totalSize;
+ info.executable = entryInfo.executable;
+ info.official = entryInfo.official;
+
+ return info;
+ }
+};
+
+std::optional<CppC4Group::EntryInfo> CppC4Group::getEntryInfo(const std::string& path)
+{
+ CC4Group_EntryInfo info;
+ if(cc4group.getEntryInfo(p->g, path.c_str(), &info))
+ {
+ CppC4Group::EntryInfo entryInfo;
+ return fillEntryInfo(entryInfo, info);
+ }
+ else
+ {
+ return {};
+ }
+}
+
+std::optional<std::vector<CppC4Group::EntryInfo> > CppC4Group::getEntryInfos(const std::string& path)
+{
+ CC4Group_EntryInfo* infos;
+ size_t infoCount;
+
+ if(cc4group.getEntryInfos(p->g, path.c_str(), &infos, &infoCount))
+ {
+ std::vector<CppC4Group::EntryInfo> entryInfos;
+ entryInfos.reserve(infoCount);
+
+ for(size_t i = 0; i < infoCount; ++i)
+ {
+ fillEntryInfo(entryInfos.emplace_back(), infos[i]);
+ }
+
+ free(infos);
+
+ return entryInfos;
+ }
+ else
+ {
+ return {};
+ }
+}
+
+bool CppC4Group::deleteEntry(const std::string& path, const bool recursive)
+{
+ return cc4group.deleteEntry(p->g, path.c_str(), recursive);
+}
+
+bool CppC4Group::renameEntry(const std::string& oldPath, const std::string& newPath)
+{
+ return cc4group.renameEntry(p->g, oldPath.c_str(), newPath.c_str());
+}
+
+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)
+{
+ return cc4group.createFile(p->g, path.c_str(), data, size);
+}
+
+bool CppC4Group::setEntryData(const std::string& path, void* data, size_t size)
+{
+ return cc4group.setEntryData(p->g, path.c_str(), data, size);
+}
diff --git a/src/cppc4group.hpp b/src/cppc4group.hpp
new file mode 100644
index 0000000..fc46592
--- /dev/null
+++ b/src/cppc4group.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+#include <memory>
+#include <vector>
+#include <optional>
+
+class CppC4Group {
+ struct Private;
+
+ std::unique_ptr<Private> p;
+
+public:
+ struct Data {
+ const void* data;
+ size_t size;
+
+ Data();
+ Data(const void* data, size_t size);
+ };
+
+ struct EntryInfo {
+ std::string fileName;
+ int32_t modified;
+ std::string author;
+ size_t size;
+ size_t totalSize;
+ bool executable;
+ bool directory;
+ bool official;
+ };
+
+public:
+ enum TmpMemoryStrategy {
+ Memory,
+ File,
+ Auto
+ };
+
+ static void setTmpMemoryStrategy(const TmpMemoryStrategy strategy);
+
+public:
+ CppC4Group();
+ ~CppC4Group();
+
+ void create();
+ bool openExisting(const std::string& path);
+ bool save(const std::string& path, const bool overwrite = false);
+
+ bool extractAll(const std::string& path);
+ bool extractSingle(const std::string& entryPath, const std::string& targetPath);
+
+ std::optional<Data> getEntryData(const std::string& path);
+ std::string getErrorMessage();
+ int32_t getErrorCode();
+ std::string getErrorMethod();
+ std::string getErrorCauser();
+
+ bool setMaker(const std::string& maker, const std::string& path = "", const bool recursive = false);
+ bool setCreation(const int32_t creation, const std::string& path = "", const bool recursive = false);
+ bool setOfficial(const bool official, const std::string& path = "", const bool recursive = false);
+ bool setExecutable(const bool executable, const std::string& path);
+
+ std::optional<EntryInfo> getEntryInfo(const std::string& path = "");
+ std::optional<std::vector<EntryInfo>> getEntryInfos(const std::string& path = "");
+
+ bool deleteEntry(const std::string& path, const bool recursive);
+ bool renameEntry(const std::string& oldPath, const std::string& newPath);
+
+ bool createDirectory(const std::string& path);
+
+ bool createFile(const std::string& path, void* data = nullptr, size_t size = 0);
+
+ bool setEntryData(const std::string& path, void* data = nullptr, size_t size = 0);
+};