| // 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_SPLIT_PATCH_WRITER_H_ |
| #define _BSDIFF_SPLIT_PATCH_WRITER_H_ |
| |
| #include <stdint.h> |
| |
| #include <vector> |
| |
| #include "bsdiff/patch_writer_interface.h" |
| |
| namespace bsdiff { |
| |
| // A PatchWriterInterface class that splits the output patch into multiple |
| // patches of a fixed new-file size. The size of each patch data will depend on |
| // the contents of the new file data, and won't necessarily be uniform. |
| class SplitPatchWriter : public PatchWriterInterface { |
| public: |
| // Create a PatchWriter that will split the patch in several patches where |
| // each one will write |new_chunk_size| bytes of new file data. Each patch |
| // will use the old file as a whole input file. |
| SplitPatchWriter(uint64_t new_chunk_size, |
| const std::vector<PatchWriterInterface*>& patches) |
| : new_chunk_size_(new_chunk_size), patches_(patches) { |
| diff_sizes_.resize(patches.size()); |
| extra_sizes_.resize(patches.size()); |
| } |
| |
| // PatchWriterInterface overrides. |
| // Note: Calling WriteDiffStream/WriteExtraStream before calling the |
| // corresponding AddControlEntry() is not supported and will fail. The reason |
| // for this is because which underlying patch takes the bytes depends on the |
| // control entries. |
| bool Init(size_t new_size) override; |
| bool WriteDiffStream(const uint8_t* data, size_t size) override; |
| bool WriteExtraStream(const uint8_t* data, size_t size) override; |
| bool AddControlEntry(const ControlEntry& entry) override; |
| bool Close() override; |
| |
| private: |
| // Add a ControlEntry to the |current_patch_| without splitting it. Updates |
| // the internal structures of used data. |
| bool AddControlEntryToCurrentPatch(const ControlEntry& entry); |
| |
| using WriteStreamMethod = bool (PatchWriterInterface::*)(const uint8_t* data, |
| size_t size); |
| |
| // Write to the diff or extra stream as determined by |method|. |
| bool WriteToStream(WriteStreamMethod method, |
| std::vector<size_t>* sizes_vector, |
| const uint8_t* data, |
| size_t size); |
| |
| // The size of the new file for the patch we are writing. |
| size_t new_size_{0}; |
| |
| // The size of each chunk of the new file written to. |
| uint64_t new_chunk_size_; |
| std::vector<PatchWriterInterface*> patches_; |
| |
| // The size of the diff and extra streams that should go in each patch and has |
| // been written so far. |
| std::vector<size_t> diff_sizes_; |
| std::vector<size_t> extra_sizes_; |
| |
| // The current patch number in the |patches_| array we are writing to. |
| size_t current_patch_{0}; |
| |
| // The number of patches we already called Close() on. The patches are always |
| // closed in order. |
| size_t closed_patches_{0}; |
| |
| // Bytes of the new files already written. Needed to store the new length in |
| // the header of the file. |
| uint64_t written_output_{0}; |
| |
| // The current pointer into the old stream. |
| uint64_t old_pos_{0}; |
| }; |
| |
| } // namespace bsdiff |
| |
| #endif // _BSDIFF_SPLIT_PATCH_WRITER_H_ |