diff options
| author | Markus Mittendrein <git@maxmitti.tk> | 2020-04-21 00:54:38 +0200 |
|---|---|---|
| committer | Markus Mittendrein <git@maxmitti.tk> | 2020-04-21 00:54:38 +0200 |
| commit | 20f8542d2730654ba7140dc59240c8d477476e77 (patch) | |
| tree | 2c48120a8882e70142fea964906e50f95d08d171 | |
| parent | 830ee22b85f1e91c547354435af2b6a79578f7ce (diff) | |
| download | cc4group-20f8542d2730654ba7140dc59240c8d477476e77.tar.gz cc4group-20f8542d2730654ba7140dc59240c8d477476e77.zip | |
Add cc4group.getName and cc4group.getFullName
| -rw-r--r-- | src/cc4group.c | 73 | ||||
| -rw-r--r-- | src/cc4group.h | 12 | ||||
| -rw-r--r-- | src/cppc4group.cpp | 23 | ||||
| -rw-r--r-- | src/cppc4group.hpp | 3 | ||||
| -rw-r--r-- | src/platform/platform.h | 7 | ||||
| -rw-r--r-- | src/platform/unix.c | 13 | ||||
| -rw-r--r-- | src/platform/windows.c | 17 |
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; +} |
