Reduce PatchWriterInterface functionality.

The recently introduced PatchWriterInterface had both the patch file
format logic and the diff/extra streams selection from the control
entries. While this simplifies the bsdiff main algorithm and makes
invalid usages of the BsdiffPatchWriter evident, writing alternative
PatchWriterInterface classes required to replicate the diff/extra
stream selection logic.

This patch splits out the diff/extra stream generation and all the
checks around those to a new helper class DiffEncoder. The public
interface PatchWriterInterface now has two methods to accept the diff
and extra stream data, and does not compute them.

Bug: 34220646
Test: Added unittests. Ran bsdiff on some pairs of files obtaining the same result as before.
Change-Id: I5f303c06f1e10910eb00dcfda38c6811977a91cf
diff --git a/diff_encoder.h b/diff_encoder.h
new file mode 100644
index 0000000..a479c81
--- /dev/null
+++ b/diff_encoder.h
@@ -0,0 +1,64 @@
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef _BSDIFF_DIFF_ENCODER_H_
+#define _BSDIFF_DIFF_ENCODER_H_
+
+#include <stdint.h>
+
+#include "bsdiff/bz2_compressor.h"
+#include "bsdiff/patch_writer_interface.h"
+
+namespace bsdiff {
+
+// Helper class to encapsulate the diff and extra stream generation logic
+// derived from the old and new file buffers. Using this class is impossible to
+// produce an invalid or incomplete bsdiff patch, since it has checks in place
+// verifying its correct usage.
+
+class DiffEncoder {
+ public:
+  // Initialize the DiffEncoder with the old and new file buffers, as well as
+  // the path writer used. The |patch| must be already initialized.
+  DiffEncoder(PatchWriterInterface* patch,
+              const uint8_t* old_buf,
+              uint64_t old_size,
+              const uint8_t* new_buf,
+              uint64_t new_size)
+      : patch_(patch),
+        old_buf_(old_buf),
+        old_size_(old_size),
+        new_buf_(new_buf),
+        new_size_(new_size) {}
+
+  // Add a new control triplet entry to the patch. The |entry.diff_size| bytes
+  // for the diff stream and the |entry.extra_size| bytes for the extra stream
+  // will be computed and added to the corresponding streams in the patch.
+  // Returns whether the operation succeeded. The operation can fail if either
+  // the old or new files are referenced out of bounds.
+  bool AddControlEntry(const ControlEntry& entry);
+
+  // Finalize the patch writing process and close the underlying patch writer.
+  bool Close();
+
+ private:
+  // Pointer to the patch we are writing to.
+  PatchWriterInterface* patch_;
+
+  // Old and new file buffers.
+  const uint8_t* old_buf_;
+  uint64_t old_size_;
+  const uint8_t* new_buf_;
+  uint64_t new_size_;
+
+  // Bytes of the new_buf_ already written.
+  uint64_t written_output_{0};
+
+  // The current position in the old buf.
+  int64_t old_pos_{0};
+};
+
+}  // namespace bsdiff
+
+#endif  // _BSDIFF_DIFF_ENCODER_H_