collection.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "collection.h"
  2. #include <string.h>
  3. #include <stdio.h>
  4. enum CollectionOpenResult collectionChainOpen(struct ICollection *collection,
  5. const char *name, enum FileType type, struct IFile **out_file) {
  6. while (collection) {
  7. enum CollectionOpenResult result = collection->open(collection, name, type, out_file);
  8. if (result == CollectionOpen_Success) return result;
  9. if (result == CollectionOpen_NotFound) {
  10. collection = collection->next;
  11. } else {
  12. /* TODO print error */
  13. return result;
  14. }
  15. }
  16. return CollectionOpen_NotFound;
  17. }
  18. static enum AFileResult filesystemCollectionFile_Open(struct FilesystemCollectionFile_ *f, const char *filename) {
  19. const enum AFileResult result = aFileOpen(&f->file, filename);
  20. f->opened = result == AFile_Success;
  21. f->head.size = f->file.size;
  22. return result;
  23. }
  24. static size_t filesystemCollectionFile_Read(struct IFile *file, size_t offset, size_t size, void *buffer) {
  25. struct FilesystemCollectionFile_ *f = (void*)file;
  26. const size_t result = aFileReadAtOffset(&f->file, offset, size, buffer);
  27. return result != AFileError ? result : 0;
  28. }
  29. static void filesystemCollectionFile_Close(struct IFile *file) {
  30. struct FilesystemCollectionFile_ *f = (void*)file;
  31. aFileClose(&f->file);
  32. f->head.size = 0;
  33. f->opened = 0;
  34. }
  35. static void filesystemCollectionClose(struct ICollection *collection) {
  36. (void)(collection);
  37. /* TODO ensure all files are closed */
  38. }
  39. static enum CollectionOpenResult filesystemCollectionOpen(struct ICollection *collection,
  40. const char *name, enum FileType type, struct IFile **out_file) {
  41. struct FilesystemCollection *fsc = (struct FilesystemCollection*)collection;
  42. char buffer[512];
  43. const char *subdir = "/";
  44. const char *suffix = "";
  45. *out_file = 0;
  46. int fileslot = 0;
  47. for(; fileslot < FilesystemCollectionFileSlots; ++fileslot)
  48. if (fsc->files[fileslot].head.read) break;
  49. if (fileslot >= FilesystemCollectionFileSlots)
  50. return CollectionOpen_TooManyFiles;
  51. struct FilesystemCollectionFile_ *f = fsc->files + fileslot;
  52. switch (type) {
  53. case File_Map: subdir = "/maps/"; suffix = ".bsp"; break;
  54. case File_Material: subdir = "/materials/"; suffix = ".vmt"; break;
  55. case File_Texture: subdir = "/textures/"; suffix = ".vtf"; break;
  56. case File_Model: subdir = "/models/"; suffix = ".mdl"; break;
  57. }
  58. snprintf(buffer, sizeof(buffer) - 1, "%s%s%s%s", fsc->path, subdir, name, suffix);
  59. /* FIXME case insensitivity */
  60. if (AFile_Success != filesystemCollectionFile_Open(f, buffer))
  61. return CollectionOpen_NotFound;
  62. *out_file = &f->head;
  63. return CollectionOpen_Success;
  64. }
  65. void filesystemCollectionCreate(struct FilesystemCollection *collection, const char *dir) {
  66. memset(collection, 0, sizeof *collection);
  67. strncpy(collection->path, dir, sizeof(collection->path) - 1);
  68. for (int i = 0; i < FilesystemCollectionFileSlots; ++i) {
  69. struct FilesystemCollectionFile_ *f = collection->files + i;
  70. aFileReset(&f->file);
  71. f->head.read = filesystemCollectionFile_Read;
  72. f->head.close = filesystemCollectionFile_Close;
  73. }
  74. collection->head.open = filesystemCollectionOpen;
  75. collection->head.close = filesystemCollectionClose;
  76. }