aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs/xattr
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfs/xattr')
-rw-r--r--lib/sqfs/xattr/xattr_writer.c28
-rw-r--r--lib/sqfs/xattr/xattr_writer.h5
-rw-r--r--lib/sqfs/xattr/xattr_writer_flush.c8
-rw-r--r--lib/sqfs/xattr/xattr_writer_record.c43
4 files changed, 30 insertions, 54 deletions
diff --git a/lib/sqfs/xattr/xattr_writer.c b/lib/sqfs/xattr/xattr_writer.c
index d23e063..e38c2be 100644
--- a/lib/sqfs/xattr/xattr_writer.c
+++ b/lib/sqfs/xattr/xattr_writer.c
@@ -24,16 +24,9 @@ static sqfs_object_t *xattr_writer_copy(const sqfs_object_t *obj)
if (str_table_copy(&copy->values, &xwr->values))
goto fail_values;
- copy->max_pairs = xwr->num_pairs;
- copy->num_pairs = xwr->num_pairs;
-
- copy->kv_pairs = malloc(sizeof(copy->kv_pairs[0]) * xwr->num_pairs);
- if (copy->kv_pairs == NULL)
+ if (array_init_copy(&copy->kv_pairs, &xwr->kv_pairs))
goto fail_pairs;
- memcpy(copy->kv_pairs, xwr->kv_pairs,
- sizeof(copy->kv_pairs[0]) * xwr->num_pairs);
-
if (rbtree_copy(&xwr->kv_block_tree, &copy->kv_block_tree) != 0)
goto fail_tree;
@@ -53,7 +46,7 @@ static sqfs_object_t *xattr_writer_copy(const sqfs_object_t *obj)
return (sqfs_object_t *)copy;
fail_tree:
- free(copy->kv_pairs);
+ array_cleanup(&copy->kv_pairs);
fail_pairs:
str_table_cleanup(&copy->values);
fail_values:
@@ -68,7 +61,7 @@ static void xattr_writer_destroy(sqfs_object_t *obj)
sqfs_xattr_writer_t *xwr = (sqfs_xattr_writer_t *)obj;
rbtree_cleanup(&xwr->kv_block_tree);
- free(xwr->kv_pairs);
+ array_cleanup(&xwr->kv_pairs);
str_table_cleanup(&xwr->values);
str_table_cleanup(&xwr->keys);
free(xwr);
@@ -86,9 +79,9 @@ static int block_compare(const void *context,
if (l->start == r->start)
return 0;
- return memcmp(xwr->kv_pairs + l->start,
- xwr->kv_pairs + r->start,
- l->count * sizeof(xwr->kv_pairs[0]));
+ return memcmp((sqfs_u64 *)xwr->kv_pairs.data + l->start,
+ (sqfs_u64 *)xwr->kv_pairs.data + r->start,
+ l->count * xwr->kv_pairs.size);
}
sqfs_xattr_writer_t *sqfs_xattr_writer_create(sqfs_u32 flags)
@@ -108,11 +101,10 @@ sqfs_xattr_writer_t *sqfs_xattr_writer_create(sqfs_u32 flags)
if (str_table_init(&xwr->values, XATTR_VALUE_BUCKETS))
goto fail_values;
- xwr->max_pairs = XATTR_INITIAL_PAIR_CAP;
- xwr->kv_pairs = alloc_array(sizeof(xwr->kv_pairs[0]), xwr->max_pairs);
-
- if (xwr->kv_pairs == NULL)
+ if (array_init(&xwr->kv_pairs, sizeof(sqfs_u64),
+ XATTR_INITIAL_PAIR_CAP)) {
goto fail_pairs;
+ }
if (rbtree_init(&xwr->kv_block_tree, sizeof(kv_block_desc_t),
sizeof(sqfs_u32), block_compare)) {
@@ -125,7 +117,7 @@ sqfs_xattr_writer_t *sqfs_xattr_writer_create(sqfs_u32 flags)
((sqfs_object_t *)xwr)->destroy = xattr_writer_destroy;
return xwr;
fail_tree:
- free(xwr->kv_pairs);
+ array_cleanup(&xwr->kv_pairs);
fail_pairs:
str_table_cleanup(&xwr->values);
fail_values:
diff --git a/lib/sqfs/xattr/xattr_writer.h b/lib/sqfs/xattr/xattr_writer.h
index 8ff9691..ff8479a 100644
--- a/lib/sqfs/xattr/xattr_writer.h
+++ b/lib/sqfs/xattr/xattr_writer.h
@@ -20,6 +20,7 @@
#include "str_table.h"
#include "rbtree.h"
+#include "array.h"
#include "util.h"
#include <stdlib.h>
@@ -51,9 +52,7 @@ struct sqfs_xattr_writer_t {
str_table_t keys;
str_table_t values;
- sqfs_u64 *kv_pairs;
- size_t max_pairs;
- size_t num_pairs;
+ array_t kv_pairs;
size_t kv_start;
diff --git a/lib/sqfs/xattr/xattr_writer_flush.c b/lib/sqfs/xattr/xattr_writer_flush.c
index 92f9be3..85ec724 100644
--- a/lib/sqfs/xattr/xattr_writer_flush.c
+++ b/lib/sqfs/xattr/xattr_writer_flush.c
@@ -145,15 +145,15 @@ static int write_block_pairs(const sqfs_xattr_writer_t *xwr,
const kv_block_desc_t *blk,
sqfs_u64 *ool_locations)
{
- sqfs_u32 key_idx, val_idx;
const char *key_str, *value_str;
sqfs_s32 diff, total = 0;
size_t i, refcount;
sqfs_u64 ref;
for (i = 0; i < blk->count; ++i) {
- key_idx = GET_KEY(xwr->kv_pairs[blk->start + i]);
- val_idx = GET_VALUE(xwr->kv_pairs[blk->start + i]);
+ sqfs_u64 ent = ((sqfs_u64 *)xwr->kv_pairs.data)[blk->start + i];
+ sqfs_u32 key_idx = GET_KEY(ent);
+ sqfs_u32 val_idx = GET_VALUE(ent);
key_str = str_table_get_string(&xwr->keys, key_idx);
value_str = str_table_get_string(&xwr->values, val_idx);
@@ -306,7 +306,7 @@ int sqfs_xattr_writer_flush(const sqfs_xattr_writer_t *xwr, sqfs_file_t *file,
size_t i, count;
int err;
- if (xwr->num_pairs == 0 || xwr->num_blocks == 0) {
+ if (xwr->kv_pairs.used == 0 || xwr->num_blocks == 0) {
super->xattr_id_table_start = 0xFFFFFFFFFFFFFFFFUL;
super->flags |= SQFS_FLAG_NO_XATTRS;
return 0;
diff --git a/lib/sqfs/xattr/xattr_writer_record.c b/lib/sqfs/xattr/xattr_writer_record.c
index 510ca17..81bbf6b 100644
--- a/lib/sqfs/xattr/xattr_writer_record.c
+++ b/lib/sqfs/xattr/xattr_writer_record.c
@@ -42,22 +42,21 @@ int sqfs_xattr_writer_begin(sqfs_xattr_writer_t *xwr, sqfs_u32 flags)
if (flags != 0)
return SQFS_ERROR_UNSUPPORTED;
- xwr->kv_start = xwr->num_pairs;
+ xwr->kv_start = xwr->kv_pairs.used;
return 0;
}
int sqfs_xattr_writer_add(sqfs_xattr_writer_t *xwr, const char *key,
const void *value, size_t size)
{
- size_t i, key_index, old_value_index, value_index, new_count;
- sqfs_u64 kv_pair, *new;
+ size_t i, key_index, old_value_index, value_index;
+ sqfs_u64 kv_pair;
char *value_str;
int err;
if (sqfs_get_xattr_prefix_id(key) < 0)
return SQFS_ERROR_UNSUPPORTED;
- /* resolve key and value into unique, incremental IDs */
err = str_table_get_index(&xwr->keys, key, &key_index);
if (err)
return err;
@@ -78,38 +77,25 @@ int sqfs_xattr_writer_add(sqfs_xattr_writer_t *xwr, const char *key,
return SQFS_ERROR_OVERFLOW;
}
- /* bail if already have the pair, overwrite if we have the key */
kv_pair = MK_PAIR(key_index, value_index);
- for (i = xwr->kv_start; i < xwr->num_pairs; ++i) {
- if (xwr->kv_pairs[i] == kv_pair)
+ for (i = xwr->kv_start; i < xwr->kv_pairs.used; ++i) {
+ sqfs_u64 ent = ((sqfs_u64 *)xwr->kv_pairs.data)[i];
+
+ if (ent == kv_pair)
return 0;
- if (GET_KEY(xwr->kv_pairs[i]) == key_index) {
- old_value_index = GET_VALUE(xwr->kv_pairs[i]);
+ if (GET_KEY(ent) == key_index) {
+ old_value_index = GET_VALUE(ent);
str_table_del_ref(&xwr->values, old_value_index);
- xwr->kv_pairs[i] = kv_pair;
+ ((sqfs_u64 *)xwr->kv_pairs.data)[i] = kv_pair;
return 0;
}
}
- /* append it to the list */
- if (xwr->max_pairs == xwr->num_pairs) {
- new_count = xwr->max_pairs * 2;
- new = realloc(xwr->kv_pairs,
- sizeof(xwr->kv_pairs[0]) * new_count);
-
- if (new == NULL)
- return SQFS_ERROR_ALLOC;
-
- xwr->kv_pairs = new;
- xwr->max_pairs = new_count;
- }
-
- xwr->kv_pairs[xwr->num_pairs++] = kv_pair;
- return 0;
+ return array_append(&xwr->kv_pairs, &kv_pair);
}
int sqfs_xattr_writer_end(sqfs_xattr_writer_t *xwr, sqfs_u32 *out)
@@ -121,21 +107,20 @@ int sqfs_xattr_writer_end(sqfs_xattr_writer_t *xwr, sqfs_u32 *out)
memset(&blk, 0, sizeof(blk));
blk.start = xwr->kv_start;
- blk.count = xwr->num_pairs - xwr->kv_start;
+ blk.count = xwr->kv_pairs.used - xwr->kv_start;
if (blk.count == 0) {
*out = 0xFFFFFFFF;
return 0;
}
- qsort(xwr->kv_pairs + blk.start, blk.count,
- sizeof(xwr->kv_pairs[0]), compare_u64);
+ array_sort_range(&xwr->kv_pairs, blk.start, blk.count, compare_u64);
n = rbtree_lookup(&xwr->kv_block_tree, &blk);
if (n != NULL) {
index = *((sqfs_u32 *)rbtree_node_value(n));
- xwr->num_pairs = xwr->kv_start;
+ xwr->kv_pairs.used = xwr->kv_start;
} else {
index = xwr->num_blocks;