1*a3a45f30SXin Li // Copyright 2017 The Chromium OS Authors. All rights reserved. 2*a3a45f30SXin Li // Use of this source code is governed by a BSD-style license that can be 3*a3a45f30SXin Li // found in the LICENSE file. 4*a3a45f30SXin Li 5*a3a45f30SXin Li #ifndef _BSDIFF_SPLIT_PATCH_WRITER_H_ 6*a3a45f30SXin Li #define _BSDIFF_SPLIT_PATCH_WRITER_H_ 7*a3a45f30SXin Li 8*a3a45f30SXin Li #include <stdint.h> 9*a3a45f30SXin Li 10*a3a45f30SXin Li #include <vector> 11*a3a45f30SXin Li 12*a3a45f30SXin Li #include "bsdiff/patch_writer_interface.h" 13*a3a45f30SXin Li 14*a3a45f30SXin Li namespace bsdiff { 15*a3a45f30SXin Li 16*a3a45f30SXin Li // A PatchWriterInterface class that splits the output patch into multiple 17*a3a45f30SXin Li // patches of a fixed new-file size. The size of each patch data will depend on 18*a3a45f30SXin Li // the contents of the new file data, and won't necessarily be uniform. 19*a3a45f30SXin Li class SplitPatchWriter : public PatchWriterInterface { 20*a3a45f30SXin Li public: 21*a3a45f30SXin Li // Create a PatchWriter that will split the patch in several patches where 22*a3a45f30SXin Li // each one will write |new_chunk_size| bytes of new file data. Each patch 23*a3a45f30SXin Li // will use the old file as a whole input file. SplitPatchWriter(uint64_t new_chunk_size,const std::vector<PatchWriterInterface * > & patches)24*a3a45f30SXin Li SplitPatchWriter(uint64_t new_chunk_size, 25*a3a45f30SXin Li const std::vector<PatchWriterInterface*>& patches) 26*a3a45f30SXin Li : new_chunk_size_(new_chunk_size), patches_(patches) { 27*a3a45f30SXin Li diff_sizes_.resize(patches.size()); 28*a3a45f30SXin Li extra_sizes_.resize(patches.size()); 29*a3a45f30SXin Li } 30*a3a45f30SXin Li 31*a3a45f30SXin Li // PatchWriterInterface overrides. 32*a3a45f30SXin Li // Note: Calling WriteDiffStream/WriteExtraStream before calling the 33*a3a45f30SXin Li // corresponding AddControlEntry() is not supported and will fail. The reason 34*a3a45f30SXin Li // for this is because which underlying patch takes the bytes depends on the 35*a3a45f30SXin Li // control entries. 36*a3a45f30SXin Li bool Init(size_t new_size) override; 37*a3a45f30SXin Li bool WriteDiffStream(const uint8_t* data, size_t size) override; 38*a3a45f30SXin Li bool WriteExtraStream(const uint8_t* data, size_t size) override; 39*a3a45f30SXin Li bool AddControlEntry(const ControlEntry& entry) override; 40*a3a45f30SXin Li bool Close() override; 41*a3a45f30SXin Li 42*a3a45f30SXin Li private: 43*a3a45f30SXin Li // Add a ControlEntry to the |current_patch_| without splitting it. Updates 44*a3a45f30SXin Li // the internal structures of used data. 45*a3a45f30SXin Li bool AddControlEntryToCurrentPatch(const ControlEntry& entry); 46*a3a45f30SXin Li 47*a3a45f30SXin Li using WriteStreamMethod = bool (PatchWriterInterface::*)(const uint8_t* data, 48*a3a45f30SXin Li size_t size); 49*a3a45f30SXin Li 50*a3a45f30SXin Li // Write to the diff or extra stream as determined by |method|. 51*a3a45f30SXin Li bool WriteToStream(WriteStreamMethod method, 52*a3a45f30SXin Li std::vector<size_t>* sizes_vector, 53*a3a45f30SXin Li const uint8_t* data, 54*a3a45f30SXin Li size_t size); 55*a3a45f30SXin Li 56*a3a45f30SXin Li // The size of the new file for the patch we are writing. 57*a3a45f30SXin Li size_t new_size_{0}; 58*a3a45f30SXin Li 59*a3a45f30SXin Li // The size of each chunk of the new file written to. 60*a3a45f30SXin Li uint64_t new_chunk_size_; 61*a3a45f30SXin Li std::vector<PatchWriterInterface*> patches_; 62*a3a45f30SXin Li 63*a3a45f30SXin Li // The size of the diff and extra streams that should go in each patch and has 64*a3a45f30SXin Li // been written so far. 65*a3a45f30SXin Li std::vector<size_t> diff_sizes_; 66*a3a45f30SXin Li std::vector<size_t> extra_sizes_; 67*a3a45f30SXin Li 68*a3a45f30SXin Li // The current patch number in the |patches_| array we are writing to. 69*a3a45f30SXin Li size_t current_patch_{0}; 70*a3a45f30SXin Li 71*a3a45f30SXin Li // The number of patches we already called Close() on. The patches are always 72*a3a45f30SXin Li // closed in order. 73*a3a45f30SXin Li size_t closed_patches_{0}; 74*a3a45f30SXin Li 75*a3a45f30SXin Li // Bytes of the new files already written. Needed to store the new length in 76*a3a45f30SXin Li // the header of the file. 77*a3a45f30SXin Li uint64_t written_output_{0}; 78*a3a45f30SXin Li 79*a3a45f30SXin Li // The current pointer into the old stream. 80*a3a45f30SXin Li uint64_t old_pos_{0}; 81*a3a45f30SXin Li }; 82*a3a45f30SXin Li 83*a3a45f30SXin Li } // namespace bsdiff 84*a3a45f30SXin Li 85*a3a45f30SXin Li #endif // _BSDIFF_SPLIT_PATCH_WRITER_H_ 86