From 88d82f90cbdfa5017524c6a26a25b7ff2c43f2a3 Mon Sep 17 00:00:00 2001
From: "raphael.bach" <raphael.bach@etu.hesge.ch>
Date: Sat, 19 Jan 2019 22:52:31 +0100
Subject: [PATCH] Add Sparse_WriteImage() in sparse.h

---
 include/sparse.h |  4 ++++
 src/sparse.c     | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/include/sparse.h b/include/sparse.h
index 96c9bd7..3f113d6 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 d0b78ff..da55612 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()
 ------------------------------------------------------------------------------*/
-- 
GitLab