static int hog_open(const char *filename, int forWriting, void **fh, PHYSFS_uint32 *count) { PHYSFS_uint8 buf[13]; PHYSFS_uint32 size; PHYSFS_sint64 pos; *count = 0; *fh = NULL; BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0); *fh = __PHYSFS_platformOpenRead(filename); BAIL_IF_MACRO(*fh == NULL, NULL, 0); if (__PHYSFS_platformRead(*fh, buf, 3, 1) != 1) goto openHog_failed; if (memcmp(buf, "DHF", 3) != 0) { __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE); goto openHog_failed; } /* if */ while( 1 ) { if (__PHYSFS_platformRead(*fh, buf, 13, 1) != 1) break; //eof here is ok if (__PHYSFS_platformRead(*fh, &size, 4, 1) != 1) goto openHog_failed; size = PHYSFS_swapULE32(size); (*count)++; // Skip over entry pos = __PHYSFS_platformTell(*fh); if (pos == -1) goto openHog_failed; if (!__PHYSFS_platformSeek(*fh, pos + size)) goto openHog_failed; } // Rewind to start of entries if (!__PHYSFS_platformSeek(*fh, 3)) goto openHog_failed; return(1); openHog_failed: if (*fh != NULL) __PHYSFS_platformClose(*fh); *count = -1; *fh = NULL; return(0); } /* hog_open */
static int ZIP_seek(fvoid *opaque, PHYSFS_uint64 offset) { ZIPfileinfo *finfo = (ZIPfileinfo *) opaque; ZIPentry *entry = finfo->entry; void *in = finfo->handle; BAIL_IF_MACRO(offset > entry->uncompressed_size, ERR_PAST_EOF, 0); if (entry->compression_method == COMPMETH_NONE) { PHYSFS_sint64 newpos = offset + entry->offset; BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0); finfo->uncompressed_position = (PHYSFS_uint32) offset; } /* if */ else { /* * If seeking backwards, we need to redecode the file * from the start and throw away the compressed bits until we hit * the offset we need. If seeking forward, we still need to * decode, but we don't rewind first. */ if (offset < finfo->uncompressed_position) { /* we do a copy so state is sane if inflateInit2() fails. */ z_stream str; initializeZStream(&str); if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK) return(0); if (!__PHYSFS_platformSeek(in, entry->offset)) return(0); inflateEnd(&finfo->stream); memcpy(&finfo->stream, &str, sizeof (z_stream)); finfo->uncompressed_position = finfo->compressed_position = 0; } /* if */ while (finfo->uncompressed_position != offset) { PHYSFS_uint8 buf[512]; PHYSFS_uint32 maxread; maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position); if (maxread > sizeof (buf)) maxread = sizeof (buf); if (ZIP_read(finfo, buf, maxread, 1) != 1) return(0); } /* while */ } /* else */ return(1); } /* ZIP_seek */
static int HHA_seek(fvoid *opaque, PHYSFS_uint64 offset) { HHAfileinfo *finfo = (HHAfileinfo *) opaque; HHAentry *entry = finfo->entry; void *in = finfo->handle; BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0); BAIL_IF_MACRO(offset >= entry->uncompressed_size, ERR_PAST_EOF, 0); if (entry->compress == HHA_COMPRESS_NONE) { PHYSFS_sint64 newpos = offset + entry->offset; BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0); finfo->uncompressed_position = (PHYSFS_uint32) offset; } else if (entry->compress == HHA_COMPRESS_ZLIB) { /* * If seeking backwards, we need to redecode the file * from the start and throw away the compressed bits until we hit * the offset we need. If seeking forward, we still need to * decode, but we don't rewind first. */ if (offset < finfo->uncompressed_position) { /* we do a copy so state is sane if inflateInit2() fails. */ z_stream str; initializeZStream(&str); if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK) return(0); if (!__PHYSFS_platformSeek(in, entry->offset)) return(0); inflateEnd(&finfo->zlib_stream); memcpy(&finfo->zlib_stream, &str, sizeof (z_stream)); finfo->uncompressed_position = finfo->compressed_position = 0; } /* if */ while (finfo->uncompressed_position != offset) { PHYSFS_uint8 buf[512]; PHYSFS_uint32 maxread; maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position); if (maxread > sizeof (buf)) maxread = sizeof (buf); if (HHA_read(finfo, buf, maxread, 1) != 1) return(0); } /* while */ } /* else */ else printf("LZMA file: %s/%s\n", entry->dir, entry->name); return(1); } /* HHA_seek */
static fvoid *WAD_openRead(dvoid *opaque, const char *fnm, int *fileExists) { WADinfo *info = ((WADinfo *) opaque); WADfileinfo *finfo; WADentry *entry; entry = wad_find_entry(info, fnm); *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, NULL, NULL); finfo = (WADfileinfo *) allocator.Malloc(sizeof (WADfileinfo)); BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL); finfo->handle = __PHYSFS_platformOpenRead(info->filename); if ( (finfo->handle == NULL) || (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) ) { allocator.Free(finfo); return NULL; } /* if */ finfo->curPos = 0; finfo->entry = entry; return finfo; } /* WAD_openRead */
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) { CFileInStream *s = (CFileInStream *) object; if (__PHYSFS_platformSeek(s->File, (PHYSFS_uint64) pos)) return SZ_OK; return SZE_FAIL; } /* SzFileSeekImp */
static int wad_load_entries(const char *name, int forWriting, WADinfo *info) { void *fh = NULL; PHYSFS_uint32 fileCount; PHYSFS_uint32 directoryOffset; WADentry *entry; char lastDirectory[9]; lastDirectory[8] = 0; /* Make sure lastDirectory stays null-terminated. */ BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0); info->entryCount = fileCount; info->entries = (WADentry *) allocator.Malloc(sizeof(WADentry)*fileCount); if (info->entries == NULL) { __PHYSFS_platformClose(fh); BAIL_MACRO(ERR_OUT_OF_MEMORY, 0); } /* if */ __PHYSFS_platformSeek(fh,directoryOffset); for (entry = info->entries; fileCount > 0; fileCount--, entry++) { if (__PHYSFS_platformRead(fh, &entry->startPos, 4, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ if (__PHYSFS_platformRead(fh, &entry->name, 8, 1) != 1) { __PHYSFS_platformClose(fh); return 0; } /* if */ entry->name[8] = '\0'; /* name might not be null-terminated in file. */ entry->size = PHYSFS_swapULE32(entry->size); entry->startPos = PHYSFS_swapULE32(entry->startPos); } /* for */ __PHYSFS_platformClose(fh); __PHYSFS_sort(info->entries, info->entryCount, wad_entry_cmp, wad_entry_swap); return 1; } /* wad_load_entries */
static int hog_load_entries(const char *name, int forWriting, HOGinfo *info) { void *fh = NULL; PHYSFS_uint32 fileCount; HOGentry *entry; BAIL_IF_MACRO(!hog_open(name, forWriting, &fh, &fileCount), NULL, 0); info->entryCount = fileCount; info->entries = (HOGentry *) malloc(sizeof (HOGentry) * fileCount); if (info->entries == NULL) { __PHYSFS_platformClose(fh); BAIL_MACRO(ERR_OUT_OF_MEMORY, 0); } /* if */ for (entry = info->entries; fileCount > 0; fileCount--, entry++) { if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1) { __PHYSFS_platformClose(fh); return(0); } /* if */ if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1) { __PHYSFS_platformClose(fh); return(0); } /* if */ entry->size = PHYSFS_swapULE32(entry->size); entry->startPos = __PHYSFS_platformTell(fh); if (entry->startPos == -1) { __PHYSFS_platformClose(fh); return(0); } // Skip over entry if (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size)) { __PHYSFS_platformClose(fh); return(0); } } /* for */ __PHYSFS_platformClose(fh); __PHYSFS_sort(info->entries, info->entryCount, hog_entry_cmp, hog_entry_swap); return(1); } /* hog_load_entries */
static int HOG_seek(FileHandle *handle, PHYSFS_uint64 offset) { HOGfileinfo *finfo = (HOGfileinfo *) (handle->opaque); HOGentry *entry = finfo->entry; int rc; BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0); BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0); rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset); if (rc) finfo->curPos = (PHYSFS_uint32) offset; return(rc); } /* HOG_seek */
static int WAD_seek(fvoid *opaque, PHYSFS_uint64 offset) { WADfileinfo *finfo = (WADfileinfo *) opaque; WADentry *entry = finfo->entry; int rc; BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0); BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0); rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset); if (rc) finfo->curPos = (PHYSFS_uint32) offset; return rc; } /* WAD_seek */
static fvoid *HHA_openRead(dvoid *opaque, const char *fnm, int *fileExists) { HHAinfo *info = (HHAinfo *) opaque; HHAfileinfo *finfo; HHAentry *entry; entry = HHA_find_entry(info, fnm); *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, NULL, NULL); finfo = (HHAfileinfo *) allocator.Malloc(sizeof (HHAfileinfo)); BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL); memset(finfo, '\0', sizeof (HHAfileinfo)); finfo->handle = __PHYSFS_platformOpenRead(info->filename); if ( (finfo->handle == NULL) || (!__PHYSFS_platformSeek(finfo->handle, entry->offset)) ) { allocator.Free(finfo); return(NULL); } /* if */ finfo->entry = entry; if (finfo->entry->compress == HHA_COMPRESS_ZLIB) { initializeZStream(&finfo->zlib_stream); if (zlib_err(inflateInit2(&finfo->zlib_stream, -MAX_WBITS)) != Z_OK) { HHA_fileClose(finfo); return(NULL); } /* if */ finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE); if (finfo->buffer == NULL) { HHA_fileClose(finfo); BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); } /* if */ } /* if */ return(finfo); } /* HHA_openRead */
static FileHandle *HOG_openRead(DirHandle *h, const char *fnm, int *fileExists) { HOGinfo *info = ((HOGinfo *) h->opaque); FileHandle *retval; HOGfileinfo *finfo; HOGentry *entry; entry = hog_find_entry(info, fnm); *fileExists = (entry != NULL); BAIL_IF_MACRO(entry == NULL, NULL, NULL); retval = (FileHandle *) malloc(sizeof (FileHandle)); BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); finfo = (HOGfileinfo *) malloc(sizeof (HOGfileinfo)); if (finfo == NULL) { free(retval); BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); } /* if */ finfo->handle = __PHYSFS_platformOpenRead(info->filename); if ( (finfo->handle == NULL) || (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) ) { free(finfo); free(retval); return(NULL); } /* if */ finfo->curPos = 0; finfo->entry = entry; retval->opaque = (void *) finfo; retval->funcs = &__PHYSFS_FileFunctions_HOG; retval->dirHandle = h; return(retval); } /* HOG_openRead */
static PHYSFS_sint64 zip_find_end_of_central_dir(void *in, PHYSFS_sint64 *len) { PHYSFS_uint8 buf[256]; PHYSFS_sint32 i = 0; PHYSFS_sint64 filelen; PHYSFS_sint64 filepos; PHYSFS_sint32 maxread; PHYSFS_sint32 totalread = 0; int found = 0; PHYSFS_uint32 extra = 0; filelen = __PHYSFS_platformFileLength(in); BAIL_IF_MACRO(filelen == -1, NULL, 0); /* !!! FIXME: unlocalized string */ BAIL_IF_MACRO(filelen > 0xFFFFFFFF, "ZIP bigger than 2 gigs?!", 0); /* * Jump to the end of the file and start reading backwards. * The last thing in the file is the zipfile comment, which is variable * length, and the field that specifies its size is before it in the * file (argh!)...this means that we need to scan backwards until we * hit the end-of-central-dir signature. We can then sanity check that * the comment was as big as it should be to make sure we're in the * right place. The comment length field is 16 bits, so we can stop * searching for that signature after a little more than 64k at most, * and call it a corrupted zipfile. */ if (sizeof (buf) < filelen) { filepos = filelen - sizeof (buf); maxread = sizeof (buf); } /* if */ else { filepos = 0; maxread = (PHYSFS_uint32) filelen; } /* else */ while ((totalread < filelen) && (totalread < 65557)) { BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, filepos), NULL, -1); /* make sure we catch a signature between buffers. */ if (totalread != 0) { if (__PHYSFS_platformRead(in, buf, maxread - 4, 1) != 1) return(-1); *((PHYSFS_uint32 *) (&buf[maxread - 4])) = extra; totalread += maxread - 4; } /* if */ else { if (__PHYSFS_platformRead(in, buf, maxread, 1) != 1) return(-1); totalread += maxread; } /* else */ extra = *((PHYSFS_uint32 *) (&buf[0])); for (i = maxread - 4; i > 0; i--) { if ((buf[i + 0] == 0x50) && (buf[i + 1] == 0x4B) && (buf[i + 2] == 0x05) && (buf[i + 3] == 0x06) ) { found = 1; /* that's the signature! */ break; } /* if */ } /* for */ if (found) break; filepos -= (maxread - 4); } /* while */ BAIL_IF_MACRO(!found, ERR_NOT_AN_ARCHIVE, -1); if (len != NULL) *len = filelen; return(filepos + i); } /* zip_find_end_of_central_dir */
static int DIR_seek(fvoid *opaque, PHYSFS_uint64 offset) { return(__PHYSFS_platformSeek(opaque, offset)); } /* DIR_seek */
static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset) { return(__PHYSFS_platformSeek(handle->opaque, offset)); } /* DIR_seek */