summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2007-07-10 13:09:37 +0000
committerpixel <pixel>2007-07-10 13:09:37 +0000
commitdcd04bd6d9569aff386d438dcaa1194e9ce7d36e (patch)
tree5c174e53193c6f14f713d47850139bbca316bd61
parentda769d1be51b4251854b10f841b6764cbc1fde1f (diff)
mpq-fs working.
-rw-r--r--mpq-file.c2
-rw-r--r--mpq-fs.c164
-rw-r--r--test-it.c21
3 files changed, 184 insertions, 3 deletions
diff --git a/mpq-file.c b/mpq-file.c
index d759109..7bafd2f 100644
--- a/mpq-file.c
+++ b/mpq-file.c
@@ -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);
diff --git a/mpq-fs.c b/mpq-fs.c
index acc2648..dac03b4 100644
--- a/mpq-fs.c
+++ b/mpq-fs.c
@@ -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;
}
diff --git a/test-it.c b/test-it.c
index f34d07f..341fe8a 100644
--- a/test-it.c
+++ b/test-it.c
@@ -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);