archivers/wad.c
changeset 610 1d8057a5d08e
parent 609 3a91332776e0
child 622 c8e67ca63ad6
equal deleted inserted replaced
609:3a91332776e0 610:1d8057a5d08e
    56 #define __PHYSICSFS_INTERNAL__
    56 #define __PHYSICSFS_INTERNAL__
    57 #include "physfs_internal.h"
    57 #include "physfs_internal.h"
    58 
    58 
    59 typedef struct
    59 typedef struct
    60 {
    60 {
    61     char name[9];
    61     char name[18];
    62     PHYSFS_uint32 startPos;
    62     PHYSFS_uint32 startPos;
    63     PHYSFS_uint32 size;
    63     PHYSFS_uint32 size;
    64 } WADentry;
    64 } WADentry;
    65 
    65 
    66 typedef struct
    66 typedef struct
   307 {
   307 {
   308     void *fh = NULL;
   308     void *fh = NULL;
   309     PHYSFS_uint32 fileCount;
   309     PHYSFS_uint32 fileCount;
   310     PHYSFS_uint32 directoryOffset;
   310     PHYSFS_uint32 directoryOffset;
   311     WADentry *entry;
   311     WADentry *entry;
       
   312     char lastDirectory[9],buffer[9];
       
   313 
       
   314     lastDirectory[8] = 0; /* Make sure lastDirectory stays null-terminated. */
   312 
   315 
   313     BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0);
   316     BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0);
   314     info->entryCount = fileCount;
   317     info->entryCount = fileCount;
   315     info->entries = (WADentry *) malloc(sizeof (WADentry) * fileCount);
   318     info->entries = (WADentry *) malloc(sizeof (WADentry) * fileCount);
   316     if (info->entries == NULL)
   319     if (info->entries == NULL)
   410     WADinfo *info = ((WADinfo *) h->opaque);
   413     WADinfo *info = ((WADinfo *) h->opaque);
   411     WADentry *entry = info->entries;
   414     WADentry *entry = info->entries;
   412     LinkedStringList *retval = NULL, *p = NULL;
   415     LinkedStringList *retval = NULL, *p = NULL;
   413     PHYSFS_uint32 max = info->entryCount;
   416     PHYSFS_uint32 max = info->entryCount;
   414     PHYSFS_uint32 i;
   417     PHYSFS_uint32 i;
   415 
   418     char *sep;
   416     /* no directories in WAD files. */
   419 
   417     BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
   420     if (dirname[0] == 0)
   418 
   421     {
   419     for (i = 0; i < max; i++, entry++)
   422         for (i = 0; i < max; i++, entry++)
   420         retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
   423         {
   421 
   424             if (strchr(entry->name, '/') == NULL)
       
   425             {
       
   426                 retval = __PHYSFS_addToLinkedStringList(retval, &p,
       
   427                                                         entry->name, -1);
       
   428             } /* if */
       
   429         } /* for */
       
   430     } /* if */
       
   431     else
       
   432     {
       
   433         for (i = 0; i < max; i++, entry++)
       
   434         {
       
   435             sep = strchr(entry->name, '/');
       
   436             if (sep != NULL)
       
   437             {
       
   438                 if (strncmp(dirname, entry->name, (sep-entry->name)) == 0)
       
   439                 {
       
   440                     retval = __PHYSFS_addToLinkedStringList(retval, &p,
       
   441                                                             sep + 1, -1);
       
   442                 } /* if */
       
   443             } /* if */
       
   444         } /* for */
       
   445     } /* else */
       
   446     
   422     return(retval);
   447     return(retval);
   423 } /* WAD_enumerateFiles */
   448 } /* WAD_enumerateFiles */
   424 
   449 
   425 
   450 
   426 static WADentry *wad_find_entry(WADinfo *info, const char *name)
   451 static WADentry *wad_find_entry(WADinfo *info, const char *name)
   427 {
   452 {
   428     char *ptr = strchr(name, '.');
       
   429     WADentry *a = info->entries;
   453     WADentry *a = info->entries;
   430     PHYSFS_sint32 lo = 0;
   454     PHYSFS_sint32 lo = 0;
   431     PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
   455     PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
   432     PHYSFS_sint32 middle;
   456     PHYSFS_sint32 middle;
   433     int rc;
   457     int rc;
   434 
       
   435     /*
       
   436      * Rule out filenames to avoid unneeded processing...no dirs,
       
   437      *   big filenames, or extensions > 3 chars.
       
   438      */
       
   439     BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
       
   440     BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
       
   441     BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
       
   442 
   458 
   443     while (lo <= hi)
   459     while (lo <= hi)
   444     {
   460     {
   445         middle = lo + ((hi - lo) / 2);
   461         middle = lo + ((hi - lo) / 2);
   446         rc = strcmp(name, a[middle].name);
   462         rc = strcmp(name, a[middle].name);
   462 } /* WAD_exists */
   478 } /* WAD_exists */
   463 
   479 
   464 
   480 
   465 static int WAD_isDirectory(DirHandle *h, const char *name, int *fileExists)
   481 static int WAD_isDirectory(DirHandle *h, const char *name, int *fileExists)
   466 {
   482 {
   467     *fileExists = WAD_exists(h, name);
   483     WADentry *entry = wad_find_entry(((WADinfo *) h->opaque), name);
   468     return(0);  /* never directories in a wad. */
   484     if (entry != NULL)
       
   485     {
       
   486         char *n;
       
   487 
       
   488         *fileExists = 1;
       
   489 
       
   490         /* Can't be a directory if it's a subdirectory. */
       
   491         if (strchr(entry->name, '/') != NULL)
       
   492             return(0);
       
   493 
       
   494         /* Check if it matches "MAP??" or "E?M?" ... */
       
   495         n = entry->name;
       
   496         if ((n[0] == 'E' && n[2] == 'M') ||
       
   497             (n[0] == 'M' && n[1] == 'A' && n[2] == 'P' && n[6] == 0))
       
   498         {
       
   499             return(1);
       
   500         } /* if */
       
   501         return(0);
       
   502     } /* if */
       
   503     else
       
   504     {
       
   505         *fileExists = 0;
       
   506         return(0);
       
   507     } /* else */
   469 } /* WAD_isDirectory */
   508 } /* WAD_isDirectory */
   470 
   509 
   471 
   510 
   472 static int WAD_isSymLink(DirHandle *h, const char *name, int *fileExists)
   511 static int WAD_isSymLink(DirHandle *h, const char *name, int *fileExists)
   473 {
   512 {