86 lines
3.1 KiB
C
86 lines
3.1 KiB
C
|
// 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_
|