changeset 625:e8fc083b7499

More work on resource management.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 15 Apr 2013 03:26:35 +0300
parents dfdff30ad363
children 1dc029925377
files dmres.c dmres.h
diffstat 2 files changed, 102 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- 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 <time.h>
 
+#ifdef DM_USE_STDIO
+#    ifdef __WIN32
+#    else
+#        include <sys/types.h>
+#        include <sys/stat.h>
+#        include <unistd.h>
+#        include <dirent.h>
+#    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)
--- 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);