summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sqfs/block_writer.c78
1 files changed, 25 insertions, 53 deletions
diff --git a/lib/sqfs/block_writer.c b/lib/sqfs/block_writer.c
index 1230c2d..10f5ada 100644
--- a/lib/sqfs/block_writer.c
+++ b/lib/sqfs/block_writer.c
@@ -11,6 +11,8 @@
#include "sqfs/error.h"
#include "sqfs/block.h"
#include "sqfs/io.h"
+
+#include "util/array.h"
#include "util/util.h"
#include <stdlib.h>
@@ -33,14 +35,9 @@ typedef struct {
sqfs_block_writer_t base;
sqfs_file_t *file;
- size_t num_blocks;
- size_t max_blocks;
- blk_info_t *blocks;
+ array_t blocks;
size_t devblksz;
- sqfs_u64 blocks_written;
- sqfs_u64 data_area_start;
-
sqfs_u64 start;
size_t file_start;
@@ -52,24 +49,9 @@ typedef struct {
static int store_block_location(block_writer_default_t *wr, sqfs_u64 offset,
sqfs_u32 size, sqfs_u32 chksum)
{
- blk_info_t *new;
- size_t new_sz;
-
- if (wr->num_blocks == wr->max_blocks) {
- new_sz = wr->max_blocks * 2;
- new = realloc(wr->blocks, sizeof(wr->blocks[0]) * new_sz);
-
- if (new == NULL)
- return SQFS_ERROR_ALLOC;
-
- wr->blocks = new;
- wr->max_blocks = new_sz;
- }
+ blk_info_t info = { offset, MK_BLK_HASH(chksum, size) };
- wr->blocks[wr->num_blocks].offset = offset;
- wr->blocks[wr->num_blocks].hash = MK_BLK_HASH(chksum, size);
- wr->num_blocks += 1;
- return 0;
+ return array_append(&(wr->blocks), &info);
}
static int compare_blocks(block_writer_default_t *wr, sqfs_u64 loc_a,
@@ -105,17 +87,18 @@ static int compare_blocks(block_writer_default_t *wr, sqfs_u64 loc_a,
static int deduplicate_blocks(block_writer_default_t *wr, size_t count,
size_t *out)
{
+ const blk_info_t *blocks = wr->blocks.data;
sqfs_u64 loc_a, loc_b;
size_t i, j, sz;
int ret;
for (i = 0; i < wr->file_start; ++i) {
for (j = 0; j < count; ++j) {
- if (wr->blocks[i + j].hash == 0)
+ if (blocks[i + j].hash == 0)
break;
- if (wr->blocks[i + j].hash !=
- wr->blocks[wr->file_start + j].hash)
+ if (blocks[i + j].hash !=
+ blocks[wr->file_start + j].hash)
break;
}
@@ -126,10 +109,10 @@ static int deduplicate_blocks(block_writer_default_t *wr, size_t count,
break;
for (j = 0; j < count; ++j) {
- sz = SIZE_FROM_HASH(wr->blocks[i + j].hash);
+ sz = SIZE_FROM_HASH(blocks[i + j].hash);
- loc_a = wr->blocks[i + j].offset;
- loc_b = wr->blocks[wr->file_start + j].offset;
+ loc_a = blocks[i + j].offset;
+ loc_b = blocks[wr->file_start + j].offset;
ret = compare_blocks(wr, loc_a, loc_b, sz);
if (ret < 0)
@@ -172,7 +155,7 @@ static int align_file(block_writer_default_t *wr)
static void block_writer_destroy(sqfs_object_t *wr)
{
- free(((block_writer_default_t *)wr)->blocks);
+ array_cleanup(&(((block_writer_default_t *)wr)->blocks));
free(wr);
}
@@ -182,7 +165,6 @@ static int write_data_block(sqfs_block_writer_t *base, void *user,
{
block_writer_default_t *wr = (block_writer_default_t *)base;
size_t start, count;
- sqfs_u64 offset;
sqfs_u32 out;
int err;
(void)user;
@@ -196,27 +178,24 @@ static int write_data_block(sqfs_block_writer_t *base, void *user,
if (flags & SQFS_BLK_FIRST_BLOCK) {
wr->start = wr->file->get_size(wr->file);
- wr->file_start = wr->num_blocks;
+ wr->file_start = wr->blocks.used;
}
}
- offset = wr->file->get_size(wr->file);
- *location = offset;
+ *location = wr->file->get_size(wr->file);
if (size != 0 && !(flags & SQFS_BLK_IS_SPARSE)) {
out = size;
if (!(flags & SQFS_BLK_IS_COMPRESSED))
out |= 1 << 24;
- err = store_block_location(wr, offset, out, checksum);
+ err = store_block_location(wr, *location, out, checksum);
if (err)
return err;
- err = wr->file->write_at(wr->file, offset, data, size);
+ err = wr->file->write_at(wr->file, *location, data, size);
if (err)
return err;
-
- wr->blocks_written = wr->num_blocks;
}
if (flags & SQFS_BLK_ALIGN) {
@@ -228,7 +207,7 @@ static int write_data_block(sqfs_block_writer_t *base, void *user,
}
if (flags & SQFS_BLK_LAST_BLOCK) {
- count = wr->num_blocks - wr->file_start;
+ count = wr->blocks.used - wr->file_start;
if (count == 0) {
*location = 0;
@@ -237,26 +216,22 @@ static int write_data_block(sqfs_block_writer_t *base, void *user,
if (err)
return err;
- offset = wr->blocks[start].offset;
+ *location = ((blk_info_t *)
+ wr->blocks.data)[start].offset;
- *location = offset;
if (start >= wr->file_start)
return 0;
- offset = start + count;
- if (offset >= wr->file_start) {
- count = wr->num_blocks - offset;
- wr->num_blocks = offset;
+ if (count >= (wr->file_start - start)) {
+ wr->blocks.used = start + count;
} else {
- wr->num_blocks = wr->file_start;
+ wr->blocks.used = wr->file_start;
}
err = wr->file->truncate(wr->file, wr->start);
if (err)
return err;
}
-
- wr->blocks_written = wr->num_blocks;
}
return 0;
@@ -264,7 +239,7 @@ static int write_data_block(sqfs_block_writer_t *base, void *user,
static sqfs_u64 get_block_count(const sqfs_block_writer_t *wr)
{
- return ((const block_writer_default_t *)wr)->blocks_written;
+ return ((const block_writer_default_t *)wr)->blocks.used;
}
sqfs_block_writer_t *sqfs_block_writer_create(sqfs_file_t *file,
@@ -290,11 +265,8 @@ sqfs_block_writer_t *sqfs_block_writer_create(sqfs_file_t *file,
wr->flags = flags;
wr->file = file;
wr->devblksz = devblksz;
- wr->max_blocks = INIT_BLOCK_COUNT;
- wr->data_area_start = wr->file->get_size(wr->file);
- wr->blocks = alloc_array(sizeof(wr->blocks[0]), wr->max_blocks);
- if (wr->blocks == NULL) {
+ if (array_init(&(wr->blocks), sizeof(blk_info_t), INIT_BLOCK_COUNT)) {
free(wr);
return NULL;
}