diff options
Diffstat (limited to 'lib/sqfshelper')
| -rw-r--r-- | lib/sqfshelper/data_writer.c | 21 | ||||
| -rw-r--r-- | lib/sqfshelper/io_stdin.c | 67 | 
2 files changed, 69 insertions, 19 deletions
| diff --git a/lib/sqfshelper/data_writer.c b/lib/sqfshelper/data_writer.c index 96cd9ee..a365e6d 100644 --- a/lib/sqfshelper/data_writer.c +++ b/lib/sqfshelper/data_writer.c @@ -98,9 +98,8 @@ static int add_sentinel_block(data_writer_t *data, sqfs_inode_generic_t *inode,  	return sqfs_data_writer_enqueue(data->proc, blk);  } -int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, -				   sqfs_inode_generic_t *inode, -				   const sqfs_sparse_map_t *map, int flags) +int write_data_from_file(data_writer_t *data, sqfs_inode_generic_t *inode, +			 sqfs_file_t *file, int flags)  {  	uint32_t blk_flags = SQFS_BLK_FIRST_BLOCK;  	uint64_t filesz, offset; @@ -123,14 +122,8 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file,  			diff = filesz - offset;  		} -		if (map == NULL) { -			ret = sqfs_file_create_block(file, offset, diff, inode, -						     blk_flags, &blk); -		} else { -			ret = sqfs_file_create_block_dense(file, offset, diff, -							   inode, blk_flags, -							   map, &blk); -		} +		ret = sqfs_file_create_block(file, offset, diff, inode, +					     blk_flags, &blk);  		if (ret)  			return -1; @@ -189,12 +182,6 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file,  	return 0;  } -int write_data_from_file(data_writer_t *data, sqfs_inode_generic_t *inode, -			 sqfs_file_t *file, int flags) -{ -	return write_data_from_file_condensed(data, file, inode, NULL, flags); -} -  data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp,  				  sqfs_file_t *file, size_t devblksize,  				  unsigned int num_jobs, size_t max_backlog) diff --git a/lib/sqfshelper/io_stdin.c b/lib/sqfshelper/io_stdin.c index 6cb45d4..8568f5e 100644 --- a/lib/sqfshelper/io_stdin.c +++ b/lib/sqfshelper/io_stdin.c @@ -11,12 +11,14 @@  #include <stdlib.h>  #include <unistd.h> +#include <string.h>  #include <errno.h>  typedef struct {  	sqfs_file_t base; +	const sparse_map_t *map;  	uint64_t offset;  	uint64_t size;  } sqfs_file_stdin_t; @@ -78,6 +80,60 @@ static int stdin_read_at(sqfs_file_t *base, uint64_t offset,  	return 0;  } +static int stdin_read_condensed(sqfs_file_t *base, uint64_t offset, +				void *buffer, size_t size) +{ +	sqfs_file_stdin_t *file = (sqfs_file_stdin_t *)base; +	uint64_t poffset = 0, src_start; +	size_t dst_start, diff, count; +	const sparse_map_t *it; +	int err; + +	memset(buffer, 0, size); + +	for (it = file->map; it != NULL; it = it->next) { +		if (it->offset + it->count <= offset) { +			poffset += it->count; +			continue; +		} + +		if (it->offset >= offset + size) { +			poffset += it->count; +			continue; +		} + +		count = size; + +		if (offset + count >= it->offset + it->count) +			count = it->offset + it->count - offset; + +		if (it->offset < offset) { +			diff = offset - it->offset; + +			src_start = poffset + diff; +			dst_start = 0; +			count -= diff; +		} else if (it->offset > offset) { +			diff = it->offset - offset; + +			src_start = poffset; +			dst_start = diff; +		} else { +			src_start = poffset; +			dst_start = 0; +		} + +		err = stdin_read_at(base, src_start, +				    (char *)buffer + dst_start, count); +		if (err) +			return err; + +		poffset += it->count; +	} + +	return 0; +} +  static int stdin_write_at(sqfs_file_t *base, uint64_t offset,  			  const void *buffer, size_t size)  { @@ -96,7 +152,7 @@ static int stdin_truncate(sqfs_file_t *base, uint64_t size)  	return SQFS_ERROR_IO;  } -sqfs_file_t *sqfs_get_stdin_file(uint64_t size) +sqfs_file_t *sqfs_get_stdin_file(const sparse_map_t *map, uint64_t size)  {  	sqfs_file_stdin_t *file = calloc(1, sizeof(*file));  	sqfs_file_t *base = (sqfs_file_t *)file; @@ -105,10 +161,17 @@ sqfs_file_t *sqfs_get_stdin_file(uint64_t size)  		return NULL;  	file->size = size; +	file->map = map; +  	base->destroy = stdin_destroy; -	base->read_at = stdin_read_at;  	base->write_at = stdin_write_at;  	base->get_size = stdin_get_size;  	base->truncate = stdin_truncate; + +	if (map == NULL) { +		base->read_at = stdin_read_at; +	} else { +		base->read_at = stdin_read_condensed; +	}  	return base;  } | 
