Files
bsdiff/split_patch_writer.h
Alex Deymo 4dadd8b443 Pass the size of the new file to the PatchWriterInterface::Init()
Most patch formats include the size of the new file in the header.
To help streaming the patch to disk while generating it, this CL
passes the size of the new file to the patch writer on initialization.

To do this, we also move the Init() call to the patch writer to the
DiffEncoder, which makes more sense since the Close() call is also made
from the DiffEnconder.

Bug: None
Test: Updated tests to check for this value.
Change-Id: Idfaedbd492d68ab6e6cb2c1cb3883947f068c3aa
2017-10-27 13:52:46 +02:00

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_