wad: Refactor ResFindSignature to work in chunks

kinda mucky but it works
This commit is contained in:
Ash Logan 2022-08-23 12:32:50 +10:00 committed by James R.
parent 8ca2dc77e7
commit dedd0047bd

View file

@ -522,24 +522,49 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
*/ */
static boolean ResFindSignature (FILE* handle, char endPat[], UINT32 startpos) static boolean ResFindSignature (FILE* handle, char endPat[], UINT32 startpos)
{ {
//the Wii U has rather slow filesystem access, and fgetc is *unbearable*
//so I reimplemented this function to buffer 128k chunks
char *s; char *s;
int c; int c;
fseek(handle, 0, SEEK_END);
size_t len = ftell(handle);
fseek(handle, startpos, SEEK_SET); fseek(handle, startpos, SEEK_SET);
size_t remaining = len - startpos;
size_t chunkpos = startpos;
s = endPat; s = endPat;
while((c = fgetc(handle)) != EOF)
{ //128k buffers
if (*s != c && s > endPat) // No match? size_t buffer_size = std::min(128 * 1024 * sizeof(char), remaining);
s = endPat; // We "reset" the counter by sending the s pointer back to the start of the array. char* buffer = static_cast<char*>(malloc(buffer_size));
if (*s == c)
{ size_t bytes_read = 0;
s++; while ((bytes_read = fread(buffer, 1, buffer_size, handle)) > 0) {
if (*s == 0x00) // The array pointer has reached the key char which marks the end. It means we have matched the signature. for (size_t i = 0; i < bytes_read; i++) {
c = (int)buffer[i];
if (*s != c && s > endPat) // No match?
s = endPat; // We "reset" the counter by sending the s pointer back to the start of the array.
if (*s == c)
{ {
return true; s++;
if (*s == 0x00) // The array pointer has reached the key char which marks the end. It means we have matched the signature.
{
//the original function would leave the FILE* seeked to the end of the match
size_t foundpos = chunkpos + i + 1;
fseek(handle, foundpos, SEEK_SET);
free(buffer);
return true;
}
} }
} }
chunkpos += bytes_read;
} }
free(buffer);
return false; return false;
} }