update_engine: Remove sparse hole extents.

Whenever there is an extent beginning with a sparse hole, that extent
will be filtered out. Extents are now read in from the partition rather
than the file itself in ReadFileToDiff. src/dst_length are set to the
number of blocks in src/dst_extents * block_size.

This was tested manually with _GenerateSinglePayload to generate a delta
payload between test images.

BUG=chromium:469792,chromium:474497
TEST=`FEATURES=test emerge-link update_engine` and manual testing.

Change-Id: I384ec3f16f7fd9087159817358308f22d29e9edf
Reviewed-on: https://chromium-review.googlesource.com/264442
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Commit-Queue: Allie Wood <alliewood@chromium.org>
Tested-by: Allie Wood <alliewood@chromium.org>
diff --git a/utils.cc b/utils.cc
index c076682..31b25af 100644
--- a/utils.cc
+++ b/utils.cc
@@ -1691,6 +1691,32 @@
   return false;
 }
 
+bool ReadExtents(const std::string& path, vector<Extent>* extents,
+                 chromeos::Blob* out_data, ssize_t out_data_size,
+                 size_t block_size) {
+  chromeos::Blob data(out_data_size);
+  ssize_t bytes_read = 0;
+  int fd = open(path.c_str(), O_RDONLY);
+  TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
+  ScopedFdCloser fd_closer(&fd);
+
+  for (const Extent& extent : *extents) {
+    ssize_t bytes_read_this_iteration = 0;
+    ssize_t bytes = extent.num_blocks() * block_size;
+    TEST_AND_RETURN_FALSE(bytes_read + bytes <= out_data_size);
+    TEST_AND_RETURN_FALSE(utils::PReadAll(fd,
+                                          &data[bytes_read],
+                                          bytes,
+                                          extent.start_block() * block_size,
+                                          &bytes_read_this_iteration));
+    TEST_AND_RETURN_FALSE(bytes_read_this_iteration == bytes);
+    bytes_read += bytes_read_this_iteration;
+  }
+  TEST_AND_RETURN_FALSE(out_data_size == bytes_read);
+  *out_data = data;
+  return true;
+}
+
 }  // namespace utils
 
 }  // namespace chromeos_update_engine