Pak.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /******************************************************************************
  2. Use 'Pak' for archiving multiple data files into one "*.pak" file.
  3. /******************************************************************************/
  4. // PAK
  5. /******************************************************************************/
  6. enum PAK_FILE_FLAG
  7. {
  8. PF_REMOVED =1<<0, // this file is marked as removed, this flag is useful if you're using multiple paks and you want to specify that a file which was in one pak should now no longer exist (for example: having "Data.pak" - base pak of data, "Patch.pak" - pak storing updated files, "Data.pak" has "file.txt", in the "Patch.pak" we want to specify that "file.txt" should no longer exist, to do that, we include a dummy "file.txt" PakFile in the "Patch.pak" with PF_REMOVED enabled, now when loading "Data.pak" followed by "Patch.pak", "file.txt" from "Patch.pak" with PF_REMOVED flag will replace "file.txt" from "Data.pak" making it no longer accessible)
  9. PF_STD_DIR =1<<1, // this file was originally created from a standard directory (not a file)
  10. PF_STD_LINK=1<<2, // this file was originally created from a symbolic link
  11. };
  12. struct PakFile // Single File stored in Pak
  13. {
  14. CChar *name ; // file name (this does not include the path, if you want the full name you need to use 'Pak.fullName')
  15. Byte flag ; // file flags (PAK_FILE_FLAG)
  16. COMPRESS_TYPE compression ; // file compression algorithm
  17. Int parent , // parent index in 'Pak.file', -1=none
  18. children_offset , // offset of children in 'Pak.file' (this is the index of the first child in 'Pak.file' array)
  19. children_num ; // number of children
  20. ULong data_offset ; // offset of data in Pak
  21. UInt data_size , // size of data
  22. data_size_compressed, // size of data after compression (if this file is not compressed, then this member is equal to 'data_size')
  23. data_xxHash64_32 ; // xxHash64_32 of data, this member is set to 0 if PAK_SET_HASH was not enabled during pak creation
  24. DateTime modify_time_utc ; // file modification time (UTC time zone)
  25. FSTD_TYPE type()C {return (flag&PF_STD_DIR) ? FSTD_DIR : (flag&PF_STD_LINK) ? FSTD_LINK : FSTD_FILE;} // get type of the file
  26. #if EE_PRIVATE
  27. PakFile& type (FSTD_TYPE type); // set type
  28. PakFile& reset();
  29. #endif
  30. };
  31. /******************************************************************************/
  32. enum PAK_FLAG // Pak Creation Flags
  33. {
  34. PAK_SHORTEN =1<<0, // when packing only one directory "xxx", files inside it won't be stored in "xxx\*.*" but in root "*.*"
  35. PAK_NO_DATA =1<<1, // store only file names without their data
  36. PAK_NO_FILE =1<<2, // don't create output pak file, but only set Pak class members
  37. PAK_SET_HASH=1<<3, // calculate the hash member for each pak file, if not enabled then the hash will be set to zero (hash calculation requires additional processing and slows down creation of paks)
  38. };
  39. enum PAK_LOAD // Pak Load result
  40. {
  41. PAK_LOAD_NOT_FOUND , // source file was not found
  42. PAK_LOAD_NOT_PAK , // source is not a Pak
  43. PAK_LOAD_UNSUPPORTED_VERSION, // source Pak version is not supported
  44. PAK_LOAD_INCOMPLETE_HEADER , // source has incomplete header
  45. PAK_LOAD_INCOMPLETE_DATA , // source has complete header, however data is incomplete
  46. PAK_LOAD_OK , // Pak loaded OK
  47. };
  48. struct Pak // Set of Pak Files
  49. {
  50. // load
  51. void operator=( C Str &name ); // load pak from file , Exit on fail
  52. Bool load ( C Str &name , const_mem_addr Cipher *cipher=null); // load pak from file , false on fail, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed)
  53. Bool loadMem (const_mem_addr CPtr data, Int size, const_mem_addr Cipher *cipher=null); // load pak from memory, false on fail, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed), 'data' must point to a constant memory address (only pointer is stored through which the data can be later accessed)
  54. PAK_LOAD loadEx(C Str &name, const_mem_addr Cipher *cipher=null, Long pak_offset=0, Long *expected_size=null, Long *actual_size=null); // load pak from file, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed), 'pak_offset'=offset of PAK data inside the file, 'expected_size'=expected size of the PAK file, 'actual_size'=actual size of the PAK file
  55. // get
  56. Int rootFiles( )C {return _root_files ;} // get number of files in root directory, they are stored first in the 'files' array
  57. Int totalFiles( )C {return _files.elms();} // get number of all files
  58. C Mems<PakFile>& files( )C {return _files ;} // get files array
  59. C PakFile & file (Int i)C {return _files[i] ;} // get i-th file
  60. Long totalSize(C PakFile &file, Bool compressed=false )C; // get file total size (size of the file and all of its children), 'compressed'=if return the compressed size 'PakFile.data_size_compressed' instead of 'PakFile.data_size'
  61. Long totalSize( Int i , Bool compressed=false )C; // get i-th file total size (size of the file and all of its children), 'compressed'=if return the compressed size 'PakFile.data_size_compressed' instead of 'PakFile.data_size'
  62. Str fullName (C PakFile &file )C; // get file full name (path + name)
  63. Str fullName ( Int i )C; // get i-th file full name (path + name)
  64. C PakFile* find (CChar *name, Bool include_removed=true)C; // find file from its full name (path + name), 'include_removed'=return also files which are marked as removed (have PF_REMOVED flag enabled), null on fail
  65. C PakFile* find (CChar8 *name, Bool include_removed=true)C; // find file from its full name (path + name), 'include_removed'=return also files which are marked as removed (have PF_REMOVED flag enabled), null on fail
  66. C PakFile* find (C UID &id , Bool include_removed=true)C; // find file from its ID , 'include_removed'=return also files which are marked as removed (have PF_REMOVED flag enabled), null on fail
  67. C Str& pakFileName( )C {return _file_name;} // get name of the file where the Pak is located. If this Pak is stored inside another file, then this method will return the file name of the top most parent
  68. Pak& pakFileName(C Str &name); // manually adjust the Pak file name in case the file was moved
  69. // create from files and save to disk
  70. Bool create(C Str &file , C Str &pak_name=S, UInt flag=PAK_SHORTEN, Cipher *dest_cipher=null, Cipher *src_cipher=null, COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9, Bool (*filter)(C Str &name)=null, Str *error_message=null, PakProgress *progress=null); // create pak, 'file '=single file/directory , 'pak_name'=pak file name to save to, 'flag'=PAK_FLAG , 'compression_level'=0..CompressionLevels(compress) (0=fastest/worst, ..=slowest/best), false on fail, 'filter'=optional pointer to custom callback function which will receive information about encountered files and folders (their name) for which it should return true if the element should be included in the Pak and false if not included (if 'filter' is null then all encountered files/folders will be included), 'error_message'=will contain a message what went wrong upon error, 'progress'=optional parameter allowing to control creation from secondary thread
  71. Bool create(C MemPtr<Str > &files, C Str &pak_name=S, UInt flag=PAK_SHORTEN, Cipher *dest_cipher=null, Cipher *src_cipher=null, COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9, Bool (*filter)(C Str &name)=null, Str *error_message=null, PakProgress *progress=null); // create pak, 'files'=list of file/directories , 'pak_name'=pak file name to save to, 'flag'=PAK_FLAG, all elements listed in 'files' must be located in the same path, 'compression_level'=0..CompressionLevels(compress) (0=fastest/worst, ..=slowest/best), false on fail, 'filter'=optional pointer to custom callback function which will receive information about encountered files and folders (their name) for which it should return true if the element should be included in the Pak and false if not included (if 'filter' is null then all encountered files/folders will be included), 'error_message'=will contain a message what went wrong upon error, 'progress'=optional parameter allowing to control creation from secondary thread
  72. Bool create(C MemPtr<PakNode > &files, C Str &pak_name , UInt flag= 0, Cipher *dest_cipher=null , COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9 , Str *error_message=null, PakProgress *progress=null); // create pak, 'files'=list of file/directory nodes, 'pak_name'=pak file name to save to, 'flag'=PAK_FLAG , 'compression_level'=0..CompressionLevels(compress) (0=fastest/worst, ..=slowest/best), false on fail , 'error_message'=will contain a message what went wrong upon error, 'progress'=optional parameter allowing to control creation from secondary thread
  73. Bool create(C MemPtr<PakFileData> &files, C Str &pak_name , UInt flag= 0, Cipher *dest_cipher=null , COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9 , Str *error_message=null, PakProgress *progress=null); // create pak, 'files'=list of file/directory data , 'pak_name'=pak file name to save to, 'flag'=PAK_FLAG , 'compression_level'=0..CompressionLevels(compress) (0=fastest/worst, ..=slowest/best), false on fail , 'error_message'=will contain a message what went wrong upon error, 'progress'=optional parameter allowing to control creation from secondary thread
  74. #if EE_PRIVATE
  75. Bool create(C Mems<C PakFileData*> &files, C Str &pak_name , UInt flag , Cipher *dest_cipher , COMPRESS_TYPE compress , Int compression_level , Str *error_message=null, PakProgress *progress=null);
  76. #endif
  77. // io
  78. Bool saveHeader(File &f)C; // save pak header (information about files, without their data), false on fail
  79. Pak& del(); // delete manually
  80. ~Pak() {del();}
  81. Pak();
  82. #if !EE_PRIVATE
  83. private:
  84. #endif
  85. UInt _root_files;
  86. ULong _data_offset;
  87. Mems<Byte > _data_decompressed;
  88. Mems<Char > _names;
  89. Mems<PakFile> _files;
  90. Bool _cipher_per_file;
  91. Byte _file_type;
  92. Int _file_cipher_offset;
  93. Cipher *_file_cipher;
  94. Str _file_name;
  95. CPtr _data;
  96. #if EE_PRIVATE
  97. void zero ();
  98. PAK_LOAD loadHeader(File &f, Long *expected_size=null, Long *actual_size=null); // load just the header, access to data will not be available by using this method
  99. PAK_LOAD loadMemEx (const_mem_addr CPtr data, Int size, const_mem_addr Cipher *cipher=null, Long *expected_size=null, Long *actual_size=null); // load pak from memory, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed), 'data' must point to a constant memory address (only pointer is stored through which the data can be later accessed)
  100. #endif
  101. NO_COPY_CONSTRUCTOR(Pak);
  102. };
  103. /******************************************************************************/
  104. // PAK SET
  105. /******************************************************************************/
  106. struct PaksFile // Single file stored in PakSet
  107. {
  108. Pak *pak ; // Pak to which file belongs to
  109. C PakFile *file ; // pointer to pak file
  110. Int children_offset, // offset of children in PakSet.file
  111. children_num ; // number of children
  112. Str fullName()C; // get file full name (path + name)
  113. PaksFile() {Zero(T);}
  114. };
  115. /******************************************************************************/
  116. struct PakSet // set of Pak's combined together with all their PakFile's combined in one database (PakFile's with PF_REMOVED aren't included in PakSet)
  117. {
  118. // get
  119. Int rootFiles( )C {return _root_files ;} // get number of files in root directory, they are stored first in the 'file' array
  120. Int totalFiles( )C {return _files.elms();} // get number of all files
  121. C Memc<PaksFile>& files( )C {return _files ;} // get files array
  122. C PaksFile & file (Int i)C {return _files[i] ;} // get i-th file
  123. Long totalSize(C PaksFile &file, Bool compressed=false)C; // get file total size (size of the file and all of its children), 'compressed'=if return the compressed size 'PakFile.data_size_compressed' instead of 'PakFile.data_size'
  124. Long totalSize( Int i , Bool compressed=false)C; // get i-th file total size (size of the file and all of its children), 'compressed'=if return the compressed size 'PakFile.data_size_compressed' instead of 'PakFile.data_size'
  125. Str fullName(C PaksFile &file )C; // get file full name (path + name)
  126. Str fullName( Int i )C; // get i-th file full name (path + name)
  127. C PaksFile* find (CChar *name )C; // get file from its full name (path + name)
  128. C PaksFile* find (CChar8 *name )C; // get file from its full name (path + name)
  129. C PaksFile* find (C UID &id )C; // get file from its ID
  130. // operations
  131. #if EE_PRIVATE
  132. Bool addTry ( C Str &name, const_mem_addr Cipher *cipher , Bool auto_rebuild, Long pak_offset); // add Pak from file, 'auto_rebuild'=if automatically call the 'rebuild' method, false on fail, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed), 'pak_offset'=offset of PAK data inside the file
  133. #endif
  134. Bool addTry ( C Str &name, const_mem_addr Cipher *cipher=null, Bool auto_rebuild=true); // add Pak from file , 'auto_rebuild'=if automatically call the 'rebuild' method, false on fail, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed)
  135. PakSet& add ( C Str &name, const_mem_addr Cipher *cipher=null, Bool auto_rebuild=true); // add Pak from file , 'auto_rebuild'=if automatically call the 'rebuild' method, Exit on fail, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed)
  136. Bool addMemTry(const_mem_addr CPtr data, Int size, const_mem_addr Cipher *cipher=null, Bool auto_rebuild=true); // add Pak from memory, 'auto_rebuild'=if automatically call the 'rebuild' method, false on fail, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed), 'data' must point to a constant memory address (only pointer is stored through which the data can be later accessed)
  137. PakSet& addMem (const_mem_addr CPtr data, Int size, const_mem_addr Cipher *cipher=null, Bool auto_rebuild=true); // add Pak from memory, 'auto_rebuild'=if automatically call the 'rebuild' method, Exit on fail, 'cipher' must point to object in constant memory address (only pointer is stored through which the object can be later accessed), 'data' must point to a constant memory address (only pointer is stored through which the data can be later accessed)
  138. Bool remove ( C Str &name ); // remove previously added "Pak from file" , true is returned if Pak was found and removed, false if it was not found, this method always calls 'rebuild' upon success
  139. Bool removeMem( CPtr data ); // remove previously added "Pak from memory", true is returned if Pak was found and removed, false if it was not found, this method always calls 'rebuild' upon success
  140. void rebuild ( ); // rebuild pak files database from loaded Pak's, this needs to be called once after adding new Pak's
  141. PakSet& del(); // delete manually
  142. PakSet();
  143. #if !EE_PRIVATE
  144. private:
  145. #endif
  146. struct Src : Pak
  147. {
  148. Str name;
  149. Long pak_offset;
  150. };
  151. UInt _root_files;
  152. SyncLock _lock;
  153. Meml<Src> _paks;
  154. Memc<PaksFile> _files;
  155. }extern
  156. Paks; // this is the global pak set which is automatically used when opening files
  157. /******************************************************************************/
  158. // PAK CREATE
  159. /******************************************************************************/
  160. struct PakProgress // class that can be optionally passed to Pak creation functions to get extra control over that process (for example on one thread you can call Pak create function with this class object as the parameter, then on secondary thread you can access that object and read the 'progress' or enable 'stop' to break pak creation)
  161. {
  162. Bool stop ; // set this to 'true' on secondary thread to break pak creation, default=false
  163. Flt progress; // current progress of pak creation, 0..1, pak creation functions will modify this value according to the progress, default=0
  164. PakProgress& reset() {stop=false; progress=0; return T;} // reset members to initial values
  165. PakProgress() {reset();}
  166. #if EE_PRIVATE
  167. Bool wantStop(Str *error_message=null)C;
  168. #endif
  169. };
  170. /******************************************************************************/
  171. struct DataSource
  172. {
  173. enum TYPE : Byte
  174. {
  175. NONE , // data is empty
  176. NAME , // data comes from a file named 'name' which can be accessed using standard IO functions, such as 'File.read*' and 'FileInfo'
  177. STD , // data comes from a file named 'name' which can be accessed using standard IO functions, such as 'File.readStd*' and 'FileInfoSystem'
  178. FILE , // data comes from a pointer to 'File' object, which should be already opened for reading
  179. PAK_FILE, // data comes from a pointer to 'PakFile' and 'Pak' objects
  180. MEM , // data comes from specified memory address and its size
  181. };
  182. TYPE type;
  183. Str name; // used when "type==NAME || type==STD"
  184. union { struct { File * file; }; // used when "type==FILE"
  185. struct { C PakFile *pak_file; C Pak *pak ; }; // used when "type==PAK_FILE"
  186. struct { CPtr memory; Long memory_size; }; }; // used when "type==MEM"
  187. DataSource& set ( ) {type=NONE ; return T;} // set NONE type
  188. DataSource& set ( C Str & name ) {type=NAME ; T. name= name; return T;} // set NAME type
  189. DataSource& setStd( C Str & name ) {type=STD ; T. name= name; return T;} // set STD type
  190. DataSource& set ( File & file ) {type=FILE ; T. file=& file; return T;} // set FILE type
  191. DataSource& set (C PakFile &pak_file, C Pak &pak ) {type=PAK_FILE; T.pak_file=&pak_file; T.pak =&pak; return T;} // set PAK_FILE type
  192. DataSource& set ( CPtr memory, Long size) {type=MEM ; T. memory= memory; T.memory_size=size; return T;} // set MEM type
  193. File* open (File &temp)C;
  194. #if EE_PRIVATE
  195. File* openRaw (File &temp)C;
  196. #endif
  197. Long size ( )C;
  198. Long sizeCompressed( )C;
  199. Str srcName ( )C;
  200. DataSource() {set();}
  201. };
  202. /******************************************************************************/
  203. enum COMPRESS_MODE : Byte
  204. {
  205. COMPRESS_KEEP_ORIGINAL, // keep compression as from the original source file without making any changes
  206. COMPRESS_DISABLE , // disable any compression (if source is compressed then it's decompressed and left uncompressed)
  207. COMPRESS_ENABLE , // enable compression (if source is compressed then it's decompressed first) file will be compressed as specified in the PAK create/update function
  208. };
  209. struct PakFileData // Pak File Data, used for creating or updating Pak's from custom files
  210. {
  211. enum MODE : Byte
  212. {
  213. REPLACE , // remove any previous information about this file in Pak, include new information about this file specifying that it now exists, with new data taken from 'file' member , use this mode for creating new files or updating previous files
  214. REMOVE , // remove any previous information about this file in Pak, don't include any new information about this file , use this mode for completely removing any information about previous file
  215. MARK_REMOVED, // remove any previous information about this file in Pak, include new information about this file specifying that it is now removed, by enabling PF_REMOVED flag for this file, use this mode for removing previous file and leaving information that it now is removed (see comments for PF_REMOVED flag to get more information)
  216. };
  217. FSTD_TYPE type ; // type of the file, can be set to FSTD_FILE, FSTD_DIR or FSTD_LINK, used only if "mode==REPLACE" or "mode==MARK_REMOVED"
  218. MODE mode ; // mode specifying how this file should be treated (whether it should be replaced, removed completely, or marked as removed)
  219. COMPRESS_MODE compress_mode ; // specify compression mode for this file
  220. COMPRESS_TYPE compressed ; // if source file is already compressed then specify here its compression algorithm, used only if "mode==REPLACE"
  221. Long decompressed_size; // if source file is already compressed then specify here its original decompressed size (otherwise leave to -1), used only if "mode==REPLACE"
  222. Str name ; // target name in the destination Pak (can include folders), for example "Folder/file.ext"
  223. DataSource data ; // file data, used only if "mode==REPLACE"
  224. UInt xxHash64_32 ; // file hash, if you know it already then you can set it manually to save processing time, in other case you can leave it to 0, used only if "mode==REPLACE"
  225. DateTime modify_time_utc ; // file modification time (UTC time zone)
  226. PakFileData() {type=FSTD_FILE; mode=REPLACE; compress_mode=COMPRESS_ENABLE; compressed=COMPRESS_NONE; decompressed_size=-1; xxHash64_32=0; modify_time_utc.zero();}
  227. };
  228. /******************************************************************************/
  229. struct PakNode // Pak File Node, used for creating Pak's from custom files
  230. {
  231. FSTD_TYPE type ; // type of the file, can be set to FSTD_FILE, FSTD_DIR or FSTD_LINK
  232. Bool exists ; // if the file exists, if it's set to false then file will be created with PF_REMOVED flag enabled (see comments for PF_REMOVED flag to get more information)
  233. COMPRESS_MODE compress_mode ; // specify compression mode for this file
  234. COMPRESS_TYPE compressed ; // if source file is already compressed then specify here its compression algorithm
  235. Long decompressed_size; // if source file is already compressed then specify here its original decompressed size (otherwise leave to -1)
  236. Str name ; // target name in the destination Pak, for example "file.ext" (can't include folders, for example can't be "Folder/file.ext")
  237. DataSource data ; // file data
  238. UInt xxHash64_32 ; // file hash, if you know it already then you can set it manually to save processing time, in other case you can leave it to 0
  239. DateTime modify_time_utc ; // file modification time (UTC time zone)
  240. Memb<PakNode> children ; // sub-elements
  241. #if EE_PRIVATE
  242. PakNode& newSetFolder(C Str &name, C DateTime &modify_time_utc) // call this only for objects that were just created (right after constructor called)
  243. {
  244. T.type=FSTD_DIR; T.name=name; T.modify_time_utc=modify_time_utc; return T;
  245. }
  246. PakNode& setRemoved(C Str &name, C DateTime &modify_time_utc, FSTD_TYPE type)
  247. {
  248. T.type=type; T.exists=false; T.compress_mode=COMPRESS_ENABLE; T.compressed=COMPRESS_NONE; T.decompressed_size=-1;
  249. T.name=name; T.data.set(); T.xxHash64_32=0; T.modify_time_utc=modify_time_utc; children.del(); // remove all existing children (they are not needed if this node is marked as removed)
  250. return T;
  251. }
  252. PakNode& set(C Str &name, C PakFileData &pfd)
  253. {
  254. T.type=pfd.type; T.exists=true; T.compress_mode=pfd.compress_mode; T.compressed=pfd.compressed; T.decompressed_size=pfd.decompressed_size;
  255. T.name=name; T.data=pfd.data; T.xxHash64_32=pfd.xxHash64_32; T.modify_time_utc=pfd.modify_time_utc;
  256. return T;
  257. }
  258. #endif
  259. PakNode() {type=FSTD_FILE; exists=true; compress_mode=COMPRESS_ENABLE; compressed=COMPRESS_NONE; decompressed_size=-1; xxHash64_32=0; modify_time_utc.zero();}
  260. };
  261. /******************************************************************************/
  262. // MAIN
  263. /******************************************************************************/
  264. // Create Pak
  265. inline Bool PakCreate(C Str &file , C Str &pak_name=S, UInt flag=PAK_SHORTEN, Cipher *dest_cipher=null, Cipher *src_cipher=null, COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9, Bool (*filter)(C Str &name)=null, Str *error_message=null, PakProgress *progress=null) {return Pak().create(file , pak_name, flag, dest_cipher, src_cipher, compress, compression_level, filter, error_message, progress);}
  266. inline Bool PakCreate(C MemPtr<Str > &files, C Str &pak_name=S, UInt flag=PAK_SHORTEN, Cipher *dest_cipher=null, Cipher *src_cipher=null, COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9, Bool (*filter)(C Str &name)=null, Str *error_message=null, PakProgress *progress=null) {return Pak().create(files, pak_name, flag, dest_cipher, src_cipher, compress, compression_level, filter, error_message, progress);}
  267. inline Bool PakCreate(C MemPtr<PakNode > &files, C Str &pak_name , UInt flag= 0, Cipher *dest_cipher=null , COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9 , Str *error_message=null, PakProgress *progress=null) {return Pak().create(files, pak_name, flag, dest_cipher , compress, compression_level , error_message, progress);}
  268. inline Bool PakCreate(C MemPtr<PakFileData> &files, C Str &pak_name , UInt flag= 0, Cipher *dest_cipher=null , COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9 , Str *error_message=null, PakProgress *progress=null) {return Pak().create(files, pak_name, flag, dest_cipher , compress, compression_level , error_message, progress);}
  269. // Update Pak
  270. Bool PakUpdate(Pak &src_pak, C MemPtr<PakFileData> &update_files, C Str &pak_name, Cipher *dest_cipher=null, COMPRESS_TYPE compress=COMPRESS_NONE, Int compression_level=9, Str *error_message=null, PakProgress *progress=null); // update 'src_pak' by adding 'update_files' and saving the new Pak into 'pak_name', 'compression_level'=0..CompressionLevels(compress) (0=fastest/worst, ..=slowest/best), 'compress'=compression algorithm for the 'update_files' (files from 'src_pak' will preserve their original compression)
  271. // Compare Pak
  272. Bool PakEqual(C MemPtr<PakFileData> &files, C Pak &pak); // if 'files' are the same as the ones in 'pak' (this will verify if all files from 'files' are of the same size and modification time as those from 'pak', warning: folders may get ignored)
  273. Bool PakEqual(C MemPtr<PakFileData> &files, C Str &pak_name, Cipher *pak_cipher=null);
  274. inline Int Elms(C Pak &pak ) {return pak .totalFiles();}
  275. inline Int Elms(C PakSet &paks) {return paks.totalFiles();}
  276. #if EE_PRIVATE
  277. Bool Equal(C PakFile *a , C PakFile *b ); // test if both PakFile's are of the same version
  278. Bool Equal(C PakFileData *pfd, C PakFile *pf); // test if both PakFile's are of the same version
  279. #endif
  280. /******************************************************************************/