1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef UPDATE_PATCH_H
17#define UPDATE_PATCH_H
18#include <fstream>
19#include <iostream>
20#include "package/pkg_manager.h"
21#include "openssl/sha.h"
22
23namespace UpdatePatch {
24struct PatchParam {
25    uint8_t* oldBuff;
26    size_t oldSize;
27    uint8_t* patch;
28    size_t patchSize;
29};
30
31struct PatchBuffer {
32    uint8_t *buffer;
33    size_t start;
34    size_t length;
35};
36
37using BlockBuffer = Hpackage::PkgBuffer;
38
39class UpdatePatchWriter {
40public:
41    UpdatePatchWriter() = default;
42    virtual ~UpdatePatchWriter() {}
43
44    virtual int32_t Init() = 0;
45    virtual int32_t Write(size_t start, const BlockBuffer &buffer, size_t len) = 0;
46    virtual int32_t Finish() = 0;
47};
48
49using UpdatePatchWriterPtr = UpdatePatchWriter *;
50
51class UpdateApplyPatch {
52public:
53    using ImageProcessor = std::function<int(size_t start, const BlockBuffer &data, size_t size)>;
54
55    static int32_t ApplyImagePatch(const PatchParam &param, const std::vector<uint8_t> &bonusData,
56        ImageProcessor writer, const std::string& expected);
57    static int32_t ApplyImagePatch(const PatchParam &param,
58        UpdatePatchWriterPtr writer, const std::vector<uint8_t> &bonusData);
59    static bool PreCheck(const PatchParam &param, const UpdatePatchWriterPtr writer);
60    static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo,
61        const BlockBuffer &oldInfo, UpdatePatchWriterPtr writer);
62    static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo,
63        const BlockBuffer &oldInfo, ImageProcessor writer, const std::string& expected);
64    static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo,
65        const BlockBuffer &oldInfo, std::vector<uint8_t> &newData);
66    static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo,
67        Hpackage::PkgManager::StreamPtr stream, UpdatePatchWriterPtr writer);
68    static int32_t ApplyPatch(const std::string &patchName, const std::string &oldfile, const std::string &newFile);
69};
70
71class FilePatchWriter : public UpdatePatchWriter {
72public:
73    FilePatchWriter(const std::string &newFileName) : UpdatePatchWriter(), newFileName_(newFileName) {}
74    ~FilePatchWriter() override {}
75
76    int32_t Init() override;
77    int32_t Write(size_t start, const BlockBuffer &buffer, size_t len) override;
78    int32_t Finish() override;
79private:
80    bool init_ { false };
81    std::string newFileName_;
82    std::ofstream stream_;
83};
84
85class ImagePatchWriter : public UpdatePatchWriter {
86public:
87    ImagePatchWriter(UpdateApplyPatch::ImageProcessor writer,
88        const std::string &expected, const std::string &partitionName) : UpdatePatchWriter(),
89        writer_(writer), expected_(expected), partitionName_(partitionName) {}
90    ~ImagePatchWriter() override {}
91
92    int32_t Init() override;
93    int32_t Write(size_t start, const BlockBuffer &buffer, size_t len) override;
94    int32_t Finish() override;
95private:
96    bool init_ { false };
97    SHA256_CTX sha256Ctx_ {};
98    UpdateApplyPatch::ImageProcessor writer_;
99    std::string expected_;
100    std::string partitionName_;
101};
102} // namespace UpdatePatch
103#endif // UPDATE_PATCH_H
104