| // 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_ |