diff options
-rw-r--r-- | lib/sqfs/Makemodule.am | 1 | ||||
-rw-r--r-- | lib/sqfs/frag_table.c | 94 |
2 files changed, 43 insertions, 52 deletions
diff --git a/lib/sqfs/Makemodule.am b/lib/sqfs/Makemodule.am index 7dafd8e..9702b76 100644 --- a/lib/sqfs/Makemodule.am +++ b/lib/sqfs/Makemodule.am @@ -42,6 +42,7 @@ libsquashfs_la_SOURCES += lib/util/str_table.c lib/util/alloc.c libsquashfs_la_SOURCES += lib/util/xxhash.c libsquashfs_la_SOURCES += lib/util/hash_table.c include/hash_table.h libsquashfs_la_SOURCES += lib/util/rbtree.c include/rbtree.h +libsquashfs_la_SOURCES += lib/util/array.c include/array.h if WINDOWS libsquashfs_la_SOURCES += lib/sqfs/win32/io_file.c diff --git a/lib/sqfs/frag_table.c b/lib/sqfs/frag_table.c index 5d919b8..f15da5c 100644 --- a/lib/sqfs/frag_table.c +++ b/lib/sqfs/frag_table.c @@ -13,6 +13,7 @@ #include "sqfs/error.h" #include "sqfs/block.h" #include "compat.h" +#include "array.h" #include <stdlib.h> #include <string.h> @@ -20,29 +21,30 @@ struct sqfs_frag_table_t { sqfs_object_t base; - size_t capacity; - size_t used; - sqfs_fragment_t *table; + array_t table; }; static void frag_table_destroy(sqfs_object_t *obj) { sqfs_frag_table_t *tbl = (sqfs_frag_table_t *)obj; - free(tbl->table); + array_cleanup(&tbl->table); free(tbl); } static sqfs_object_t *frag_table_copy(const sqfs_object_t *obj) { const sqfs_frag_table_t *tbl = (const sqfs_frag_table_t *)obj; - sqfs_frag_table_t *copy; + sqfs_frag_table_t *copy = calloc(1, sizeof(*copy)); - copy = malloc(sizeof(*copy)); if (copy == NULL) return NULL; - memcpy(copy, tbl, sizeof(*tbl)); + if (array_init_copy(©->table, &tbl->table)) { + free(copy); + return NULL; + } + return (sqfs_object_t *)copy; } @@ -57,6 +59,7 @@ sqfs_frag_table_t *sqfs_frag_table_create(sqfs_u32 flags) if (tbl == NULL) return NULL; + array_init(&tbl->table, sizeof(sqfs_fragment_t), 0); ((sqfs_object_t *)tbl)->copy = frag_table_copy; ((sqfs_object_t *)tbl)->destroy = frag_table_destroy; return tbl; @@ -70,10 +73,8 @@ int sqfs_frag_table_read(sqfs_frag_table_t *tbl, sqfs_file_t *file, size_t size; int err; - free(tbl->table); - tbl->table = NULL; - tbl->capacity = 0; - tbl->used = 0; + array_cleanup(&tbl->table); + tbl->table.size = sizeof(sqfs_fragment_t); if (super->flags & SQFS_FLAG_NO_FRAGMENTS) return 0; @@ -113,9 +114,9 @@ int sqfs_frag_table_read(sqfs_frag_table_t *tbl, sqfs_file_t *file, return err; } - tbl->table = raw; - tbl->capacity = super->fragment_entry_count; - tbl->used = super->fragment_entry_count; + tbl->table.data = raw; + tbl->table.count = super->fragment_entry_count; + tbl->table.used = super->fragment_entry_count; return 0; } @@ -125,7 +126,7 @@ int sqfs_frag_table_write(sqfs_frag_table_t *tbl, sqfs_file_t *file, size_t i; int err; - if (tbl->used == 0) { + if (tbl->table.used == 0) { super->fragment_table_start = 0xFFFFFFFFFFFFFFFF; super->flags |= SQFS_FLAG_NO_FRAGMENTS; super->flags &= ~SQFS_FLAG_ALWAYS_FRAGMENTS; @@ -133,19 +134,21 @@ int sqfs_frag_table_write(sqfs_frag_table_t *tbl, sqfs_file_t *file, return 0; } - err = sqfs_write_table(file, cmp, tbl->table, - sizeof(tbl->table[0]) * tbl->used, + err = sqfs_write_table(file, cmp, tbl->table.data, + tbl->table.size * tbl->table.used, &super->fragment_table_start); if (err) return err; - super->fragment_entry_count = tbl->used; + super->fragment_entry_count = tbl->table.used; super->flags &= ~SQFS_FLAG_NO_FRAGMENTS; super->flags |= SQFS_FLAG_ALWAYS_FRAGMENTS; super->flags |= SQFS_FLAG_UNCOMPRESSED_FRAGMENTS; - for (i = 0; i < tbl->used; ++i) { - if (SQFS_IS_BLOCK_COMPRESSED(le32toh(tbl->table[i].size))) { + for (i = 0; i < tbl->table.used; ++i) { + sqfs_u32 sz = ((sqfs_fragment_t *)tbl->table.data)[i].size; + + if (SQFS_IS_BLOCK_COMPRESSED(le32toh(sz))) { super->flags &= ~SQFS_FLAG_UNCOMPRESSED_FRAGMENTS; break; } @@ -157,58 +160,45 @@ int sqfs_frag_table_write(sqfs_frag_table_t *tbl, sqfs_file_t *file, int sqfs_frag_table_lookup(sqfs_frag_table_t *tbl, sqfs_u32 index, sqfs_fragment_t *out) { - if (index >= tbl->used) + sqfs_fragment_t *frag = array_get(&tbl->table, index); + + if (frag == NULL) return SQFS_ERROR_OUT_OF_BOUNDS; - out->start_offset = le64toh(tbl->table[index].start_offset); - out->size = le32toh(tbl->table[index].size); - out->pad0 = le32toh(tbl->table[index].pad0); + out->start_offset = le64toh(frag->start_offset); + out->size = le32toh(frag->size); + out->pad0 = le32toh(frag->pad0); return 0; } int sqfs_frag_table_append(sqfs_frag_table_t *tbl, sqfs_u64 location, sqfs_u32 size, sqfs_u32 *index) { - sqfs_fragment_t *new; - size_t new_sz, total; - - if (tbl->used == tbl->capacity) { - new_sz = tbl->capacity ? tbl->capacity * 2 : 128; - - if (SZ_MUL_OV(new_sz, sizeof(tbl->table[0]), &total)) - return SQFS_ERROR_OVERFLOW; - - new = realloc(tbl->table, total); - if (new == NULL) - return SQFS_ERROR_ALLOC; - - tbl->capacity = new_sz; - tbl->table = new; - } + sqfs_fragment_t frag; if (index != NULL) - *index = tbl->used; + *index = tbl->table.used; - memset(tbl->table + tbl->used, 0, sizeof(tbl->table[0])); - tbl->table[tbl->used].start_offset = htole64(location); - tbl->table[tbl->used].size = htole32(size); + memset(&frag, 0, sizeof(frag)); + frag.start_offset = htole64(location); + frag.size = htole32(size); - tbl->used += 1; - return 0; + return array_append(&tbl->table, &frag); } int sqfs_frag_table_set(sqfs_frag_table_t *tbl, sqfs_u32 index, sqfs_u64 location, sqfs_u32 size) { - if (index >= tbl->used) - return SQFS_ERROR_OUT_OF_BOUNDS; + sqfs_fragment_t frag; - tbl->table[index].start_offset = htole64(location); - tbl->table[index].size = htole32(size); - return 0; + memset(&frag, 0, sizeof(frag)); + frag.start_offset = htole64(location); + frag.size = htole32(size); + + return array_set(&tbl->table, index, &frag); } size_t sqfs_frag_table_get_size(sqfs_frag_table_t *tbl) { - return tbl->used; + return tbl->table.used; } |