# HG changeset patch # User Matti Hamalainen # Date 1365985595 -10800 # Node ID e8fc083b749962f056014b37f6bf71857c8207e8 # Parent dfdff30ad363c6948bc09a351b8ac949f829f57a More work on resource management. diff -r dfdff30ad363 -r e8fc083b7499 dmres.c --- a/dmres.c Sat Apr 13 07:01:17 2013 +0300 +++ b/dmres.c Mon Apr 15 03:26:35 2013 +0300 @@ -7,6 +7,16 @@ #include "dmres.h" #include +#ifdef DM_USE_STDIO +# ifdef __WIN32 +# else +# include +# include +# include +# include +# endif +#endif + DMResource *dmres_new(DMResourceLib *lib, const char *filename, int flags, size_t size) { @@ -68,7 +78,7 @@ void dmres_insert(DMResourceLib *lib, DMResource * node) { - if (lib == NULL) + if (lib == NULL || node == NULL) return; node->lib = lib; @@ -616,13 +626,18 @@ } else { + if (((handle->flags & DMF_PRELOAD_RES) || (handle->lib->flags & DRF_PRELOAD_RES)) && + handle->fops->preload != NULL) + ret = handle->fops->preload(handle); + else if (handle->fops->fopen != NULL) ret = handle->fops->fopen(handle); else - if (handle->fops->preload != NULL) - ret = handle->fops->preload(handle); + return DMERR_FOPEN; } + dmf_reset(handle); + // Check if resource data is to be preloaded if ((handle->flags & DMF_PRELOAD_RES) || (handle->lib->flags & DRF_PRELOAD_RES)) { @@ -907,64 +922,64 @@ } -int dmres_load_resfile(DMResourceLib *lib, const char *filename) +#ifdef DM_USE_STDIO +static int dmres_load_directory(DMResourceLib *lib, const char *path) { - int ret = DMERR_OK; - char line[256]; - FILE *f = fopen(filename, "r"); - if (f == NULL) - return DMERR_FOPEN; + int res = DMERR_OK; + BOOL done = FALSE; + +#ifdef __WIN32 +#else + DIR *hdir = opendir(path); + if (hdir == NULL) + return dmGetErrno(); +#endif dmMutexLock(lib->mutex); - while (fgets(line, sizeof(line) - 1, f) != NULL) + do { - int fnstart, fsep; - for (fnstart = 0; isspace(line[fnstart]); fnstart++); - for (fsep = fnstart; line[fsep] && line[fsep] != '|'; fsep++); - if (line[fsep] == '|') + DMResource *node = NULL; +#ifdef __WIN32 +#else + struct dirent *dh = readdir(hdir); + if (dh == NULL) + done = TRUE; + else { - int flags, i; - for (i = fsep - 1; i > 0 && isspace(line[i]); i--) - line[i] = 0; - - for (i = fsep; isspace(line[i]); i++); - } - } - - dmMutexUnlock(lib->mutex); - fclose(f); - - return ret; -} - + struct stat sbuf; + char *fname = dm_strdup_printf("%s/%s", path, dh->d_name); + if (stat(fname, &sbuf) == -1) + { + res = dmGetErrno(); + dmError("Could not stat() %s, #%d: %s\n", + fname, res, dmErrorStr(res)); + dmFree(fname); + goto out; + } -int dmres_write_resfile(DMResourceLib *lib, const char *filename) -{ - int ret; - DMResource *node; - FILE *f = fopen(filename, "w"); - if (f == NULL) - return DMERR_FOPEN; + if (S_ISREG(sbuf.st_mode)) + node = dmres_new(lib, dh->d_name, 0, sbuf.st_size); + } +#endif + if (node != NULL) + { + node->fops = &dfStdioFileOps; + dmres_insert(lib, node); + } + } while (!done); - dmMutexLock(lib->mutex); - - for (node = lib->resources; node != NULL; node = node->next) - { - char tmp[64]; - dmres_flags_to_symbolic(tmp, sizeof(tmp), node->flags); - if (fprintf(f, "%s|%s\n", node->filename, tmp) < 0) - { - ret = DMERR_FWRITE; - goto error; - } - } +out: + dmMutexUnlock(lib->mutex); -error: - dmMutexUnlock(lib->mutex); - fclose(f); - return ret; +#ifdef __WIN32 +#else + closedir(hdir); +#endif + + return res; } +#endif /* Resources subsystem initialization and shutdown routines @@ -972,7 +987,8 @@ int dmres_init(DMResourceLib **plib, const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)) { DMResourceLib *lib; - + BOOL initialized = FALSE; + // Allocate the resource library structure if ((*plib = lib = dmMalloc0(sizeof(DMResourceLib))) == NULL) return DMERR_MALLOC; @@ -983,9 +999,9 @@ lib->resPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH); - if (flags & DRF_USE_PACK) +#ifdef DM_USE_PACKFS + if (!initialized && (flags & DRF_USE_PACK)) { -#ifdef DM_USE_PACKFS int ret; DMPackEntry *node; @@ -995,41 +1011,48 @@ ret = dm_pack_open(lib->packFilename, &lib->packFile, TRUE); if (ret != DMERR_OK) { - dmError("Error opening PACK file '%s', #%i: %s\n", + if ((flags & DRF_USE_STDIO) == 0) + { + dmError("Error opening PACK file '%s', #%i: %s\n", lib->packFilename, ret, dmErrorStr(ret)); - return DMERR_INIT_FAIL; - } - - // Initialize resources from a PACK file - for (node = lib->packFile->entries; node != NULL; node = node->next) - { - DMResource *res = dmres_new(lib, node->filename, node->resFlags & DMF_MASK, node->size); - if (res == NULL) - { - dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n", - node->filename, node->resFlags, node->size); return DMERR_INIT_FAIL; } - - dmres_insert(lib, res); } - -#else - // PACK not compiled in, FAIL! - return DMERR_INIT_FAIL; + else + { + // Initialize resources from a PACK file + for (node = lib->packFile->entries; node != NULL; node = node->next) + { + DMResource *res = dmres_new(lib, node->filename, node->resFlags & DMF_MASK, node->size); + if (res == NULL) + { + dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n", + node->filename, node->resFlags, node->size); + return DMERR_INIT_FAIL; + } + + dmres_insert(lib, res); + } + + initialized = TRUE; + } + } #endif - } - else + +#ifdef DM_USE_STDIO + if (!initialized && (flags & DRF_USE_STDIO)) { // Initialize resources from a resource directory - char *resFilename = dm_strdup_printf("%s%s", lib->resPath, DMRES_RES_FILE); - int ret = dmres_load_resfile(lib, resFilename); - dmFree(resFilename); - + int ret = dmres_load_directory(lib, lib->resPath); if (ret != DMERR_OK) - return DMERR_INIT_FAIL; + return ret; + initialized = TRUE; } +#endif + + if (!initialized) + return DMERR_INIT_FAIL; // Okay, classify resources if (lib->resources != NULL && classifier != NULL) diff -r dfdff30ad363 -r e8fc083b7499 dmres.h --- a/dmres.h Sat Apr 13 07:01:17 2013 +0300 +++ b/dmres.h Mon Apr 15 03:26:35 2013 +0300 @@ -134,8 +134,6 @@ void dmres_flags_to_symbolic(char *str, size_t size, int flags); int dmres_symbolic_to_flags(const char *str); -int dmres_load_resfile(DMResourceLib *lib, const char *filename); -int dmres_write_resfile(DMResourceLib *lib, const char *filename); DMResource * dmres_new(DMResourceLib *lib, const char *filename, int flags, size_t size); void dmres_free(DMResource *node);