summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2020-05-28 22:24:08 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2020-05-29 03:39:57 +0200
commitcbdfa738c245019b7b711854d03f1ed87223ba49 (patch)
treef9081722f904630f9571e0866a2a4091bec13363
parent23e06428674750c59c17ae2a22d17ecd42056b02 (diff)
Turn the sqfs_block_writer_t into an interface
This way, everything that could be done through the hooks (and more) can be done by simply providign a custom implementation. The result is a lot clener that the previous hook based version. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--include/sqfs/block_writer.h95
-rw-r--r--lib/common/statistics.c2
-rw-r--r--lib/sqfs/block_processor/common.c4
-rw-r--r--lib/sqfs/block_writer.c77
4 files changed, 94 insertions, 84 deletions
diff --git a/include/sqfs/block_writer.h b/include/sqfs/block_writer.h
index 8cfb9a2..f8bc671 100644
--- a/include/sqfs/block_writer.h
+++ b/include/sqfs/block_writer.h
@@ -29,21 +29,69 @@
*/
/**
- * @struct sqfs_block_writer_t
+ * @interface sqfs_block_writer_t
*
* @implements sqfs_object_t
*
* @brief Abstracts writing and deduplicating of data and fragment blocks.
*
- * This object is not copyable, i.e. @ref sqfs_copy will always return NULL.
+ * A default reference implementation can be obtaiend
+ * through @ref sqfs_block_writer_create. The default implementation is not
+ * copyable, i.e. @ref sqfs_copy will always return NULL.
*/
+struct sqfs_block_writer_t {
+ sqfs_object_t base;
+
+ /**
+ * @brief Submit a data block to a block writer.
+ *
+ * @memberof sqfs_block_writer_t
+ *
+ * If the @ref SQFS_BLK_FIRST_BLOCK flag is set, the data block writer
+ * memorizes the starting location and block index of the block. If the
+ * @ref SQFS_BLK_LAST_BLOCK flag is set, it uses those stored locations
+ * to do block deduplication.
+ *
+ * If the flag @ref SQFS_BLK_ALIGN is set in combination with the
+ * @ref SQFS_BLK_FIRST_BLOCK, the file size is padded to a multiple of
+ * the device block size before writing. If it is set together with the
+ * @ref SQFS_BLK_LAST_BLOCK flag, the padding is added afterwards.
+ *
+ * @param wr A pointer to a block writer.
+ * @param size The size of the block to write.
+ * @param checksum A 32 bit checksum of the block data.
+ * @param flags A combination of @ref SQFS_BLK_FLAGS flag bits
+ * describing the block.
+ * @arapm data A pointer to the data to write.
+ * @param location Returns the location where the block has been
+ * written. If the @ref SQFS_BLK_LAST_BLOCK flag was set,
+ * deduplication is performed and this returns the (new) location
+ * of the first block instead.
+ *
+ * @return Zero on success, an @ref SQFS_ERROR error on failure.
+ */
+ int (*write_data_block)(sqfs_block_writer_t *wr, sqfs_u32 size,
+ sqfs_u32 checksum, sqfs_u32 flags,
+ const sqfs_u8 *data, sqfs_u64 *location);
+
+ /**
+ * @brief Get the number of blocks actually written to disk.
+ *
+ * @memberof sqfs_block_writer_t
+ *
+ * @param wr A pointer to a block writer.
+ *
+ * @return The number of blocks written, excluding deduplicated blocks.
+ */
+ sqfs_u64 (*get_block_count)(const sqfs_block_writer_t *wr);
+};
#ifdef __cplusplus
extern "C" {
#endif
/**
- * @brief Create a block writer object.
+ * @brief Create an instance of a default block writer implementation.
*
* @memberof sqfs_block_writer_t
*
@@ -58,47 +106,6 @@ SQFS_API sqfs_block_writer_t *sqfs_block_writer_create(sqfs_file_t *file,
size_t devblksz,
sqfs_u32 flags);
-/**
- * @brief Submit a data block to a blokc writer.
- *
- * @memberof sqfs_block_writer_t
- *
- * If the @ref SQFS_BLK_FIRST_BLOCK flag is set, the data block writer
- * memorizes the starting location and block index of the block. If the
- * @ref SQFS_BLK_LAST_BLOCK flag is set, it uses those stored locations
- * to do block deduplication.
- *
- * If the flag @ref SQFS_BLK_ALIGN is set in combination with the
- * @ref SQFS_BLK_FIRST_BLOCK, the file size is padded to a multiple of the
- * device block size before writing. If it is set together with the
- * @ref SQFS_BLK_LAST_BLOCK flag, the padding is added afterwards.
- *
- * @param wr A pointer to a block writer.
- * @param block The block to write to disk next.
- * @param location Returns the location where the block has been written.
- * If the @ref SQFS_BLK_LAST_BLOCK flag was set, deduplication
- * is performed and this returns the (new) location of the
- * first block instead.
- *
- * @return Zero on success, an @ref SQFS_ERROR error on failure.
- */
-SQFS_API int sqfs_block_writer_write(sqfs_block_writer_t *wr,
- sqfs_u32 size, sqfs_u32 checksum,
- sqfs_u32 flags, const sqfs_u8 *data,
- sqfs_u64 *location);
-
-/**
- * @brief Get the number of blocks actually written to disk.
- *
- * @memberof sqfs_block_writer_t
- *
- * @param wr A pointer to a block writer.
- *
- * @return The number of blocks written, excluding deduplicated blocks.
- */
-SQFS_API
-sqfs_u64 sqfs_block_writer_get_block_count(const sqfs_block_writer_t *wr);
-
#ifdef __cplusplus
}
#endif
diff --git a/lib/common/statistics.c b/lib/common/statistics.c
index 079c1b1..82e545d 100644
--- a/lib/common/statistics.c
+++ b/lib/common/statistics.c
@@ -18,7 +18,7 @@ void sqfs_print_statistics(const sqfs_super_t *super,
size_t ratio;
proc_stats = sqfs_block_processor_get_stats(blk);
- blocks_written = sqfs_block_writer_get_block_count(wr);
+ blocks_written = wr->get_block_count(wr);
bytes_written = super->inode_table_start - sizeof(*super);
diff --git a/lib/sqfs/block_processor/common.c b/lib/sqfs/block_processor/common.c
index 757544a..e3d5486 100644
--- a/lib/sqfs/block_processor/common.c
+++ b/lib/sqfs/block_processor/common.c
@@ -68,8 +68,8 @@ int process_completed_block(sqfs_block_processor_t *proc, sqfs_block_t *blk)
sqfs_u32 size;
int err;
- err = sqfs_block_writer_write(proc->wr, blk->size, blk->checksum,
- blk->flags, blk->data, &location);
+ err = proc->wr->write_data_block(proc->wr, blk->size, blk->checksum,
+ blk->flags, blk->data, &location);
if (err)
goto out;
diff --git a/lib/sqfs/block_writer.c b/lib/sqfs/block_writer.c
index 06cbd37..a6ca4b3 100644
--- a/lib/sqfs/block_writer.c
+++ b/lib/sqfs/block_writer.c
@@ -25,8 +25,8 @@ typedef struct {
sqfs_u64 hash;
} blk_info_t;
-struct sqfs_block_writer_t {
- sqfs_object_t base;
+typedef struct {
+ sqfs_block_writer_t base;
sqfs_file_t *file;
size_t num_blocks;
@@ -39,9 +39,9 @@ struct sqfs_block_writer_t {
sqfs_u64 start;
size_t file_start;
-};
+} block_writer_default_t;
-static int store_block_location(sqfs_block_writer_t *wr, sqfs_u64 offset,
+static int store_block_location(block_writer_default_t *wr, sqfs_u64 offset,
sqfs_u32 size, sqfs_u32 chksum)
{
size_t new_sz;
@@ -64,7 +64,7 @@ static int store_block_location(sqfs_block_writer_t *wr, sqfs_u64 offset,
return 0;
}
-static size_t deduplicate_blocks(sqfs_block_writer_t *wr, size_t count)
+static size_t deduplicate_blocks(block_writer_default_t *wr, size_t count)
{
size_t i, j;
@@ -85,7 +85,7 @@ static size_t deduplicate_blocks(sqfs_block_writer_t *wr, size_t count)
return i;
}
-static int align_file(sqfs_block_writer_t *wr)
+static int align_file(block_writer_default_t *wr)
{
void *padding;
sqfs_u64 size;
@@ -111,41 +111,15 @@ static int align_file(sqfs_block_writer_t *wr)
static void block_writer_destroy(sqfs_object_t *wr)
{
- free(((sqfs_block_writer_t *)wr)->blocks);
+ free(((block_writer_default_t *)wr)->blocks);
free(wr);
}
-sqfs_block_writer_t *sqfs_block_writer_create(sqfs_file_t *file,
- size_t devblksz, sqfs_u32 flags)
-{
- sqfs_block_writer_t *wr;
-
- if (flags != 0)
- return NULL;
-
- wr = calloc(1, sizeof(*wr));
- if (wr == NULL)
- return NULL;
-
- ((sqfs_object_t *)wr)->destroy = block_writer_destroy;
- 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) {
- free(wr);
- return NULL;
- }
-
- return wr;
-}
-
-int sqfs_block_writer_write(sqfs_block_writer_t *wr, sqfs_u32 size,
+static int write_data_block(sqfs_block_writer_t *base, sqfs_u32 size,
sqfs_u32 checksum, sqfs_u32 flags,
const sqfs_u8 *data, sqfs_u64 *location)
{
+ block_writer_default_t *wr = (block_writer_default_t *)base;
size_t start, count;
sqfs_u64 offset;
sqfs_u32 out;
@@ -219,7 +193,36 @@ int sqfs_block_writer_write(sqfs_block_writer_t *wr, sqfs_u32 size,
return 0;
}
-sqfs_u64 sqfs_block_writer_get_block_count(const sqfs_block_writer_t *wr)
+static sqfs_u64 get_block_count(const sqfs_block_writer_t *wr)
{
- return wr->blocks_written;
+ return ((const block_writer_default_t *)wr)->blocks_written;
+}
+
+sqfs_block_writer_t *sqfs_block_writer_create(sqfs_file_t *file,
+ size_t devblksz, sqfs_u32 flags)
+{
+ block_writer_default_t *wr;
+
+ if (flags != 0)
+ return NULL;
+
+ wr = calloc(1, sizeof(*wr));
+ if (wr == NULL)
+ return NULL;
+
+ ((sqfs_block_writer_t *)wr)->write_data_block = write_data_block;
+ ((sqfs_block_writer_t *)wr)->get_block_count = get_block_count;
+ ((sqfs_object_t *)wr)->destroy = block_writer_destroy;
+ 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) {
+ free(wr);
+ return NULL;
+ }
+
+ return (sqfs_block_writer_t *)wr;
}