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