diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 10 | ||||
| -rw-r--r-- | src/table.c | 81 | ||||
| -rw-r--r-- | src/table.h | 7 |
3 files changed, 84 insertions, 14 deletions
@@ -200,7 +200,7 @@ static void map_entries(char *path, struct params p) { /* Creates a new XP3 archive at the first path specified by `paths`, and flattens files specified by any following paths into the archive. */ -static void create_archive(char **paths, struct params p) { +static void create_archive(char **paths, int argc, struct params p) { FILE *fp = fopen(paths[0], "wb+"); if (fp == NULL) { perror(paths[0]); @@ -208,8 +208,12 @@ static void create_archive(char **paths, struct params p) { } struct header *h = create_header(); - struct table_entry *root = calloc(sizeof(struct table_entry), 1); + struct table_entry *root = calloc(sizeof(struct table_entry), 1), *cur; dump_header(fp, h); + for (int i = 1; i < argc - p.vararg_index; i++) { + cur = add_file(root, paths[i]); + } + dump_table(fp, root); } @@ -232,7 +236,7 @@ int main(int argc, char **argv) { map_entries(argv[i], p); break; case CREATE: - create_archive(argv + p.vararg_index, p); + create_archive(argv + p.vararg_index, argc, p); } params_free(p); return EXIT_SUCCESS; diff --git a/src/table.c b/src/table.c index a67c735..afd2e0f 100644 --- a/src/table.c +++ b/src/table.c @@ -203,17 +203,75 @@ struct table_entry *add_file(struct table_entry *root, char *path) { } -/* Dumps an eliF entry into the table at `fp`. */ -static void dump_elif(FILE *fp, char *path, uint32_t key) { - /* FIXME: Entry size is likely incorrect. Go back and inspect the - table output. */ - uint16_t name_len = strlen(path); +/* Dumps the adlr segment for `key` into the table at `fp` and returns + the number of bytes written. */ +static uint64_t dump_adlr(FILE *fp, uint32_t key) { + uint32_t magic = ADLR_MAGIC; + uint64_t written, entry_size = sizeof(uint32_t); + written = fwrite(&magic, sizeof(uint32_t), 1, fp); + written += fwrite(&entry_size, sizeof(uint64_t), 1, fp); + written += fwrite(&key, sizeof(uint32_t), 1, fp); + return written; +} + + +/* Dumps the time segment for `timestamp` into the table at `fp` and + returns the number of bytes written. */ +static uint64_t dump_time(FILE *fp, uint64_t timestamp) { + uint32_t magic = TIME_MAGIC; + uint64_t written, entry_size = sizeof(uint64_t); + written = fwrite(&magic, sizeof(uint32_t), 1, fp); + written += fwrite(&entry_size, sizeof(uint32_t), 1, fp); + written += fwrite(×tamp, sizeof(uint32_t), 1, fp); + return written; +} + + +/* Dumps the segm segment for `cur` into the table at `fp` and returns + the number of bytes written. */ +static uint64_t dump_segm(FILE *fp, struct table_entry *cur) { + struct segment *s; + uint32_t magic = SEGM_MAGIC; + uint64_t written, entry_size = cur->segment_count * 28; + written = fwrite(&magic, sizeof(uint32_t), 1, fp); + written += fwrite(&entry_size, sizeof(uint32_t), 1, fp); + for (uint64_t i = 0; i < cur->segment_count; i++) { + s = cur->segments[i]; + written += fwrite(&s->compressed, sizeof(uint32_t), 1, fp); + written += fwrite(&s->offset, sizeof(uint64_t), 1, fp); + written += fwrite(&s->decompressed_size, sizeof(uint64_t), 1, fp); + written += fwrite(&s->compressed_size, sizeof(uint64_t), 1, fp); + } + return written; +} + + +/* Dumps the File entry for `cur` into the table at `fp`. */ +static void dump_file(FILE *fp, struct table_entry *cur) { + uint32_t magic = FILE_MAGIC; + uint64_t bytes_written; + fwrite(&magic, sizeof(uint32_t), 1, fp); + fwrite(&bytes_written, sizeof(uint64_t), 1, fp); + bytes_written = dump_adlr(fp, cur->key); + bytes_written += dump_time(fp, cur->ctime); + bytes_written += dump_segm(fp, cur); + + fseek(fp, -bytes_written, SEEK_CUR); + fwrite(&bytes_written, sizeof(uint64_t), 1, fp); + fseek(fp, bytes_written, SEEK_CUR); +} + + +/* Dumps the eliF entry for `cur` into the table at `fp`. */ +static void dump_elif(FILE *fp, struct table_entry *cur) { + uint32_t magic = ELIF_MAGIC; + uint16_t name_len = strlen(cur->filename); uint64_t entry_size = name_len * 2 + 8; char *encoded = malloc(name_len * 2 + 2); - utf16le_encode(path, encoded, name_len); - fwrite(&ELIF_MAGIC, sizeof(uint32_t), 1, fp); + utf16le_encode(cur->filename, encoded, name_len); + fwrite(&magic, sizeof(uint32_t), 1, fp); fwrite(&entry_size, sizeof(uint64_t), 1, fp); - fwrite(&key, sizeof(uint32_t), 1, fp); + fwrite(&cur->key, sizeof(uint32_t), 1, fp); fwrite(&name_len, sizeof(uint16_t), 1, fp); fwrite(encoded, name_len * 2 + 2, 1, fp); } @@ -222,8 +280,9 @@ static void dump_elif(FILE *fp, char *path, uint32_t key) { /* Dumps the XP3 table specified by `root` into `fp`. */ void dump_table(FILE *fp, struct table_entry *root) { struct table_entry *cur; - for (cur = root; cur != NULL; cur = cur->next) { - dump_elif(fp, cur->filename, cur->key); + for (cur = root->next; cur != NULL; cur = cur->next) { + dump_elif(fp, cur); + dump_file(fp, cur); } } @@ -238,7 +297,7 @@ struct table_entry *get_node(struct table_entry *root, uint32_t key) { if (cur == NULL) return NULL; entry_append(root, cur); cur->key = key; -p } + } return cur; } diff --git a/src/table.h b/src/table.h index 89189c6..d9e9f53 100644 --- a/src/table.h +++ b/src/table.h @@ -73,3 +73,10 @@ void entry_append(struct table_entry *root, struct table_entry *e); /* Frees every entry in the linked list specified by `cur`. */ void entry_free(struct table_entry *cur); + +/* Dumps the XP3 table specified by `root` into `fp`. */ +void dump_table(FILE *fp, struct table_entry *root); + +/* Inserts the file specified by `path` into the table linked list + specified by `root`. */ +struct table_entry *add_file(struct table_entry *root, char *path); |