aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sqfs/Makemodule.am1
-rw-r--r--lib/sqfs/frag_table.c94
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(&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;
}