* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IMGAE_DIFF_H
#define IMGAE_DIFF_H
#include <iostream>
#include <memory>
#include <vector>
#include "blocks_diff.h"
#include "update_diff.h"
namespace UpdatePatch {
struct ImageBlock {
int32_t type;
PatchBuffer newInfo;
PatchBuffer oldInfo;
size_t srcOriginalLength;
size_t destOriginalLength;
std::vector<uint8_t> patchData;
std::vector<uint8_t> srcOriginalData;
std::vector<uint8_t> destOriginalData;
};
class ImageDiff {
public:
ImageDiff() = delete;
ImageDiff(size_t limit, UpdateDiff::ImageParserPtr newParser, UpdateDiff::ImageParserPtr oldParser)
: limit_(limit), newParser_(newParser), oldParser_(oldParser) {}
virtual ~ImageDiff()
{
updateBlocks_.clear();
}
virtual int32_t MakePatch(const std::string &patchName);
virtual int32_t WriteHeader(std::ofstream &patchFile,
std::fstream &blockPatchFile, size_t &dataOffset, ImageBlock &block) const;
protected:
int32_t SplitImage(const PatchBuffer &oldInfo, const PatchBuffer &newInfo);
int32_t DiffImage(const std::string &patchName);
int32_t MakeBlockPatch(ImageBlock &block, std::fstream &blockPatchFile,
const BlockBuffer &newInfo, const BlockBuffer &oldInfo, size_t &patchSize) const;
int32_t WritePatch(std::ofstream &patchFile, std::fstream &blockPatchFile);
size_t limit_;
std::vector<ImageBlock> updateBlocks_ {};
UpdateDiff::ImageParserPtr newParser_ {nullptr};
UpdateDiff::ImageParserPtr oldParser_ {nullptr};
bool usePatchFile_ { false };
};
class CompressedImageDiff : public ImageDiff {
public:
CompressedImageDiff(size_t limit,
UpdateDiff::ImageParserPtr newParser, UpdateDiff::ImageParserPtr oldParser, int32_t type)
: ImageDiff(limit, newParser, oldParser), type_(type) {}
~CompressedImageDiff() override {}
int32_t MakePatch(const std::string &patchName) override;
protected:
virtual int32_t TestAndSetConfig(const BlockBuffer &buffer, const std::string &fileName) = 0;
int32_t DiffFile(const std::string &fileName, size_t &oldOffset, size_t &newOffset);
void UpdateBlocks(const BlockBuffer &orgNewBuffer, const Hpackage::FileInfo *newFileInfo,
const BlockBuffer &orgOldBuffer, const Hpackage::FileInfo *oldFileInfo,
std::pair<std::vector<uint8_t>, std::vector<uint8_t>> &buffer);
int32_t CompressData(Hpackage::PkgManager::FileInfoPtr info,
const BlockBuffer &buffer, std::vector<uint8_t> &outData, size_t &outSize) const;
int32_t type_;
};
class ZipImageDiff : public CompressedImageDiff {
public:
ZipImageDiff(size_t limit, UpdateDiff::ImageParserPtr newParser, UpdateDiff::ImageParserPtr oldParser)
: CompressedImageDiff(limit, newParser, oldParser, BLOCK_DEFLATE) {}
~ZipImageDiff() override {}
int32_t WriteHeader(std::ofstream &patchFile,
std::fstream &blockPatchFile, size_t &dataOffset, ImageBlock &block) const override;
protected:
int32_t TestAndSetConfig(const BlockBuffer &buffer, const std::string &fileName) override;
int32_t method_ = 0;
int32_t level_ = 0;
int32_t windowBits_ = 0;
int32_t memLevel_ = 0;
int32_t strategy_ = 0;
};
class Lz4ImageDiff : public CompressedImageDiff {
public:
Lz4ImageDiff(size_t limit, UpdateDiff::ImageParserPtr newParser, UpdateDiff::ImageParserPtr oldParser)
: CompressedImageDiff(limit, newParser, oldParser, BLOCK_LZ4) {}
~Lz4ImageDiff() override {}
int32_t WriteHeader(std::ofstream &patchFile,
std::fstream &blockPatchFile, size_t &dataOffset, ImageBlock &block) const override;
protected:
int32_t TestAndSetConfig(const BlockBuffer &buffer, const std::string &fileName) override;
private:
int32_t method_ {0};
int32_t compressionLevel_ {0};
int32_t blockIndependence_ {0};
int32_t contentChecksumFlag_ {0};
int32_t blockSizeID_ {0};
int32_t autoFlush_ {1};
};
class GZipImageDiff : public ZipImageDiff {
public:
GZipImageDiff(size_t limit, UpdateDiff::ImageParserPtr newParser, UpdateDiff::ImageParserPtr oldParser)
: ZipImageDiff(limit, newParser, oldParser) {}
~GZipImageDiff() override {}
};
}
#endif