update_engine: Merge contiguous operations.

Merges operations of type SOURCE_COPY, REPLACE, or REPLACE_BZ if they
have the same type, are contiguous, have only one destination extent,
and their combined block count does not exceed the chunk size.

BUG=chromium:461651
TEST=`cros flash --src-image-to-delta`, checking generated payloads
using `cros payload show --list_ops`, unit tests.
CQ-DEPEND=CL:269134

Change-Id: I5f71e6828561f2e0a6a8ab3e3aae4c362ea2ddde
Reviewed-on: https://chromium-review.googlesource.com/269604
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Allie Wood <alliewood@chromium.org>
Trybot-Ready: Allie Wood <alliewood@chromium.org>
Tested-by: Allie Wood <alliewood@chromium.org>
diff --git a/payload_generator/annotated_operation.cc b/payload_generator/annotated_operation.cc
index 0e73479..7f8a36c 100644
--- a/payload_generator/annotated_operation.cc
+++ b/payload_generator/annotated_operation.cc
@@ -8,6 +8,8 @@
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/stringprintf.h>
 
+#include "update_engine/utils.h"
+
 using std::string;
 
 namespace chromeos_update_engine {
@@ -36,6 +38,18 @@
   }
 }
 
+bool AnnotatedOperation::SetOperationBlob(chromeos::Blob* blob, int data_fd,
+                                          off_t* data_file_size) {
+  TEST_AND_RETURN_FALSE(utils::PWriteAll(data_fd,
+                                         blob->data(),
+                                         blob->size(),
+                                         *data_file_size));
+  op.set_data_length(blob->size());
+  op.set_data_offset(*data_file_size);
+  *data_file_size += blob->size();
+  return true;
+}
+
 string InstallOperationTypeName(
     DeltaArchiveManifest_InstallOperation_Type op_type) {
   switch (op_type) {