AU: Optionally limit the size of delta update operations.

Add a --chunk_size flag to delta_generator. If it's not -1, files will
be split into chunks of this size when generating delta payloads. This
effectively limits the size of each delta operation.

BUG=chromium:229797
TEST=unit tests; generated delta payloads and checked them through
paycheck.py.

Change-Id: I21502118088bfbac75aa8009eb144f6aaf23a83a
Reviewed-on: https://gerrit.chromium.org/gerrit/48357
Commit-Queue: Darin Petkov <petkov@chromium.org>
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Darin Petkov <petkov@chromium.org>
diff --git a/utils_unittest.cc b/utils_unittest.cc
index 39c8ad7..ec58046 100644
--- a/utils_unittest.cc
+++ b/utils_unittest.cc
@@ -10,6 +10,8 @@
 #include <string>
 #include <vector>
 
+#include <base/file_path.h>
+#include <base/file_util.h>
 #include <base/string_util.h>
 #include <base/stringprintf.h>
 #include <gtest/gtest.h>
@@ -69,6 +71,27 @@
   EXPECT_FALSE(utils::ReadFile("/this/doesn't/exist", &empty));
 }
 
+TEST(UtilsTest, ReadFileChunk) {
+  FilePath file;
+  EXPECT_TRUE(file_util::CreateTemporaryFile(&file));
+  ScopedPathUnlinker unlinker(file.value());
+  vector<char> data;
+  const size_t kSize = 1024 * 1024;
+  for (size_t i = 0; i < kSize; i++) {
+    data.push_back(i % 255);
+  }
+  EXPECT_TRUE(utils::WriteFile(file.value().c_str(), &data[0], data.size()));
+  vector<char> in_data;
+  EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), kSize, 10, &in_data));
+  EXPECT_TRUE(in_data.empty());
+  EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), 0, -1, &in_data));
+  EXPECT_TRUE(data == in_data);
+  in_data.clear();
+  EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), 10, 20, &in_data));
+  EXPECT_TRUE(vector<char>(data.begin() + 10, data.begin() + 10 + 20) ==
+              in_data);
+}
+
 TEST(UtilsTest, ErrnoNumberAsStringTest) {
   EXPECT_EQ("No such file or directory", utils::ErrnoNumberAsString(ENOENT));
 }