summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2020-04-21 00:54:38 +0200
committerMarkus Mittendrein <git@maxmitti.tk>2020-04-21 00:54:38 +0200
commit20f8542d2730654ba7140dc59240c8d477476e77 (patch)
tree2c48120a8882e70142fea964906e50f95d08d171
parent830ee22b85f1e91c547354435af2b6a79578f7ce (diff)
downloadcc4group-20f8542d2730654ba7140dc59240c8d477476e77.tar.gz
cc4group-20f8542d2730654ba7140dc59240c8d477476e77.zip
Add cc4group.getName and cc4group.getFullName
-rw-r--r--src/cc4group.c73
-rw-r--r--src/cc4group.h12
-rw-r--r--src/cppc4group.cpp23
-rw-r--r--src/cppc4group.hpp3
-rw-r--r--src/platform/platform.h7
-rw-r--r--src/platform/unix.c13
-rw-r--r--src/platform/windows.c17
7 files changed, 138 insertions, 10 deletions
diff --git a/src/cc4group.c b/src/cc4group.c
index c1c434a..1fc0584 100644
--- a/src/cc4group.c
+++ b/src/cc4group.c
@@ -81,6 +81,9 @@ LIST_AUTO(C4GroupEntryData, GroupEntryList)
LIST_AUTO(CC4Group_CleanupJob, CleanUpJobList)
#define ForeachCleanupJob(list) LIST_FOREACH(CleanUpJobList, list, job)
+LIST_AUTO(const CC4Group*, GroupList);
+#define ForeachGroup(list) LIST_FOREACH(GroupList, list, group)
+
typedef char* (*ErrorFormatter)(int32_t const code, const char* const method, const char* const causer, void* const data);
typedef struct {
@@ -125,6 +128,8 @@ struct CC4Group_t {
bool lazy;
const char* path;
+ const char* name;
+ const char* pathInParent;
bool subRooted;
};
@@ -1065,6 +1070,8 @@ static bool cc4group_setSubRoot(CC4Group* const this, const char* const subPath)
this->realRoot = this->root;
this->root = *subRoot;
this->subRooted = true;
+ this->pathInParent = strdup(subPath);
+ this->name = strdup(subRoot->core.FileName);
}
return true;
@@ -1205,6 +1212,8 @@ static void cc4group_init(CC4Group* const this)
this->parent = NULL;
this->lazy = true;
this->path = NULL;
+ this->name = NULL;
+ this->pathInParent = NULL;
this->subRooted = false;
this->uncompressedData = NULL;
@@ -1715,6 +1724,7 @@ static bool cc4group_openExisting(CC4Group* const this, const char* const path)
}
this->path = cc4group_absolutePath(path);
+ this->name = cc4group_basename(path);
if(cc4group_isDirectory(path))
{
@@ -1760,6 +1770,16 @@ static void cc4group_delete(CC4Group* const this)
free((void*)this->path);
}
+ if(this->name != NULL)
+ {
+ free((void*)this->name);
+ }
+
+ if(this->pathInParent != NULL)
+ {
+ free((void*)this->pathInParent);
+ }
+
free(this);
}
@@ -3281,6 +3301,8 @@ static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const pa
}
child->parent = this;
+ child->name = strdup(entry->core.FileName);
+ child->pathInParent = strdup(path);
++this->referenceCounter;
@@ -3294,6 +3316,52 @@ static bool cc4group_isChild(const CC4Group* const this)
return this->parent != NULL;
}
+static const char* cc4group_getName(const CC4Group* const this)
+{
+ return this->name;
+}
+
+static char* cc4group_getFullName(const CC4Group* const this)
+{
+ if(!this->parent && !this->subRooted)
+ {
+ return strdup(this->path);
+ }
+
+ GroupList* groups = GroupListNew();
+
+ size_t len = 0;
+ const CC4Group* child = this;
+ while(child->parent)
+ {
+ GroupListPrepend(groups, child);
+ len += strlen(child->pathInParent) + 1;
+ child = child->parent;
+ }
+
+ if(!child->path)
+ {
+ GroupListDestroy(groups);
+ return NULL;
+ }
+ len += strlen(child->path) + 1;
+
+ char* result = malloc(sizeof(char) * len);
+ if(result == NULL)
+ {
+ return NULL;
+ }
+ strcpy(result, child->path);
+
+ ForeachGroup(groups)
+ {
+ strcat(result, "/");
+ strcat(result, group->value->pathInParent);
+ }
+
+ return result;
+}
+
static void* cc4group_memoryManagementTakeStart(void* const data, size_t const size, void* const arg)
{
(void)size;
@@ -3442,5 +3510,8 @@ CC4Group_API cc4group = {
.openAsChild = cc4group_openAsChild,
- .isChild = cc4group_isChild
+ .isChild = cc4group_isChild,
+
+ .getName = cc4group_getName,
+ .getFullName = cc4group_getFullName
};
diff --git a/src/cc4group.h b/src/cc4group.h
index 732aa0c..6365f82 100644
--- a/src/cc4group.h
+++ b/src/cc4group.h
@@ -29,7 +29,7 @@
// the directory separator used for all entry paths in cc4group is "/" _regardless of the platform_. yes, you better watch out Windows users!
// in contrast to paths names are only the the name of the entry itself, not the whole path
// - to free all resources used by the group when it is not needed anymore, call cc4group.delete with the group pointer and discard it afterwards (i.e. don't use it anymore)
-// - all functions, except cc4group.new, cc4group.setLazy, cc4group.openAsChild, cc4group.isChild, cc4group.delete, cc4group.setWarningCallback and cc4group.setTmpMemoryStrategy (where the latter three can't fail) follow the same scheme
+// - most functions follow the same scheme
// all of them can fail, either caused by wrong arguments or by things outside of the applications control
// they all return _true_ if everything went well and _false_ if any error occured
// information about the error (incredibly useful for debugging or asking for help with problems) can be obtained by using one of the cc4group.getError* functions
@@ -434,6 +434,16 @@ typedef struct {
// returns wether this group has been opend with cc4group.openAsChild
// NOTE: this function can't fail, thus the return value is the result value, not the success indication
bool (*isChild)(const CC4Group* const this);
+
+
+ // returns the filename of the group file, if known, or directory name of the child-root entry for openAsChild groups
+ // might return NULL if not determinable (e.g. if not opened from file)
+ const char* (*getName)(const CC4Group* const this);
+
+ // returns the full absolute path of the group file, including the path inside the real group file for openAsChild groups
+ // the returned value must be freed by the caller
+ // might return NULL if not determinable (e.g. if not opened from file)
+ char* (*getFullName)(const CC4Group* const this);
} const CC4Group_API;
diff --git a/src/cppc4group.cpp b/src/cppc4group.cpp
index 31dab62..35b589a 100644
--- a/src/cppc4group.cpp
+++ b/src/cppc4group.cpp
@@ -492,3 +492,26 @@ bool CppC4Group::isChild()
{
return cc4group.isChild(p->g);
}
+
+std::string CppC4Group::getName() const
+{
+ std::string ret;
+ const auto result = cc4group.getName(p->g);
+ if(result != nullptr)
+ {
+ ret = result;
+ }
+ return result;
+}
+
+std::string CppC4Group::getFullName() const
+{
+ const auto result = cc4group.getFullName(p->g);
+ std::string ret;
+ if(result != nullptr)
+ {
+ ret = result;
+ free(result);
+ }
+ return result;
+}
diff --git a/src/cppc4group.hpp b/src/cppc4group.hpp
index 7ede7ae..639fbf4 100644
--- a/src/cppc4group.hpp
+++ b/src/cppc4group.hpp
@@ -194,6 +194,9 @@ public:
// to get the child group out of the optional in case of success, construct a new CppC4Group with the move constructor: CppC4Group child{std::move(*optionalChild)};
std::optional<CppC4Group> openAsChild(const std::string& path);
bool isChild();
+
+ std::string getName() const;
+ std::string getFullName() const;
};
inline bool operator&(CppC4Group::AllowedEntryTypes lhs, CppC4Group::AllowedEntryTypes rhs)
diff --git a/src/platform/platform.h b/src/platform/platform.h
index 55ed242..04b20b0 100644
--- a/src/platform/platform.h
+++ b/src/platform/platform.h
@@ -24,11 +24,7 @@
#define cc4group_mkdir(path, mode) mkdir((path))
#define SET_BINARY(fd) setmode(fd, O_BINARY)
#else
- #ifndef _XOPEN_SOURCE
- #define _XOPEN_SOURCE 700
- #endif
#include <sys/mman.h>
- #include <stdlib.h>
#define cc4group_mkdir(path, mode) mkdir((path), (mode))
#define O_BINARY 0
@@ -37,4 +33,5 @@
void *cc4group_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int cc4group_munmap(void *addr, size_t length);
-char* cc4group_absolutePath(const char* path); \ No newline at end of file
+char* cc4group_absolutePath(const char* path);
+char* cc4group_basename(const char* path); \ No newline at end of file
diff --git a/src/platform/unix.c b/src/platform/unix.c
index 01161fc..4e534a6 100644
--- a/src/platform/unix.c
+++ b/src/platform/unix.c
@@ -1,3 +1,11 @@
+#ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 700
+#endif
+#ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+#include <string.h>
#include "platform.h"
void *cc4group_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
@@ -14,3 +22,8 @@ char* cc4group_absolutePath(const char* path)
{
return realpath(path, NULL);
}
+
+char* cc4group_basename(const char* path)
+{
+ return strdup(basename(path));
+} \ No newline at end of file
diff --git a/src/platform/windows.c b/src/platform/windows.c
index 96678ab..50cb722 100644
--- a/src/platform/windows.c
+++ b/src/platform/windows.c
@@ -15,6 +15,7 @@
#include <io.h>
#include <windows.h>
+#include <string.h>
#include <sys/types.h>
#include "platform.h"
@@ -90,6 +91,9 @@ void *cc4group_mmap(void *start, size_t length, int prot, int flags, int fd, off
return ret;
}
+#undef DWORD_HI
+#undef DWORD_LO
+
int cc4group_munmap(void *addr, size_t length)
{
(void)length;
@@ -102,6 +106,13 @@ char* cc4group_absolutePath(const char* path)
return _fullpath(NULL, path, 0);
}
-
-#undef DWORD_HI
-#undef DWORD_LO
+char* cc4group_basename(const char* path)
+{
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+ _splitpath(path, NULL, NULL, fname, ext);
+ char* result = malloc(sizeof(char) * (strlen(fname) + strlen(ext) + 1);
+ strcpy(result, fname);
+ strcat(result, ext);
+ return result;
+}