From 8eeaf6c6d7a08e90c824c1f5dc5608466f7e8193 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 25 Jul 2002 04:41:43 +0000 Subject: [PATCH] Rewrote ZIP_enumerateFiles() again. Hopefully it sucks less this time. --- archivers/zip.c | 73 ++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/archivers/zip.c b/archivers/zip.c index 84921171..97745a08 100644 --- a/archivers/zip.c +++ b/archivers/zip.c @@ -1230,9 +1230,13 @@ static PHYSFS_sint32 zip_find_start_of_dir(ZIPinfo *info, const char *path, rc = 1; else { - if ((name[dlen + 1] == '\0') || (stop_on_first_find)) + + if (stop_on_first_find) /* Just checking dir's existance? */ return(middle); + if (name[dlen + 1] == '\0') /* Skip initial dir entry. */ + return(middle + 1); + /* there might be more entries earlier in the list. */ retval = middle; hi = middle - 1; @@ -1253,60 +1257,47 @@ static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname, int omitSymLinks) { -#if 1 - return(NULL); /* !!! FIXME */ -#else ZIPinfo *info = ((ZIPinfo *) h->opaque); - PHYSFS_sint32 i, tmp, max; LinkedStringList *retval = NULL, *p = NULL; - PHYSFS_uint32 dlen = strlen(dirname); - - if ((dlen > 0) && (dirname[dlen - 1] == '/')) - dlen--; + PHYSFS_sint32 dlen, dlen_inc, max, i; i = zip_find_start_of_dir(info, dirname, 0); BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL); - for (max = (PHYSFS_sint32) info->entryCount; i < max; i++) - { - ZIPentry *entry = &info->entries[i]; - const char *add_file; - size_t strsize; - char *slash; - - if ((dlen > 0) && (strncmp(entry->name, dirname, dlen) != 0)) - break; /* we're past this dir's entries. */ - - add_file = entry->name + dlen + ((dlen > 0) ? 1 : 0); - if ( ((omitSymLinks) && (zip_entry_is_symlink(entry))) || - (*add_file == '\0') ) /* skip links and the dir entry itself. */ - { - continue; - } /* if */ + dlen = strlen(dirname); + if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */ + dlen--; - slash = strchr(add_file, '/'); /* handle subdirs under dirname... */ - strsize = (size_t) ((slash) ? (slash - add_file) : strlen(add_file)); - retval = __PHYSFS_addToLinkedStringList(retval, &p, add_file, strsize); + dlen_inc = ((dlen > 0) ? 1 : 0) + dlen; + max = (PHYSFS_sint32) info->entryCount; + while (i < max) + { + char *e = info->entries[i].name; + if ((dlen) && ((strncmp(e, dirname, dlen) != 0) || (e[dlen] != '/'))) + break; /* past end of this dir; we're done. */ - tmp = i; - /* We added a subdir? Skip its children. */ - while ((slash != NULL) && (i < max)) + if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i]))) + i++; + else { - if (strncmp(info->entries[i].name, info->entries[tmp].name, dlen + strsize + 1) == 0) + char *add = e + dlen_inc; + char *ptr = strchr(add, '/'); + PHYSFS_sint32 ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add)); + retval = __PHYSFS_addToLinkedStringList(retval, &p, add, ln); + ln += dlen_inc; /* point past entry to children... */ + + /* increment counter and skip children of subdirs... */ + while ((++i < max) && (ptr != NULL)) { - if (info->entries[i].name[dlen + strsize + 1] == '/') - { - i++; + char *e_new = info->entries[i].name; + if ((strncmp(e, e_new, ln) == 0) && (e_new[ln] == '/')) continue; - } /* if */ - } /* if */ - i--; /* for loop will increment. */ - slash = NULL; - } /* while */ + ptr = NULL; + } /* while */ + } /* else */ } /* while */ return(retval); -#endif } /* ZIP_enumerateFiles */