================= FS_LoadZipFile Creates a new pak_t in the search chain for the contents of a zip file. ================= */
| 1860 | ================= |
| 1861 | */ |
| 1862 | static pack_t *FS_LoadZipFile( const char *zipfile, const char *basename ) |
| 1863 | { |
| 1864 | fileInPack_t *buildBuffer; |
| 1865 | pack_t *pack; |
| 1866 | unzFile uf; |
| 1867 | int err; |
| 1868 | unz_global_info gi; |
| 1869 | char filename_inzip[MAX_ZPATH]; |
| 1870 | unz_file_info file_info; |
| 1871 | int len; |
| 1872 | size_t i; |
| 1873 | long hash; |
| 1874 | int fs_numHeaderLongs; |
| 1875 | int *fs_headerLongs; |
| 1876 | char *namePtr; |
| 1877 | |
| 1878 | fs_numHeaderLongs = 0; |
| 1879 | |
| 1880 | uf = unzOpen(zipfile); |
| 1881 | err = unzGetGlobalInfo (uf,&gi); |
| 1882 | |
| 1883 | if (err != UNZ_OK) |
| 1884 | return NULL; |
| 1885 | |
| 1886 | len = 0; |
| 1887 | unzGoToFirstFile(uf); |
| 1888 | for (i = 0; i < gi.number_entry; i++) |
| 1889 | { |
| 1890 | err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); |
| 1891 | if (err != UNZ_OK) { |
| 1892 | break; |
| 1893 | } |
| 1894 | len += strlen(filename_inzip) + 1; |
| 1895 | unzGoToNextFile(uf); |
| 1896 | } |
| 1897 | |
| 1898 | buildBuffer = (struct fileInPack_s *)Z_Malloc( (gi.number_entry * sizeof( fileInPack_t )) + len, TAG_FILESYS, qtrue ); |
| 1899 | namePtr = ((char *) buildBuffer) + gi.number_entry * sizeof( fileInPack_t ); |
| 1900 | fs_headerLongs = (int *)Z_Malloc( gi.number_entry * sizeof(int), TAG_FILESYS, qtrue ); |
| 1901 | |
| 1902 | // get the hash table size from the number of files in the zip |
| 1903 | // because lots of custom pk3 files have less than 32 or 64 files |
| 1904 | for (i = 1; i <= MAX_FILEHASH_SIZE; i <<= 1) { |
| 1905 | if (i > gi.number_entry) { |
| 1906 | break; |
| 1907 | } |
| 1908 | } |
| 1909 | |
| 1910 | pack = (pack_t *)Z_Malloc( sizeof( pack_t ) + i * sizeof(fileInPack_t *), TAG_FILESYS, qtrue ); |
| 1911 | pack->hashSize = i; |
| 1912 | pack->hashTable = (fileInPack_t **) (((char *) pack) + sizeof( pack_t )); |
| 1913 | for(int j = 0; j < pack->hashSize; j++) { |
| 1914 | pack->hashTable[j] = NULL; |
| 1915 | } |
| 1916 | |
| 1917 | Q_strncpyz( pack->pakFilename, zipfile, sizeof( pack->pakFilename ) ); |
| 1918 | Q_strncpyz( pack->pakBasename, basename, sizeof( pack->pakBasename ) ); |
| 1919 |
no test coverage detected