blob: 395f9993bf9cc40a3583d13790622cf4c168b72a [file] [log] [blame]
Alex Deymoe1140a22017-10-02 21:01:15 +02001// 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
14namespace 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.
19class SplitPatchWriter : public PatchWriterInterface {
20 public:
Alex Deymo30964e82017-10-26 15:41:25 +020021 // 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.
Alex Deymoe1140a22017-10-02 21:01:15 +020024 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.
Alex Deymo4dadd8b2017-10-26 16:19:33 +020036 bool Init(size_t new_size) override;
Alex Deymoe1140a22017-10-02 21:01:15 +020037 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
Alex Deymo4dadd8b2017-10-26 16:19:33 +020056 // The size of the new file for the patch we are writing.
57 size_t new_size_{0};
58
Alex Deymoe1140a22017-10-02 21:01:15 +020059 // 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_