5 * formats that can just hand back a list of files and the offsets of their |
5 * formats that can just hand back a list of files and the offsets of their |
6 * uncompressed data. There are an alarming number of formats like this. |
6 * uncompressed data. There are an alarming number of formats like this. |
7 * |
7 * |
8 * RULES: Archive entries must be uncompressed, must not have separate subdir |
8 * RULES: Archive entries must be uncompressed, must not have separate subdir |
9 * entries (but can have subdirs), must be case insensitive LOW ASCII |
9 * entries (but can have subdirs), must be case insensitive LOW ASCII |
10 * filenames <= 56 bytes. No symlinks, etc. We can relax some of these rules |
10 * filenames <= 64 bytes. No symlinks, etc. We can relax some of these rules |
11 * as necessary. |
11 * as necessary. |
12 * |
12 * |
13 * Please see the file LICENSE.txt in the source's root directory. |
13 * Please see the file LICENSE.txt in the source's root directory. |
14 * |
14 * |
15 * This file written by Ryan C. Gordon. |
15 * This file written by Ryan C. Gordon. |
240 cb(callbackdata, odir, newstr); |
240 cb(callbackdata, odir, newstr); |
241 __PHYSFS_smallFree(newstr); |
241 __PHYSFS_smallFree(newstr); |
242 } /* doEnumCallback */ |
242 } /* doEnumCallback */ |
243 |
243 |
244 |
244 |
245 void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname, |
245 void UNPK_enumerateFiles(void *opaque, const char *dname, |
246 int omitSymLinks, PHYSFS_EnumFilesCallback cb, |
246 PHYSFS_EnumFilesCallback cb, |
247 const char *origdir, void *callbackdata) |
247 const char *origdir, void *callbackdata) |
248 { |
248 { |
249 UNPKinfo *info = ((UNPKinfo *) opaque); |
249 UNPKinfo *info = ((UNPKinfo *) opaque); |
250 PHYSFS_sint32 dlen, dlen_inc, max, i; |
250 PHYSFS_sint32 dlen, dlen_inc, max, i; |
251 |
251 |
291 } /* UNPK_enumerateFiles */ |
291 } /* UNPK_enumerateFiles */ |
292 |
292 |
293 |
293 |
294 /* |
294 /* |
295 * This will find the UNPKentry associated with a path in platform-independent |
295 * This will find the UNPKentry associated with a path in platform-independent |
296 * notation. Directories don't have UNPKentries associated with them, but |
296 * notation. Directories don't have UNPKentries associated with them, but |
297 * (*isDir) will be set to non-zero if a dir was hit. |
297 * (*isDir) will be set to non-zero if a dir was hit. |
298 */ |
298 */ |
299 static UNPKentry *findEntry(const UNPKinfo *info, const char *path, int *isDir) |
299 static UNPKentry *findEntry(const UNPKinfo *info, const char *path, int *isDir) |
300 { |
300 { |
301 UNPKentry *a = info->entries; |
301 UNPKentry *a = info->entries; |
338 } /* while */ |
338 } /* while */ |
339 |
339 |
340 if (isDir != NULL) |
340 if (isDir != NULL) |
341 *isDir = 0; |
341 *isDir = 0; |
342 |
342 |
343 BAIL_MACRO(PHYSFS_ERR_NO_SUCH_PATH, NULL); |
343 BAIL_MACRO(PHYSFS_ERR_NOT_FOUND, NULL); |
344 } /* findEntry */ |
344 } /* findEntry */ |
345 |
345 |
346 |
346 |
347 PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists) |
347 PHYSFS_Io *UNPK_openRead(void *opaque, const char *name) |
348 { |
348 { |
349 PHYSFS_Io *retval = NULL; |
349 PHYSFS_Io *retval = NULL; |
350 UNPKinfo *info = (UNPKinfo *) opaque; |
350 UNPKinfo *info = (UNPKinfo *) opaque; |
351 UNPKfileinfo *finfo = NULL; |
351 UNPKfileinfo *finfo = NULL; |
352 int isdir = 0; |
352 int isdir = 0; |
353 UNPKentry *entry = findEntry(info, fnm, &isdir); |
353 UNPKentry *entry = findEntry(info, name, &isdir); |
354 |
354 |
355 *fileExists = (entry != NULL); |
|
356 GOTO_IF_MACRO(isdir, PHYSFS_ERR_NOT_A_FILE, UNPK_openRead_failed); |
355 GOTO_IF_MACRO(isdir, PHYSFS_ERR_NOT_A_FILE, UNPK_openRead_failed); |
357 GOTO_IF_MACRO(!entry, ERRPASS, UNPK_openRead_failed); |
356 GOTO_IF_MACRO(!entry, ERRPASS, UNPK_openRead_failed); |
358 |
357 |
359 retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io)); |
358 retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io)); |
360 GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed); |
359 GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed); |
388 |
387 |
389 return NULL; |
388 return NULL; |
390 } /* UNPK_openRead */ |
389 } /* UNPK_openRead */ |
391 |
390 |
392 |
391 |
393 PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name) |
392 PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name) |
394 { |
393 { |
395 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
394 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
396 } /* UNPK_openWrite */ |
395 } /* UNPK_openWrite */ |
397 |
396 |
398 |
397 |
399 PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name) |
398 PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name) |
400 { |
399 { |
401 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
400 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL); |
402 } /* UNPK_openAppend */ |
401 } /* UNPK_openAppend */ |
403 |
402 |
404 |
403 |
405 int UNPK_remove(PHYSFS_Dir *opaque, const char *name) |
404 int UNPK_remove(void *opaque, const char *name) |
406 { |
405 { |
407 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
406 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
408 } /* UNPK_remove */ |
407 } /* UNPK_remove */ |
409 |
408 |
410 |
409 |
411 int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name) |
410 int UNPK_mkdir(void *opaque, const char *name) |
412 { |
411 { |
413 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
412 BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0); |
414 } /* UNPK_mkdir */ |
413 } /* UNPK_mkdir */ |
415 |
414 |
416 |
415 |
417 int UNPK_stat(PHYSFS_Dir *opaque, const char *filename, |
416 int UNPK_stat(void *opaque, const char *filename, PHYSFS_Stat *stat) |
418 int *exists, PHYSFS_Stat *stat) |
|
419 { |
417 { |
420 int isDir = 0; |
418 int isDir = 0; |
421 const UNPKinfo *info = (const UNPKinfo *) opaque; |
419 const UNPKinfo *info = (const UNPKinfo *) opaque; |
422 const UNPKentry *entry = findEntry(info, filename, &isDir); |
420 const UNPKentry *entry = findEntry(info, filename, &isDir); |
423 |
421 |
424 if (isDir) |
422 if (isDir) |
425 { |
423 { |
426 *exists = 1; |
|
427 stat->filetype = PHYSFS_FILETYPE_DIRECTORY; |
424 stat->filetype = PHYSFS_FILETYPE_DIRECTORY; |
428 stat->filesize = 0; |
425 stat->filesize = 0; |
429 } /* if */ |
426 } /* if */ |
430 else if (entry != NULL) |
427 else if (entry != NULL) |
431 { |
428 { |
432 *exists = 1; |
|
433 stat->filetype = PHYSFS_FILETYPE_REGULAR; |
429 stat->filetype = PHYSFS_FILETYPE_REGULAR; |
434 stat->filesize = entry->size; |
430 stat->filesize = entry->size; |
435 } /* else if */ |
431 } /* else if */ |
436 else |
432 else |
437 { |
433 { |
438 *exists = 0; |
|
439 return 0; |
434 return 0; |
440 } /* else */ |
435 } /* else */ |
441 |
436 |
442 stat->modtime = -1; |
437 stat->modtime = -1; |
443 stat->createtime = -1; |
438 stat->createtime = -1; |