Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Standard directory I/O support routines for PhysicsFS.
  3.  *
  4.  * Please see the file LICENSE.txt in the source's root directory.
  5.  *
  6.  *  This file written by Ryan C. Gordon.
  7.  */
  8.  
  9. #define __PHYSICSFS_INTERNAL__
  10. #include "physfs_internal.h"
  11.  
  12. /* There's no PHYSFS_Io interface here. Use __PHYSFS_createNativeIo(). */
  13.  
  14.  
  15.  
  16. static char *cvtToDependent(const char *prepend, const char *path,
  17.                             char *buf, const size_t buflen)
  18. {
  19.     BAIL_IF(buf == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
  20.     snprintf(buf, buflen, "%s%s", prepend ? prepend : "", path);
  21.  
  22.     #if !__PHYSFS_STANDARD_DIRSEP
  23.     assert(__PHYSFS_platformDirSeparator != '/');
  24.     {
  25.         char *p;
  26.         for (p = strchr(buf, '/'); p != NULL; p = strchr(p + 1, '/'))
  27.             *p = __PHYSFS_platformDirSeparator;
  28.     } /* if */
  29.     #endif
  30.  
  31.     return buf;
  32. } /* cvtToDependent */
  33.  
  34.  
  35. #define CVT_TO_DEPENDENT(buf, pre, dir) { \
  36.     const size_t len = ((pre) ? strlen((char *) pre) : 0) + strlen(dir) + 1; \
  37.     buf = cvtToDependent((char*)pre,dir,(char*)__PHYSFS_smallAlloc(len),len); \
  38. }
  39.  
  40.  
  41.  
  42. static void *DIR_openArchive(PHYSFS_Io *io, const char *name,
  43.                              int forWriting, int *claimed)
  44. {
  45.     PHYSFS_Stat st;
  46.     const char dirsep = __PHYSFS_platformDirSeparator;
  47.     char *retval = NULL;
  48.     const size_t namelen = strlen(name);
  49.     const size_t seplen = 1;
  50.  
  51.     assert(io == NULL);  /* shouldn't create an Io for these. */
  52.     BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st, 1), NULL);
  53.  
  54.     if (st.filetype != PHYSFS_FILETYPE_DIRECTORY)
  55.         BAIL(PHYSFS_ERR_UNSUPPORTED, NULL);
  56.  
  57.     *claimed = 1;
  58.     retval = allocator.Malloc(namelen + seplen + 1);
  59.     BAIL_IF(retval == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
  60.  
  61.     strcpy(retval, name);
  62.  
  63.     /* make sure there's a dir separator at the end of the string */
  64.     if (retval[namelen - 1] != dirsep)
  65.     {
  66.         retval[namelen] = dirsep;
  67.         retval[namelen + 1] = '\0';
  68.     } /* if */
  69.  
  70.     return retval;
  71. } /* DIR_openArchive */
  72.  
  73.  
  74. static PHYSFS_EnumerateCallbackResult DIR_enumerate(void *opaque,
  75.                          const char *dname, PHYSFS_EnumerateCallback cb,
  76.                          const char *origdir, void *callbackdata)
  77. {
  78.     char *d;
  79.     PHYSFS_EnumerateCallbackResult retval;
  80.     CVT_TO_DEPENDENT(d, opaque, dname);
  81.     BAIL_IF_ERRPASS(!d, PHYSFS_ENUM_ERROR);
  82.     retval = __PHYSFS_platformEnumerate(d, cb, origdir, callbackdata);
  83.     __PHYSFS_smallFree(d);
  84.     return retval;
  85. } /* DIR_enumerate */
  86.  
  87.  
  88. static PHYSFS_Io *doOpen(void *opaque, const char *name, const int mode)
  89. {
  90.     PHYSFS_Io *io = NULL;
  91.     char *f = NULL;
  92.  
  93.     CVT_TO_DEPENDENT(f, opaque, name);
  94.     BAIL_IF_ERRPASS(!f, NULL);
  95.  
  96.     io = __PHYSFS_createNativeIo(f, mode);
  97.     if (io == NULL)
  98.     {
  99.         const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
  100.         PHYSFS_Stat statbuf;
  101.         __PHYSFS_platformStat(f, &statbuf, 0);  /* !!! FIXME: why are we stating here? */
  102.         PHYSFS_setErrorCode(err);
  103.     } /* if */
  104.  
  105.     __PHYSFS_smallFree(f);
  106.  
  107.     return io;
  108. } /* doOpen */
  109.  
  110.  
  111. static PHYSFS_Io *DIR_openRead(void *opaque, const char *filename)
  112. {
  113.     return doOpen(opaque, filename, 'r');
  114. } /* DIR_openRead */
  115.  
  116.  
  117. static PHYSFS_Io *DIR_openWrite(void *opaque, const char *filename)
  118. {
  119.     return doOpen(opaque, filename, 'w');
  120. } /* DIR_openWrite */
  121.  
  122.  
  123. static PHYSFS_Io *DIR_openAppend(void *opaque, const char *filename)
  124. {
  125.     return doOpen(opaque, filename, 'a');
  126. } /* DIR_openAppend */
  127.  
  128.  
  129. static int DIR_remove(void *opaque, const char *name)
  130. {
  131.     int retval;
  132.     char *f;
  133.  
  134.     CVT_TO_DEPENDENT(f, opaque, name);
  135.     BAIL_IF_ERRPASS(!f, 0);
  136.     retval = __PHYSFS_platformDelete(f);
  137.     __PHYSFS_smallFree(f);
  138.     return retval;
  139. } /* DIR_remove */
  140.  
  141.  
  142. static int DIR_mkdir(void *opaque, const char *name)
  143. {
  144.     int retval;
  145.     char *f;
  146.  
  147.     CVT_TO_DEPENDENT(f, opaque, name);
  148.     BAIL_IF_ERRPASS(!f, 0);
  149.     retval = __PHYSFS_platformMkDir(f);
  150.     __PHYSFS_smallFree(f);
  151.     return retval;
  152. } /* DIR_mkdir */
  153.  
  154.  
  155. static void DIR_closeArchive(void *opaque)
  156. {
  157.     allocator.Free(opaque);
  158. } /* DIR_closeArchive */
  159.  
  160.  
  161. static int DIR_stat(void *opaque, const char *name, PHYSFS_Stat *stat)
  162. {
  163.     int retval = 0;
  164.     char *d;
  165.  
  166.     CVT_TO_DEPENDENT(d, opaque, name);
  167.     BAIL_IF_ERRPASS(!d, 0);
  168.     retval = __PHYSFS_platformStat(d, stat, 0);
  169.     __PHYSFS_smallFree(d);
  170.     return retval;
  171. } /* DIR_stat */
  172.  
  173.  
  174. const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
  175. {
  176.     CURRENT_PHYSFS_ARCHIVER_API_VERSION,
  177.     {
  178.         "",
  179.         "Non-archive, direct filesystem I/O",
  180.         "Ryan C. Gordon <icculus@icculus.org>",
  181.         "https://icculus.org/physfs/",
  182.         1,  /* supportsSymlinks */
  183.     },
  184.     DIR_openArchive,
  185.     DIR_enumerate,
  186.     DIR_openRead,
  187.     DIR_openWrite,
  188.     DIR_openAppend,
  189.     DIR_remove,
  190.     DIR_mkdir,
  191.     DIR_stat,
  192.     DIR_closeArchive
  193. };
  194.  
  195. /* end of physfs_archiver_dir.c ... */
  196.  
  197.