diff --git a/include/sparse.h b/include/sparse.h index 96c9bd7dffc7a7bae5bdf9244c411840e542699f..3f113d6b3dd7c54347ccc24b07250aa9e66d068d 100644 --- a/include/sparse.h +++ b/include/sparse.h @@ -120,6 +120,10 @@ void Sparse_ReadChunksHeader(struct Sparse * const sparse); Sparse_Read() ------------------------------------------------------------------------------*/ void Sparse_Read(struct Sparse * const sparse); +/*------------------------------------------------------------------------------ + Sparse_WriteImage() +------------------------------------------------------------------------------*/ +void Sparse_WriteImage(const struct Sparse * const sparse, int fd); /*------------------------------------------------------------------------------ Sparse_PrintHeader() ------------------------------------------------------------------------------*/ diff --git a/src/sparse.c b/src/sparse.c index d0b78ff7bb4270f744566b77e558b7f8cc0430eb..da556126f471327f92f46e81cdffc0521d3e7d99 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -38,7 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <errno.h> #include <inttypes.h> // PRIu16, PRIx16, PRIu32, PRIx32 #include <stdio.h> // printf() -#include <stdlib.h> // exit(), NULL +#include <stdlib.h> // malloc(), calloc(), free(), exit(), NULL #include <string.h> // strncpy(), strlen(), strerror() // Internal #include "file_io.h" @@ -171,6 +171,49 @@ void Sparse_Read(struct Sparse * const sparse) } } } +/*------------------------------------------------------------------------------ + Sparse_WriteImage() +------------------------------------------------------------------------------*/ +void Sparse_WriteImage(const struct Sparse * const sparse, int fd) +{ + assert(sparse != NULL); + for(size_t i = 0; i < sparse->header.chunk_count; i++) { + size_t write_size = 0; + char * buffer = NULL; + if(sparse->chunks[i].header.type == CHUNK_TYPE_RAW) { + write_size = sparse->chunks[i].size; + buffer = sparse->chunks[i].data; + } else if(sparse->chunks[i].header.type == CHUNK_TYPE_FILL) { + write_size = sparse->chunks[i].header.block_count * sparse->header.block_size; + buffer = malloc(write_size); + } else if(sparse->chunks[i].header.type == CHUNK_TYPE_DONT_CARE) { + write_size = sparse->chunks[i].header.block_count * sparse->header.block_size; + buffer = calloc(write_size, 1); + } else if(sparse->chunks[i].header.type == CHUNK_TYPE_CRC32) { + write_size = sparse->chunks[i].header.block_count * sparse->header.block_size; + } else { + } + if(buffer != NULL) { + if(sparse->chunks[i].header.type == CHUNK_TYPE_FILL) { + for(size_t j = 0; j < write_size; j++) { + buffer[j] = *sparse->chunks[i].data; + } + } + size_t bytes_written = FIO_Write(fd, buffer, write_size); + if(bytes_written == write_size) { + if(sparse->chunks[i].header.type != CHUNK_TYPE_RAW) { + free(buffer); + } + } else { + Log_Fatal(&s_logger, "FIO_Write(%d) failed! %s\n", sparse->fd, strerror(errno)); + exit(-1); + } + } else { + Log_Fatal(&s_logger, "malloc() : %s\n", strerror(errno)); + exit(-1); + } + } +} /*------------------------------------------------------------------------------ Sparse_PrintHeader() ------------------------------------------------------------------------------*/