• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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