libsparse: Split off most of sparse_file_read_normal into a helper function

This carves out the core of sparse_file_read_normal and splits it off so
it can be reused in the next patch. No functional change intended.

Change-Id: Id00491fd7e5bb6fa28c517a0bb32b8b506539d4d
diff --git a/libsparse/sparse_read.cpp b/libsparse/sparse_read.cpp
index c4c1823..c2f8859 100644
--- a/libsparse/sparse_read.cpp
+++ b/libsparse/sparse_read.cpp
@@ -410,12 +410,10 @@
   return 0;
 }
 
-static int sparse_file_read_normal(struct sparse_file* s, int fd) {
+static int do_sparse_file_read_normal(struct sparse_file* s, int fd, uint32_t* buf, int64_t offset,
+                                      int64_t remain) {
   int ret;
-  uint32_t* buf = (uint32_t*)malloc(s->block_size);
-  unsigned int block = 0;
-  int64_t remain = s->len;
-  int64_t offset = 0;
+  unsigned int block = offset / s->block_size;
   unsigned int to_read;
   unsigned int i;
   bool sparse_block;
@@ -429,7 +427,6 @@
     ret = read_all(fd, buf, to_read);
     if (ret < 0) {
       error("failed to read sparse file");
-      free(buf);
       return ret;
     }
 
@@ -457,10 +454,21 @@
     block++;
   }
 
-  free(buf);
   return 0;
 }
 
+static int sparse_file_read_normal(struct sparse_file* s, int fd) {
+  int ret;
+  uint32_t* buf = (uint32_t*)malloc(s->block_size);
+
+  if (!buf)
+    return -ENOMEM;
+
+  ret = do_sparse_file_read_normal(s, fd, buf, 0, s->len);
+  free(buf);
+  return ret;
+}
+
 int sparse_file_read(struct sparse_file* s, int fd, bool sparse, bool crc) {
   if (crc && !sparse) {
     return -EINVAL;