archiver_dir.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. #define __PHYSICSFS_INTERNAL__
  9. #include "physfs_internal.h"
  10. /* There's no PHYSFS_Io interface here. Use __PHYSFS_createNativeIo(). */
  11. static void *DIR_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
  12. {
  13. PHYSFS_Stat statbuf;
  14. const char dirsep = __PHYSFS_platformDirSeparator;
  15. char *retval = NULL;
  16. const size_t namelen = strlen(name);
  17. const size_t seplen = 1;
  18. int exists = 0;
  19. assert(io == NULL); /* shouldn't create an Io for these. */
  20. BAIL_IF_MACRO(!__PHYSFS_platformStat(name, &exists, &statbuf), NULL, NULL);
  21. if ((!exists) || (statbuf.filetype != PHYSFS_FILETYPE_DIRECTORY))
  22. BAIL_MACRO(ERR_NOT_AN_ARCHIVE, NULL);
  23. retval = allocator.Malloc(namelen + seplen + 1);
  24. BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
  25. strcpy(retval, name);
  26. /* make sure there's a dir separator at the end of the string */
  27. if (retval[namelen - 1] != dirsep)
  28. {
  29. retval[namelen] = dirsep;
  30. retval[namelen + 1] = '\0';
  31. } /* if */
  32. return retval;
  33. } /* DIR_openArchive */
  34. /* !!! FIXME: I would like to smallAlloc() all these conversions somehow. */
  35. static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
  36. int omitSymLinks, PHYSFS_EnumFilesCallback cb,
  37. const char *origdir, void *callbackdata)
  38. {
  39. char *d = __PHYSFS_platformCvtToDependent((char *) opaque, dname, NULL);
  40. if (d != NULL)
  41. {
  42. __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb,
  43. origdir, callbackdata);
  44. allocator.Free(d);
  45. } /* if */
  46. } /* DIR_enumerateFiles */
  47. static PHYSFS_Io *doOpen(dvoid *opaque, const char *name,
  48. const int mode, int *fileExists)
  49. {
  50. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  51. PHYSFS_Io *io = NULL;
  52. int existtmp = 0;
  53. if (fileExists == NULL)
  54. fileExists = &existtmp;
  55. BAIL_IF_MACRO(f == NULL, NULL, NULL);
  56. io = __PHYSFS_createNativeIo(f, mode);
  57. if (io == NULL)
  58. {
  59. PHYSFS_Stat statbuf; /* !!! FIXME: this changes the error message. */
  60. __PHYSFS_platformStat(f, fileExists, &statbuf);
  61. } /* if */
  62. else
  63. {
  64. *fileExists = 1;
  65. } /* else */
  66. allocator.Free(f);
  67. return io;
  68. } /* doOpen */
  69. static PHYSFS_Io *DIR_openRead(dvoid *opaque, const char *fnm, int *exist)
  70. {
  71. return doOpen(opaque, fnm, 'r', exist);
  72. } /* DIR_openRead */
  73. static PHYSFS_Io *DIR_openWrite(dvoid *opaque, const char *filename)
  74. {
  75. return doOpen(opaque, filename, 'w', NULL);
  76. } /* DIR_openWrite */
  77. static PHYSFS_Io *DIR_openAppend(dvoid *opaque, const char *filename)
  78. {
  79. return doOpen(opaque, filename, 'a', NULL);
  80. } /* DIR_openAppend */
  81. static int DIR_remove(dvoid *opaque, const char *name)
  82. {
  83. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  84. int retval;
  85. BAIL_IF_MACRO(f == NULL, NULL, 0);
  86. retval = __PHYSFS_platformDelete(f);
  87. allocator.Free(f);
  88. return retval;
  89. } /* DIR_remove */
  90. static int DIR_mkdir(dvoid *opaque, const char *name)
  91. {
  92. char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  93. int retval;
  94. BAIL_IF_MACRO(f == NULL, NULL, 0);
  95. retval = __PHYSFS_platformMkDir(f);
  96. allocator.Free(f);
  97. return retval;
  98. } /* DIR_mkdir */
  99. static void DIR_dirClose(dvoid *opaque)
  100. {
  101. allocator.Free(opaque);
  102. } /* DIR_dirClose */
  103. static int DIR_stat(dvoid *opaque, const char *name, int *exists,
  104. PHYSFS_Stat *stat)
  105. {
  106. char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
  107. int retval = 0;
  108. BAIL_IF_MACRO(d == NULL, NULL, 0);
  109. retval = __PHYSFS_platformStat(d, exists, stat);
  110. allocator.Free(d);
  111. return retval;
  112. } /* DIR_stat */
  113. const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
  114. {
  115. "",
  116. DIR_ARCHIVE_DESCRIPTION,
  117. "Ryan C. Gordon <icculus@icculus.org>",
  118. "http://icculus.org/physfs/",
  119. };
  120. const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
  121. {
  122. &__PHYSFS_ArchiveInfo_DIR,
  123. DIR_openArchive, /* openArchive() method */
  124. DIR_enumerateFiles, /* enumerateFiles() method */
  125. DIR_openRead, /* openRead() method */
  126. DIR_openWrite, /* openWrite() method */
  127. DIR_openAppend, /* openAppend() method */
  128. DIR_remove, /* remove() method */
  129. DIR_mkdir, /* mkdir() method */
  130. DIR_dirClose, /* dirClose() method */
  131. DIR_stat /* stat() method */
  132. };
  133. /* end of dir.c ... */