PackFile.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef _PakFile_h_
  2. #define _PakFile_h_
  3. #include "..\..\common_h\FileService.h"
  4. class PackArchivator;
  5. class DataFileMem;
  6. //Пак-файл
  7. class PackFile : public IPackFile
  8. {
  9. private:
  10. /*
  11. Формат пак файла
  12. Header
  13. Element[Header.filesCount]
  14. strings table
  15. data
  16. */
  17. #pragma pack(push, 1)
  18. struct Element
  19. {
  20. const char * name; //Имя файла
  21. dword hash; //Хэшь значение файла
  22. dword len; //Длинна имени файла
  23. const byte * data; //Смещение начала относительно начала данных
  24. dword fileSize; //Реальный размер файла
  25. dword packSize; //Размер файла в паке
  26. Element * next; //Следующий в цепочке хэша
  27. };
  28. struct Header
  29. {
  30. byte id[8]; //Идентификатор
  31. byte version[4]; //Версия
  32. dword filesCount; //Количество файлов
  33. dword entryMask; //Маска входной таблицы
  34. Element * entry[1]; //Входная таблица поиска размера entryMask + 1
  35. };
  36. #pragma pack(pop)
  37. public:
  38. PackFile(const char * path, const char * _cppFileName, long _cppFileLine);
  39. virtual ~PackFile();
  40. //Загрузить файл в память
  41. bool Load(IDataFile * df);
  42. //Увеличить счётчик ссылок
  43. void AddRefCount();
  44. //Закрыть файл сообщив об ошибке
  45. void ErrorRelease();
  46. //Проверить имя пака на совпадение
  47. bool IsThis(const char * _fileName);
  48. #ifndef _XBOX
  49. //Сохранить файлы в паке
  50. static bool SaveToPack(const char * path, PackArchivator & compressor);
  51. #endif
  52. public:
  53. //Удалить объект
  54. virtual void Release();
  55. //Получить количество файлов
  56. virtual dword Count() const;
  57. //Получить путь до файла внутри пака
  58. virtual const char * LocalPath(dword index) const;
  59. //Получить полный путь до файла
  60. virtual const char * FullPath(dword index) const;
  61. //Получить размер пак-файла
  62. virtual dword Size() const;
  63. //Найти в паке файл
  64. const byte * Find(const char * fileName, dword hash, dword len, dword & packedSize, dword & fileSize);
  65. //Добавить все имена файлов
  66. void CollectFiles(array<const char *> & names);
  67. private:
  68. array<byte> data; //Данные пака
  69. long refCounter; //Счётчик пользователей файла
  70. char fileName[256]; //Имя файла без пути
  71. #ifndef STOP_DEBUG
  72. const char * cppFileName; //Исходный файл откуда был открыт пак-файл
  73. long cppFileLine; //Строка исходного файла, откуда был открыт пак-файл
  74. #endif
  75. static const char id[8]; //Идентификатор пак-файлов
  76. static const char ver[4]; //Текущая версия пак-файла
  77. };
  78. //Проверить имя пака на совпадение
  79. __forceinline bool PackFile::IsThis(const char * _fileName)
  80. {
  81. return string::IsEqual(fileName, _fileName);
  82. }
  83. //Найти в паке файл
  84. __forceinline const byte * PackFile::Find(const char * fileName, dword hash, dword len, dword & packedSize, dword & fileSize)
  85. {
  86. Header & hdr = (Header &)data[0];
  87. for(Element * el = hdr.entry[hash & hdr.entryMask]; el; el = el->next)
  88. {
  89. if(el->hash == hash && el->len == len)
  90. {
  91. if(string::IsEqual(el->name, fileName))
  92. {
  93. packedSize = el->packSize;
  94. fileSize = el->fileSize;
  95. return el->data;
  96. }
  97. }
  98. }
  99. return null;
  100. }
  101. #endif