mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-18 14:41:55 +00:00
- removed kplib's compression code.
Its only use in savegames has already been disabled in favor of a format restructuring.
This commit is contained in:
parent
ab28697c18
commit
1d7bfe14dc
3 changed files with 0 additions and 747 deletions
|
@ -213,31 +213,10 @@
|
|||
extern void EDUKE32_ASSERT_NAME(EDUKE32_UNIQUE_SRC_ID)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define longlong(x) x##i64
|
||||
#else
|
||||
# define longlong(x) x##ll
|
||||
#endif
|
||||
|
||||
#ifndef FP_OFF
|
||||
# define FP_OFF(__p) ((uintptr_t)(__p))
|
||||
#endif
|
||||
|
||||
#ifdef UNDERSCORES
|
||||
# define ASMSYM(x) "_" x
|
||||
#else
|
||||
# define ASMSYM(x) x
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus
|
||||
# define STATIC_CAST_OP(t) static_cast<t>
|
||||
# define REINTERPRET_CAST_OP(t) reinterpret_cast<t>
|
||||
#else
|
||||
# define STATIC_CAST_OP(t) (t)
|
||||
# define REINTERPRET_CAST_OP(t) (t)
|
||||
#endif
|
||||
#define STATIC_CAST(t, v) (STATIC_CAST_OP(t)(v))
|
||||
#define REINTERPRET_CAST(t, v) (REINTERPRET_CAST_OP(t)(v))
|
||||
|
||||
#if defined __cplusplus && (__cplusplus >= 201103L || __has_feature(cxx_constexpr) || EDUKE32_MSVC_PREREQ(1900))
|
||||
# define HAVE_CONSTEXPR
|
||||
|
|
|
@ -23,24 +23,6 @@ typedef struct
|
|||
|
||||
extern kzfilestate kzfs;
|
||||
|
||||
//ZIP functions:
|
||||
extern int32_t kzaddstack (const char *);
|
||||
extern void kzuninit ();
|
||||
extern intptr_t kzopen (const char *);
|
||||
extern int32_t kzread (void *, int32_t);
|
||||
extern int32_t kzseek (int32_t, int32_t);
|
||||
|
||||
static inline int32_t kztell(void) { return kzfs.fil ? kzfs.pos : -1; }
|
||||
static inline int32_t kzeof(void) { return kzfs.fil ? kzfs.pos >= kzfs.leng : -1; }
|
||||
static inline int32_t kzfilelength(void) { return kzfs.fil ? kzfs.leng : 0; }
|
||||
static inline int32_t kzgetc(void) { char ch; return kzread(&ch, 1) ? ch : -1; }
|
||||
static inline void kzclose(void) { MAYBE_FCLOSE_AND_NULL(kzfs.fil); }
|
||||
|
||||
extern void kzfindfilestart (const char *); //pass wildcard string
|
||||
extern int32_t kzfindfile (char *); //you alloc buf, returns 1:found,0:~found
|
||||
|
||||
//like stricmp(st0,st1) except: '/' == '\'
|
||||
|
||||
extern uint8_t toupperlookup[256];
|
||||
static inline int32_t filnamcmp(const char *j, const char *i)
|
||||
{
|
||||
|
@ -49,4 +31,3 @@ static inline int32_t filnamcmp(const char *j, const char *i)
|
|||
i++, j++;
|
||||
return *i != '\0' || *j != '\0';
|
||||
}
|
||||
extern int32_t wildmatch(const char *match, const char *wild);
|
||||
|
|
|
@ -546,710 +546,3 @@ static void initpngtables()
|
|||
//============================= KPNGILIB ends ================================
|
||||
|
||||
//==================== External picture interface ends =======================
|
||||
|
||||
//Brute-force case-insensitive, slash-insensitive, * and ? wildcard matcher
|
||||
//Given: string i and string j. string j can have wildcards
|
||||
//Returns: 1:matches, 0:doesn't match
|
||||
|
||||
|
||||
|
||||
int32_t wildmatch(const char *match, const char *wild)
|
||||
{
|
||||
do
|
||||
{
|
||||
int const match_deref = *match, wild_deref = *wild;
|
||||
|
||||
if (match_deref && (toupperlookup[wild_deref] == toupperlookup[match_deref] || wild_deref == '?'))
|
||||
{
|
||||
wild++, match++;
|
||||
continue;
|
||||
}
|
||||
else if ((match_deref|wild_deref) == '\0')
|
||||
return 1;
|
||||
else if (wild_deref == '*')
|
||||
{
|
||||
do { wild++; } while (*wild == '*');
|
||||
int const wild_deref = *wild;
|
||||
do
|
||||
{
|
||||
if (wild_deref == '\0')
|
||||
return 1;
|
||||
while (*match && toupperlookup[*match] != toupperlookup[wild_deref]) match++;
|
||||
if (*match && *(match+1) && toupperlookup[*(match+1)] != toupperlookup[*(wild+1)])
|
||||
{
|
||||
match++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (1);
|
||||
if (toupperlookup[*match] == toupperlookup[wild_deref])
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
//===================== ZIP decompression code begins ========================
|
||||
|
||||
//format: (used by kzaddstack/kzopen to cache file name&start info)
|
||||
//[char zipnam[?]\0]
|
||||
//[next hashindex/-1][next index/-1][zipnam index][fileoffs][fileleng][iscomp][char filnam[?]\0]
|
||||
//[next hashindex/-1][next index/-1][zipnam index][fileoffs][fileleng][iscomp][char filnam[?]\0]
|
||||
//...
|
||||
//[char zipnam[?]\0]
|
||||
//[next hashindex/-1][next index/-1][zipnam index][fileoffs][fileleng][iscomp][char filnam[?]\0]
|
||||
//[next hashindex/-1][next index/-1][zipnam index][fileoffs][fileleng][iscomp][char filnam[?]\0]
|
||||
//...
|
||||
#define KZHASHINITSIZE 8192
|
||||
static char *kzhashbuf = 0;
|
||||
static int32_t kzhashead[256], kzhashpos, kzlastfnam = -1, kzhashsiz, kzdirnamhead = -1;
|
||||
|
||||
static int32_t kzcheckhashsiz(int32_t siz)
|
||||
{
|
||||
if (!kzhashbuf) //Initialize hash table on first call
|
||||
{
|
||||
Bmemset(kzhashead,-1,sizeof(kzhashead));
|
||||
kzhashbuf = (char *)Xmalloc(KZHASHINITSIZE); if (!kzhashbuf) return 0;
|
||||
kzhashpos = 0; kzlastfnam = -1; kzhashsiz = KZHASHINITSIZE; kzdirnamhead = -1;
|
||||
}
|
||||
if (kzhashpos+siz > kzhashsiz) //Make sure string fits in kzhashbuf
|
||||
{
|
||||
int32_t i = kzhashsiz; do { i <<= 1; }
|
||||
while (kzhashpos+siz > i);
|
||||
kzhashbuf = (char *)Xrealloc(kzhashbuf,i); if (!kzhashbuf) return 0;
|
||||
kzhashsiz = i;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int32_t kzcalchash(const char *st)
|
||||
{
|
||||
int32_t i, hashind;
|
||||
|
||||
for (i=0,hashind=0; st[i]; i++)
|
||||
hashind = toupperlookup[st[i]]-((hashind<<1)+hashind);
|
||||
|
||||
return hashind%ARRAY_SIZE(kzhashead);
|
||||
}
|
||||
|
||||
static int32_t kzcheckhash(const char *filnam, char **zipnam, int32_t *fileoffs, int32_t *fileleng, char *iscomp)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if (!kzhashbuf) return 0;
|
||||
if (filnam[0] == '|') filnam++;
|
||||
for (i=kzhashead[kzcalchash(filnam)]; i>=0; i=(B_UNBUF32(&kzhashbuf[i])))
|
||||
if (!filnamcmp(filnam,&kzhashbuf[i+21]))
|
||||
{
|
||||
(*zipnam) = &kzhashbuf[B_UNBUF32(&kzhashbuf[i+8])];
|
||||
(*fileoffs) = B_UNBUF32(&kzhashbuf[i+12]);
|
||||
(*fileleng) = B_UNBUF32(&kzhashbuf[i+16]);
|
||||
(*iscomp) = kzhashbuf[i+20];
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kzuninit()
|
||||
{
|
||||
DO_FREE_AND_NULL(kzhashbuf);
|
||||
kzhashpos = kzhashsiz = 0; kzdirnamhead = -1;
|
||||
}
|
||||
|
||||
//If file found, loads internal directory from ZIP/GRP into memory (hash) to allow faster access later
|
||||
//If file not found, assumes it's a directory and adds it to an internal list
|
||||
int32_t kzaddstack(const char *filnam)
|
||||
{
|
||||
buildvfs_FILE fil;
|
||||
int32_t i, j, k, leng, hashind, zipnamoffs, numfiles;
|
||||
char tempbuf[260+46];
|
||||
|
||||
fil = buildvfs_fopen_read(filnam);
|
||||
if (!fil) //if file not found, assume it's a directory
|
||||
{
|
||||
//Add directory name to internal list (using kzhashbuf for convenience of dynamic allocation)
|
||||
i = strlen(filnam)+5; if (!kzcheckhashsiz(i)) return -1;
|
||||
B_BUF32(&kzhashbuf[kzhashpos], kzdirnamhead); kzdirnamhead = kzhashpos;
|
||||
strcpy(&kzhashbuf[kzhashpos+4],filnam);
|
||||
kzhashpos += i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Write ZIP/GRP filename to hash
|
||||
i = strlen(filnam)+1; if (!kzcheckhashsiz(i)) { buildvfs_fclose(fil); return -1; }
|
||||
strcpy(&kzhashbuf[kzhashpos],filnam);
|
||||
zipnamoffs = kzhashpos; kzhashpos += i;
|
||||
|
||||
buildvfs_fread(&i,4,1,fil);
|
||||
if (i == (int32_t)B_LITTLE32(0x04034b50)) //'PK\3\4' is ZIP file id
|
||||
{
|
||||
buildvfs_fseek_abs(fil,buildvfs_flength(fil)-22);
|
||||
buildvfs_fread(tempbuf,22,1,fil);
|
||||
if (B_UNBUF32(&tempbuf[0]) == B_LITTLE32(0x06054b50)) //Fast way of finding dir info
|
||||
{
|
||||
numfiles = B_LITTLE16(B_UNBUF16(&tempbuf[10]));
|
||||
buildvfs_fseek_abs(fil,B_LITTLE32(B_UNBUF32(&tempbuf[16])));
|
||||
}
|
||||
else //Slow way of finding dir info (used when ZIP has junk at end)
|
||||
{
|
||||
buildvfs_fseek_abs(fil,0); numfiles = 0;
|
||||
while (1)
|
||||
{
|
||||
if (!buildvfs_fread(&j,4,1,fil)) { numfiles = -1; break; }
|
||||
if (j == (int32_t)B_LITTLE32(0x02014b50)) break; //Found central file header :)
|
||||
if (j != (int32_t)B_LITTLE32(0x04034b50)) { numfiles = -1; break; }
|
||||
buildvfs_fread(tempbuf,26,1,fil);
|
||||
buildvfs_fseek_rel(fil,B_LITTLE32(B_UNBUF32(&tempbuf[14])) + B_LITTLE16(B_UNBUF16(&tempbuf[24])) + B_LITTLE16(B_UNBUF16(&tempbuf[22])));
|
||||
numfiles++;
|
||||
}
|
||||
if (numfiles < 0) { buildvfs_fclose(fil); return -1; }
|
||||
buildvfs_fseek_rel(fil,-4);
|
||||
}
|
||||
for (i=0; i<numfiles; i++)
|
||||
{
|
||||
buildvfs_fread(tempbuf,46,1,fil);
|
||||
if (B_UNBUF32(&tempbuf[0]) != B_LITTLE32(0x02014b50)) { buildvfs_fclose(fil); return 0; }
|
||||
|
||||
j = B_LITTLE16(B_UNBUF16(&tempbuf[28])); //filename length
|
||||
buildvfs_fread(&tempbuf[46],j,1,fil);
|
||||
tempbuf[j+46] = 0;
|
||||
|
||||
//Write information into hash
|
||||
j = strlen(&tempbuf[46])+22; if (!kzcheckhashsiz(j)) { buildvfs_fclose(fil); return -1; }
|
||||
hashind = kzcalchash(&tempbuf[46]);
|
||||
B_BUF32(&kzhashbuf[kzhashpos], kzhashead[hashind]);
|
||||
B_BUF32(&kzhashbuf[kzhashpos+4], kzlastfnam);
|
||||
B_BUF32(&kzhashbuf[kzhashpos+8], zipnamoffs);
|
||||
B_BUF32(&kzhashbuf[kzhashpos+12], B_LITTLE32(B_UNBUF32(&tempbuf[42]))); //fileoffs
|
||||
B_BUF32(&kzhashbuf[kzhashpos+16], 0); //fileleng not used for ZIPs (reserve space for simplicity)
|
||||
kzhashbuf[kzhashpos+20] = 1; //iscomp
|
||||
strcpy(&kzhashbuf[kzhashpos+21],&tempbuf[46]);
|
||||
kzhashead[hashind] = kzhashpos; kzlastfnam = kzhashpos; kzhashpos += j;
|
||||
|
||||
j = B_LITTLE16(B_UNBUF16(&tempbuf[30])); //extra field length
|
||||
j += B_LITTLE16(B_UNBUF16(&tempbuf[32])); //file comment length
|
||||
buildvfs_fseek_rel(fil,j);
|
||||
}
|
||||
}
|
||||
else if (i == (int32_t)B_LITTLE32(0x536e654b)) //'KenS' is GRP file id
|
||||
{
|
||||
buildvfs_fread(tempbuf,12,1,fil);
|
||||
if ((B_UNBUF32(&tempbuf[0]) != B_LITTLE32(0x65766c69)) || //'ilve'
|
||||
(B_UNBUF32(&tempbuf[4]) != B_LITTLE32(0x6e616d72))) //'rman'
|
||||
{ buildvfs_fclose(fil); return 0; }
|
||||
numfiles = B_LITTLE32(B_UNBUF32(&tempbuf[8])); k = ((numfiles+1)<<4);
|
||||
for (i=0; i<numfiles; i++,k+=leng)
|
||||
{
|
||||
buildvfs_fread(tempbuf,16,1,fil);
|
||||
leng = B_LITTLE32(B_UNBUF32(&tempbuf[12])); //File length
|
||||
tempbuf[12] = 0;
|
||||
|
||||
//Write information into hash
|
||||
j = strlen(tempbuf)+22; if (!kzcheckhashsiz(j)) { buildvfs_fclose(fil); return -1; }
|
||||
hashind = kzcalchash(tempbuf);
|
||||
B_BUF32(&kzhashbuf[kzhashpos], kzhashead[hashind]);
|
||||
B_BUF32(&kzhashbuf[kzhashpos+4], kzlastfnam);
|
||||
B_BUF32(&kzhashbuf[kzhashpos+8], zipnamoffs);
|
||||
B_BUF32(&kzhashbuf[kzhashpos+12], k); //fileoffs
|
||||
B_BUF32(&kzhashbuf[kzhashpos+16], leng); //fileleng
|
||||
kzhashbuf[kzhashpos+20] = 0; //iscomp
|
||||
strcpy(&kzhashbuf[kzhashpos+21],tempbuf);
|
||||
kzhashead[hashind] = kzhashpos; kzlastfnam = kzhashpos; kzhashpos += j;
|
||||
}
|
||||
}
|
||||
buildvfs_fclose(fil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//this allows the use of kplib.c with a file that is already open
|
||||
void kzsetfil(buildvfs_FILE fil)
|
||||
{
|
||||
kzfs.fil = fil;
|
||||
kzfs.comptyp = 0;
|
||||
kzfs.seek0 = 0;
|
||||
kzfs.leng = buildvfs_flength(fil);
|
||||
kzfs.pos = 0;
|
||||
kzfs.i = 0;
|
||||
}
|
||||
|
||||
intptr_t kzopen(const char *filnam)
|
||||
{
|
||||
buildvfs_FILE fil{};
|
||||
int32_t i, fileoffs, fileleng;
|
||||
char tempbuf[46+260], *zipnam, iscomp;
|
||||
|
||||
//kzfs.fil = 0;
|
||||
if (filnam[0] != '|') //Search standalone file first
|
||||
{
|
||||
kzfs.fil = buildvfs_fopen_read(filnam);
|
||||
if (kzfs.fil)
|
||||
{
|
||||
kzfs.comptyp = 0;
|
||||
kzfs.seek0 = 0;
|
||||
kzfs.leng = buildvfs_flength(fil);
|
||||
kzfs.pos = 0;
|
||||
kzfs.i = 0;
|
||||
return (intptr_t)kzfs.fil;
|
||||
}
|
||||
}
|
||||
if (kzcheckhash(filnam,&zipnam,&fileoffs,&fileleng,&iscomp)) //Then check mounted ZIP/GRP files
|
||||
{
|
||||
fil = buildvfs_fopen_read(zipnam); if (!fil) return 0;
|
||||
buildvfs_fseek_abs(fil,fileoffs);
|
||||
if (!iscomp) //Must be from GRP file
|
||||
{
|
||||
kzfs.fil = fil;
|
||||
kzfs.comptyp = 0;
|
||||
kzfs.seek0 = fileoffs;
|
||||
kzfs.leng = fileleng;
|
||||
kzfs.pos = 0;
|
||||
kzfs.i = 0;
|
||||
return (intptr_t)kzfs.fil;
|
||||
}
|
||||
else
|
||||
{
|
||||
buildvfs_fread(tempbuf,30,1,fil);
|
||||
if (B_UNBUF32(&tempbuf[0]) != B_LITTLE32(0x04034b50)) { buildvfs_fclose(fil); return 0; }
|
||||
buildvfs_fseek_rel(fil,B_LITTLE16(B_UNBUF16(&tempbuf[26]))+B_LITTLE16(B_UNBUF16(&tempbuf[28])));
|
||||
|
||||
kzfs.fil = fil;
|
||||
kzfs.comptyp = B_LITTLE16(B_UNBUF16(&tempbuf[8]));
|
||||
kzfs.seek0 = buildvfs_ftell(fil);
|
||||
kzfs.leng = B_LITTLE32(B_UNBUF32(&tempbuf[22]));
|
||||
kzfs.pos = 0;
|
||||
switch (kzfs.comptyp) //Compression method
|
||||
{
|
||||
case 0: kzfs.i = 0; return (intptr_t)kzfs.fil;
|
||||
case 8:
|
||||
if (!pnginited) { pnginited = 1; initpngtables(); }
|
||||
kzfs.comptell = 0;
|
||||
kzfs.compleng = (int32_t)B_LITTLE32(B_UNBUF32(&tempbuf[18]));
|
||||
|
||||
//WARNING: No file in ZIP can be > 2GB-32K bytes
|
||||
gslidew = 0x7fffffff; //Force reload at beginning
|
||||
|
||||
return (intptr_t)kzfs.fil;
|
||||
default: buildvfs_fclose(kzfs.fil); kzfs.fil = 0; return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Finally, check mounted dirs
|
||||
|
||||
int const namlen = strlen(filnam);
|
||||
|
||||
for (i=kzdirnamhead; i>=0; i=B_UNBUF32(&kzhashbuf[i]))
|
||||
{
|
||||
strcpy(tempbuf,&kzhashbuf[i+4]);
|
||||
uint32_t const j = strlen(tempbuf);
|
||||
if (namlen+1+j >= sizeof(tempbuf)) continue; //don't allow int32_t filenames to buffer overrun
|
||||
if ((j) && (tempbuf[j-1] != '/') && (tempbuf[j-1] != '\\') && (filnam[0] != '/') && (filnam[0] != '\\'))
|
||||
#if defined(_WIN32)
|
||||
strcat(tempbuf,"\\");
|
||||
#else
|
||||
strcat(tempbuf,"/");
|
||||
#endif
|
||||
strcat(tempbuf,filnam);
|
||||
kzfs.fil = buildvfs_fopen_read(tempbuf);
|
||||
if (kzfs.fil)
|
||||
{
|
||||
kzfs.comptyp = 0;
|
||||
kzfs.seek0 = 0;
|
||||
kzfs.leng = buildvfs_flength(fil);
|
||||
kzfs.pos = 0;
|
||||
kzfs.i = 0;
|
||||
return (intptr_t)kzfs.fil;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef USE_PHYSFS
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#if defined(_WIN32)
|
||||
static HANDLE hfind = INVALID_HANDLE_VALUE;
|
||||
static WIN32_FIND_DATAA findata;
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#define MAX_PATH 260
|
||||
static DIR *hfind = NULL;
|
||||
static struct dirent *findata = NULL;
|
||||
#endif
|
||||
|
||||
//File find state variables. Example sequence (read top->bot, left->right):
|
||||
// srchstat srchzoff srchdoff
|
||||
// 0,1,2,3
|
||||
// 500,200,-1
|
||||
// 4 300
|
||||
// 0,1,2,3,4 100
|
||||
// 0,1,2,3,4 -1
|
||||
static int32_t srchstat = -1, srchzoff = 0, srchdoff = -1, wildstpathleng;
|
||||
static char wildst[MAX_PATH] = "", newildst[MAX_PATH] = "";
|
||||
|
||||
void kzfindfilestart(const char *st)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (hfind != INVALID_HANDLE_VALUE)
|
||||
{ FindClose(hfind); hfind = INVALID_HANDLE_VALUE; }
|
||||
#else
|
||||
if (hfind) { closedir(hfind); hfind = NULL; }
|
||||
#endif
|
||||
strcpy(wildst,st); strcpy(newildst,st);
|
||||
srchstat = 0; srchzoff = kzlastfnam; srchdoff = kzdirnamhead;
|
||||
}
|
||||
|
||||
int32_t kzfindfile(char *filnam)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
kzfindfile_beg:;
|
||||
filnam[0] = 0;
|
||||
if (srchstat == 0)
|
||||
{
|
||||
if (!newildst[0]) { srchstat = -1; return 0; }
|
||||
do
|
||||
{
|
||||
srchstat = 1;
|
||||
|
||||
//Extract directory from wildcard string for pre-pending
|
||||
wildstpathleng = 0;
|
||||
for (i=0; newildst[i]; i++)
|
||||
if ((newildst[i] == '/') || (newildst[i] == '\\'))
|
||||
wildstpathleng = i+1;
|
||||
|
||||
Bmemcpy(filnam,newildst,wildstpathleng);
|
||||
|
||||
#if defined(_WIN32)
|
||||
hfind = FindFirstFileA(newildst,&findata);
|
||||
if (hfind == INVALID_HANDLE_VALUE)
|
||||
{ if (!kzhashbuf) return 0; srchstat = 2; continue; }
|
||||
if (findata.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) continue;
|
||||
i = wildstpathleng;
|
||||
if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
|
||||
if ((findata.cFileName[0] == '.') && (!findata.cFileName[1])) continue;
|
||||
strcpy(&filnam[i],findata.cFileName);
|
||||
if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) strcat(&filnam[i],"\\");
|
||||
#else
|
||||
if (!hfind)
|
||||
{
|
||||
char const *s = ".";
|
||||
if (wildstpathleng > 0)
|
||||
{
|
||||
filnam[wildstpathleng] = 0;
|
||||
s = filnam;
|
||||
}
|
||||
hfind = opendir(s);
|
||||
if (!hfind) { if (!kzhashbuf) return 0; srchstat = 2; continue; }
|
||||
}
|
||||
break; // process srchstat == 1
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
while (0);
|
||||
}
|
||||
if (srchstat == 1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
Bmemcpy(filnam,newildst,wildstpathleng);
|
||||
#if defined(_WIN32)
|
||||
if (!FindNextFileA(hfind,&findata))
|
||||
{ FindClose(hfind); hfind = INVALID_HANDLE_VALUE; if (!kzhashbuf) return 0; srchstat = 2; break; }
|
||||
if (findata.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) continue;
|
||||
i = wildstpathleng;
|
||||
if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
|
||||
if ((findata.cFileName[0] == '.') && (!findata.cFileName[1])) continue;
|
||||
strcpy(&filnam[i],findata.cFileName);
|
||||
if (findata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) strcat(&filnam[i],"\\");
|
||||
#else
|
||||
if ((findata = readdir(hfind)) == NULL)
|
||||
{ closedir(hfind); hfind = NULL; if (!kzhashbuf) return 0; srchstat = 2; break; }
|
||||
i = wildstpathleng;
|
||||
if (findata->d_type == DT_DIR)
|
||||
{ if (findata->d_name[0] == '.' && !findata->d_name[1]) continue; } //skip .
|
||||
else if ((findata->d_type == DT_REG) || (findata->d_type == DT_LNK))
|
||||
{ if (findata->d_name[0] == '.') continue; } //skip hidden (dot) files
|
||||
else continue; //skip devices and fifos and such
|
||||
if (!wildmatch(findata->d_name,&newildst[wildstpathleng])) continue;
|
||||
strcpy(&filnam[i],findata->d_name);
|
||||
if (findata->d_type == DT_DIR) strcat(&filnam[i],"/");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
while (srchstat == 2)
|
||||
{
|
||||
if (srchzoff < 0) { srchstat = 3; break; }
|
||||
if (wildmatch(&kzhashbuf[srchzoff+21],newildst))
|
||||
{
|
||||
//strcpy(filnam,&kzhashbuf[srchzoff+21]);
|
||||
filnam[0] = '|'; strcpy(&filnam[1],&kzhashbuf[srchzoff+21]);
|
||||
srchzoff = B_UNBUF32(&kzhashbuf[srchzoff+4]);
|
||||
return 1;
|
||||
}
|
||||
srchzoff = B_UNBUF32(&kzhashbuf[srchzoff+4]);
|
||||
}
|
||||
while (srchstat == 3)
|
||||
{
|
||||
if (srchdoff < 0) { srchstat = -1; break; }
|
||||
strcpy(newildst,&kzhashbuf[srchdoff+4]);
|
||||
i = strlen(newildst);
|
||||
if ((i) && (newildst[i-1] != '/') && (newildst[i-1] != '\\') && (filnam[0] != '/') && (filnam[0] != '\\'))
|
||||
#if defined(_WIN32)
|
||||
strcat(newildst,"\\");
|
||||
#else
|
||||
strcat(newildst,"/");
|
||||
#endif
|
||||
strcat(newildst,wildst);
|
||||
srchdoff = B_UNBUF32(&kzhashbuf[srchdoff]);
|
||||
srchstat = 0; goto kzfindfile_beg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//File searching code (supports inside ZIP files!) How to use this code:
|
||||
// char filnam[MAX_PATH];
|
||||
// kzfindfilestart("vxl/*.vxl");
|
||||
// while (kzfindfile(filnam)) puts(filnam);
|
||||
//NOTES:
|
||||
// * Directory names end with '\' or '/' (depending on system)
|
||||
// * Files inside zip begin with '|'
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
static char *gzbufptr;
|
||||
static void putbuf4zip(const uint8_t *buf, int32_t uncomp0, int32_t uncomp1)
|
||||
{
|
||||
int32_t i0, i1;
|
||||
// uncomp0 ... uncomp1
|
||||
// &gzbufptr[kzfs.pos] ... &gzbufptr[kzfs.endpos];
|
||||
i0 = max(uncomp0,kzfs.pos);
|
||||
i1 = min(uncomp1,kzfs.endpos);
|
||||
if (i0 < i1) Bmemcpy(&gzbufptr[i0],&buf[i0-uncomp0],i1-i0);
|
||||
}
|
||||
|
||||
//returns number of bytes copied
|
||||
int32_t kzread(void *buffer, int32_t leng)
|
||||
{
|
||||
int32_t i, j, k, bfinal, btype, hlit, hdist;
|
||||
|
||||
if ((!kzfs.fil) || (leng <= 0)) return 0;
|
||||
|
||||
if (kzfs.comptyp == 0)
|
||||
{
|
||||
if (kzfs.pos != kzfs.i) //Seek only when position changes
|
||||
{ buildvfs_fseek_abs(kzfs.fil,kzfs.seek0+kzfs.pos); kzfs.i = kzfs.pos; }
|
||||
i = min(kzfs.leng-kzfs.pos,leng);
|
||||
buildvfs_fread(buffer,i,1,kzfs.fil);
|
||||
kzfs.i += i; //kzfs.i is a local copy of buildvfs_ftell(kzfs.fil);
|
||||
}
|
||||
else if (kzfs.comptyp == 8)
|
||||
{
|
||||
zipfilmode = 1;
|
||||
|
||||
//Initialize for putbuf4zip
|
||||
gzbufptr = (char *)buffer; gzbufptr = &gzbufptr[-kzfs.pos];
|
||||
kzfs.endpos = min(kzfs.pos+leng,kzfs.leng);
|
||||
if (kzfs.endpos == kzfs.pos) return 0; //Guard against reading 0 length
|
||||
|
||||
if (kzfs.pos < gslidew-32768) // Must go back to start :(
|
||||
{
|
||||
if (kzfs.comptell) buildvfs_fseek_abs(kzfs.fil,kzfs.seek0);
|
||||
|
||||
gslidew = 0; gslider = 16384;
|
||||
kzfs.jmpplc = 0;
|
||||
|
||||
//Initialize for suckbits/peekbits/getbits
|
||||
kzfs.comptell = min<int32_t>(kzfs.compleng,sizeof(olinbuf));
|
||||
buildvfs_fread(&olinbuf[0],kzfs.comptell,1,kzfs.fil);
|
||||
//Make it re-load when there are < 32 bits left in FIFO
|
||||
bitpos = -(((int32_t)sizeof(olinbuf)-4)<<3);
|
||||
//Identity: filptr + (bitpos>>3) = &olinbuf[0]
|
||||
filptr = &olinbuf[-(bitpos>>3)];
|
||||
}
|
||||
else
|
||||
{
|
||||
i = max(gslidew-32768,0); j = gslider-16384;
|
||||
|
||||
//HACK: Don't unzip anything until you have to...
|
||||
// (keeps file pointer as low as possible)
|
||||
if (kzfs.endpos <= gslidew) j = kzfs.endpos;
|
||||
|
||||
//write uncompoffs on slidebuf from: i to j
|
||||
if (!((i^j)&32768))
|
||||
putbuf4zip(&slidebuf[i&32767],i,j);
|
||||
else
|
||||
{
|
||||
putbuf4zip(&slidebuf[i&32767],i,j&~32767);
|
||||
putbuf4zip(slidebuf,j&~32767,j);
|
||||
}
|
||||
|
||||
//HACK: Don't unzip anything until you have to...
|
||||
// (keeps file pointer as low as possible)
|
||||
if (kzfs.endpos <= gslidew) goto retkzread;
|
||||
}
|
||||
|
||||
switch (kzfs.jmpplc)
|
||||
{
|
||||
case 0: goto kzreadplc0;
|
||||
case 1: goto kzreadplc1;
|
||||
case 2: goto kzreadplc2;
|
||||
case 3: goto kzreadplc3;
|
||||
}
|
||||
kzreadplc0:;
|
||||
do
|
||||
{
|
||||
bfinal = getbits(1); btype = getbits(2);
|
||||
|
||||
#if 0
|
||||
//Display Huffman block offsets&lengths of input file - for debugging only!
|
||||
{
|
||||
static int32_t ouncomppos = 0, ocomppos = 0;
|
||||
if (kzfs.comptell == sizeof(olinbuf)) i = 0;
|
||||
else if (kzfs.comptell < kzfs.compleng) i = kzfs.comptell-(sizeof(olinbuf)-4);
|
||||
else i = kzfs.comptell-(kzfs.comptell%(sizeof(olinbuf)-4));
|
||||
i += ((int32_t)&filptr[bitpos>>3])-((int32_t)(&olinbuf[0]));
|
||||
i = (i<<3)+(bitpos&7)-3;
|
||||
if (gslidew) printf(" ULng:0x%08x CLng:0x%08x.%x",gslidew-ouncomppos,(i-ocomppos)>>3,((i-ocomppos)&7)<<1);
|
||||
printf("\ntype:%d, Uoff:0x%08x Coff:0x%08x.%x",btype,gslidew,i>>3,(i&7)<<1);
|
||||
if (bfinal)
|
||||
{
|
||||
printf(" ULng:0x%08x CLng:0x%08x.%x",kzfs.leng-gslidew,((kzfs.compleng<<3)-i)>>3,(((kzfs.compleng<<3)-i)&7)<<1);
|
||||
printf("\n Uoff:0x%08x Coff:0x%08x.0",kzfs.leng,kzfs.compleng);
|
||||
ouncomppos = ocomppos = 0;
|
||||
}
|
||||
else { ouncomppos = gslidew; ocomppos = i; }
|
||||
}
|
||||
#endif
|
||||
|
||||
if (btype == 0)
|
||||
{
|
||||
//Raw (uncompressed)
|
||||
suckbits((-bitpos)&7); //Synchronize to start of next byte
|
||||
i = getbits(16); if ((getbits(16)^i) != 0xffff) return -1;
|
||||
for (; i; i--)
|
||||
{
|
||||
if (gslidew >= gslider)
|
||||
{
|
||||
putbuf4zip(&slidebuf[(gslider-16384)&32767],gslider-16384,gslider); gslider += 16384;
|
||||
if (gslider-16384 >= kzfs.endpos)
|
||||
{
|
||||
kzfs.jmpplc = 1; kzfs.i = i; kzfs.bfinal = bfinal;
|
||||
goto retkzread;
|
||||
kzreadplc1:; i = kzfs.i; bfinal = kzfs.bfinal;
|
||||
}
|
||||
}
|
||||
slidebuf[(gslidew++)&32767] = (uint8_t)getbits(8);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (btype == 3) continue;
|
||||
|
||||
if (btype == 1) //Fixed Huffman
|
||||
{
|
||||
hlit = 288; hdist = 32; i = 0;
|
||||
for (; i<144; i++) clen[i] = 8; //Fixed bit sizes (literals)
|
||||
for (; i<256; i++) clen[i] = 9; //Fixed bit sizes (literals)
|
||||
for (; i<280; i++) clen[i] = 7; //Fixed bit sizes (EOI,lengths)
|
||||
for (; i<288; i++) clen[i] = 8; //Fixed bit sizes (lengths)
|
||||
for (; i<320; i++) clen[i] = 5; //Fixed bit sizes (distances)
|
||||
}
|
||||
else //Dynamic Huffman
|
||||
{
|
||||
hlit = getbits(5)+257; hdist = getbits(5)+1; j = getbits(4)+4;
|
||||
for (i=0; i<j; i++) cclen[ccind[i]] = getbits(3);
|
||||
for (; i<19; i++) cclen[ccind[i]] = 0;
|
||||
hufgencode(cclen,19,ibuf0,nbuf0);
|
||||
|
||||
j = 0; k = hlit+hdist;
|
||||
while (j < k)
|
||||
{
|
||||
i = hufgetsym(ibuf0,nbuf0);
|
||||
if (i < 16) { clen[j++] = i; continue; }
|
||||
if (i == 16)
|
||||
{ for (i=getbits(2)+3; i; i--) { clen[j] = clen[j-1]; j++; } }
|
||||
else
|
||||
{
|
||||
if (i == 17) i = getbits(3)+3; else i = getbits(7)+11;
|
||||
for (; i; i--) clen[j++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hufgencode(clen,hlit,ibuf0,nbuf0);
|
||||
qhufgencode(ibuf0,nbuf0,qhufval0,qhufbit0,LOGQHUFSIZ0);
|
||||
|
||||
hufgencode(&clen[hlit],hdist,ibuf1,nbuf1);
|
||||
qhufgencode(ibuf1,nbuf1,qhufval1,qhufbit1,LOGQHUFSIZ1);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (gslidew >= gslider)
|
||||
{
|
||||
putbuf4zip(&slidebuf[(gslider-16384)&32767],gslider-16384,gslider); gslider += 16384;
|
||||
if (gslider-16384 >= kzfs.endpos)
|
||||
{
|
||||
kzfs.jmpplc = 2; kzfs.bfinal = bfinal; goto retkzread;
|
||||
kzreadplc2:; bfinal = kzfs.bfinal;
|
||||
}
|
||||
}
|
||||
|
||||
k = peekbits(LOGQHUFSIZ0);
|
||||
if (qhufbit0[k]) { i = qhufval0[k]; suckbits((int32_t)qhufbit0[k]); }
|
||||
else i = hufgetsym(ibuf0,nbuf0);
|
||||
|
||||
if (i < 256) { slidebuf[(gslidew++)&32767] = (uint8_t)i; continue; }
|
||||
if (i == 256) break;
|
||||
i = getbits(hxbit[i+30-257][0]) + hxbit[i+30-257][1];
|
||||
|
||||
k = peekbits(LOGQHUFSIZ1);
|
||||
if (qhufbit1[k]) { j = qhufval1[k]; suckbits((int32_t)qhufbit1[k]); }
|
||||
else j = hufgetsym(ibuf1,nbuf1);
|
||||
|
||||
j = getbits(hxbit[j][0]) + hxbit[j][1];
|
||||
for (; i; i--,gslidew++) slidebuf[gslidew&32767] = slidebuf[(gslidew-j)&32767];
|
||||
}
|
||||
}
|
||||
while (!bfinal);
|
||||
|
||||
gslider -= 16384;
|
||||
if (!((gslider^gslidew)&32768))
|
||||
putbuf4zip(&slidebuf[gslider&32767],gslider,gslidew);
|
||||
else
|
||||
{
|
||||
putbuf4zip(&slidebuf[gslider&32767],gslider,gslidew&~32767);
|
||||
putbuf4zip(slidebuf,gslidew&~32767,gslidew);
|
||||
}
|
||||
kzreadplc3:; kzfs.jmpplc = 3;
|
||||
}
|
||||
|
||||
retkzread:;
|
||||
i = kzfs.pos;
|
||||
kzfs.pos += leng; if (kzfs.pos > kzfs.leng) kzfs.pos = kzfs.leng;
|
||||
return kzfs.pos-i;
|
||||
}
|
||||
|
||||
//WARNING: kzseek(<-32768,SEEK_CUR); or:
|
||||
// kzseek(0,SEEK_END); can make next kzread very slow!!!
|
||||
int32_t kzseek(int32_t offset, int32_t whence)
|
||||
{
|
||||
if (!kzfs.fil) return -1;
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_CUR: kzfs.pos += offset; break;
|
||||
case SEEK_END: kzfs.pos = kzfs.leng+offset; break;
|
||||
case SEEK_SET: default: kzfs.pos = offset;
|
||||
}
|
||||
if (kzfs.pos < 0) kzfs.pos = 0;
|
||||
if (kzfs.pos > kzfs.leng) kzfs.pos = kzfs.leng;
|
||||
return kzfs.pos;
|
||||
}
|
||||
|
||||
//====================== ZIP decompression code ends =========================
|
||||
|
|
Loading…
Reference in a new issue