diff options
author | pixel <pixel> | 2007-07-10 13:09:37 +0000 |
---|---|---|
committer | pixel <pixel> | 2007-07-10 13:09:37 +0000 |
commit | dcd04bd6d9569aff386d438dcaa1194e9ce7d36e (patch) | |
tree | 5c174e53193c6f14f713d47850139bbca316bd61 | |
parent | da769d1be51b4251854b10f841b6764cbc1fde1f (diff) |
mpq-fs working.
-rw-r--r-- | mpq-file.c | 2 | ||||
-rw-r--r-- | mpq-fs.c | 164 | ||||
-rw-r--r-- | test-it.c | 21 |
3 files changed, 184 insertions, 3 deletions
@@ -117,7 +117,7 @@ struct mpq_file_t * mpqlib_open_filename(struct mpq_archive_t * mpq_a, const cha return mpqlib_open_file(mpq_a, e); } -void mpqlib_close_file(struct mpq_file_t * mpq_f) { +void mpqlib_close(struct mpq_file_t * mpq_f) { free(mpq_f->buffer); free(mpq_f->offsets); free(mpq_f->sizes); @@ -1,13 +1,173 @@ #include <stdlib.h> +#include <string.h> +#include <ctype.h> #include "mpq-fs.h" +#define MAX_FNAME 2048 + +typedef struct directory_list_t { + struct directory_list_t * child; + char * name; + struct mpq_archive_t * mpq_a; + int entry; + struct directory_list_t * next; +} directory_list; + +static directory_list root_dir = { + NULL, "", NULL, -1, NULL +}; + +static directory_list * root = &root_dir; + +static char * strtoupper(char * _str) { + char * str = _str; + while (*str) { + *str = toupper(*str); + str++; + } + return _str; +} + +static directory_list * new_directory_list(directory_list * parent, struct mpq_archive_t * mpq_a, const char * name) { + directory_list * r; + + for (r = parent->child; r; r = r->next) { + if (!strcasecmp(r->name, name)) + break; + } + + if (!r) { + r = (directory_list *) malloc(sizeof(directory_list)); + r->child = NULL; + r->next = parent->child; + parent->child = r; + r->name = strtoupper(strdup(name)); + r->mpq_a = mpq_a; + r->entry = -1; + } + + return r; +} + +static directory_list * add_file_r(directory_list * parent, struct mpq_archive_t * mpq_a, char * fname, int entry) { + char * bs; + directory_list * r; + int tail = 0; + + bs = strchr(fname, '\\'); + + if (bs) { + *bs = 0; + } else { + tail = 1; + } + if (!(r = new_directory_list(parent, mpq_a, fname))) + return NULL; + + if (tail) { + r->entry = entry; + return r; + } + + return add_file_r(r, mpq_a, bs + 1, entry); +} + +static directory_list * add_file(struct mpq_archive_t * mpq_a, char * fname) { + int entry; + + if ((entry = mpqlib_find_hash_entry_by_name(mpq_a, fname, 0, 0)) < 0) + return NULL; + + return add_file_r(root, mpq_a, fname, entry); +} + void mpqlib_fs_add_archive(struct mpq_archive_t * mpq_a) { + struct mpq_file_t * listfile; + char * buffer; + int s; + + if (!(listfile = mpqlib_open_filename(mpq_a, "(listfile)"))) + return; + + s = mpqlib_seek(listfile, 0, MPQLIB_SEEK_END); + mpqlib_seek(listfile, 0, MPQLIB_SEEK_SET); + + if (!(buffer = (char *) malloc(s + 1))) { + mpqlib_close(listfile); + return; + } + + buffer[s] = 0; + mpqlib_read(listfile, buffer, s); + mpqlib_fs_attach_listfile(mpq_a, buffer); + + free(buffer); + mpqlib_close(listfile); } void mpqlib_fs_attach_listfile(struct mpq_archive_t * mpq_a, const char * listfile) { - mpqlib_fs_add_archive(mpq_a); + char fname[MAX_FNAME]; + const char * p; + char * fnp; + + for (p = listfile, fnp = fname; *p; p++) { + switch (*p) { + case '\r': + case '\n': + case ';': + *fnp = 0; + if (fnp != fname) + add_file(mpq_a, fname); + fnp = fname; + break; + default: + *(fnp++) = *p; + break; + } + } } -struct mpq_file_t * mpqlib_fs_open(const char * fname) { +static directory_list * find_file_r(directory_list * parent, char * fname) { + char * bs; + directory_list * r; + int tail = 0; + + bs = strchr(fname, '\\'); + + if (bs) { + *bs = 0; + } else { + tail = 1; + } + + for (r = parent->child; r; r = r->next) { + if (!strcmp(fname, r->name)) { + if (tail) { + return r; + } else { + return find_file_r(r, bs + 1); + } + } + } + + return NULL; +} + +static directory_list * find_file(char * fname) { + return find_file_r(root, fname); +} + +struct mpq_file_t * mpqlib_fs_open(const char * _fname) { + char * fname = strtoupper(strdup(_fname)); + directory_list * entry; + + entry = find_file(fname); + + free(fname); + + if (entry) { + return mpqlib_open_file(entry->mpq_a, entry->entry); + } + return NULL; } @@ -2,6 +2,7 @@ #include <stdlib.h> #include "mpq-bios.h" #include "mpq-file.h" +#include "mpq-fs.h" #include "mpq-errors.h" int main(int argc, char ** argv) { @@ -38,6 +39,26 @@ int main(int argc, char ** argv) { printf("Dumping:\n"); printf("%s", b); printf("\nDone.\n"); + mpqlib_close(f1); + } + + mpqlib_fs_add_archive(t1); + f1 = mpqlib_fs_open("Interface\\FrameXML\\WorldMapFrame.lua"); + + if (f1) { + int size; + char * b; + printf("Found!\n"); + size = mpqlib_seek(f1, 0, MPQLIB_SEEK_END); + mpqlib_seek(f1, 0, MPQLIB_SEEK_SET); + printf("Filesize seems to be: %d.\n", size); + b = (char *) malloc(size + 1); + b[size] = 0; + mpqlib_read(f1, b, size); + printf("Dumping:\n"); + printf("%s", b); + printf("\nDone.\n"); + mpqlib_close(f1); } mpqlib_close_archive(t1); |