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#ifndef UPDATER_BLOCKSET_H
16#define UPDATER_BLOCKSET_H
17
18#include <string>
19#include <vector>
20
21#ifndef SIZE_MAX
22#define SIZE_MAX (~(size_t)0)
23#endif
24
25using BlockPair = std::pair<size_t, size_t>;
26static constexpr int H_BLOCK_SIZE = 4096;
27static constexpr int H_CMD_ARGS_LIMIT = 2;
28static constexpr int H_DIFF_CMD_ARGS_START = 3;
29static constexpr int H_MOVE_CMD_ARGS_START = 1;
30static constexpr int H_ZERO_NUMBER = 0;
31
32
33namespace Updater {
34class Command;
35
36class BlockSet {
37public:
38    BlockSet()
39    {
40        blockSize_ = 0;
41    }
42
43    explicit BlockSet(std::vector<BlockPair> &&pairs);
44
45    ~BlockSet() {}
46
47    // Insert block to set after parsing from a string type or vector type
48    bool ParserAndInsert(const std::string &blockStr);
49
50    bool ParserAndInsert(const std::vector<std::string> &blockToken);
51
52    // Get a number of ranges
53    size_t CountOfRanges() const;
54
55    // Get total size of blocks
56    size_t TotalBlockSize() const;
57
58    // Get begin iterator of blocks
59    std::vector<BlockPair>::iterator Begin();
60
61    // Get end iterator of blocks
62    std::vector<BlockPair>::iterator End();
63
64    // Get const begin iterator of blocks
65    std::vector<BlockPair>::const_iterator CBegin() const;
66
67    // Get const end iterator of blocks
68    std::vector<BlockPair>::const_iterator CEnd() const;
69
70    std::vector<BlockPair>::const_reverse_iterator CrBegin() const;
71
72    std::vector<BlockPair>::const_reverse_iterator CrEnd() const;
73
74    // Get a block by index
75    const BlockPair& operator[] (size_t index) const
76    {
77        return blocks_[index];
78    }
79
80    static int32_t VerifySha256(const std::vector<uint8_t> &buffer, const size_t size,
81        const std::string &expected);
82
83    static bool IsTwoBlocksOverlap(const BlockSet &source, BlockSet &target);
84
85    static void MoveBlock(std::vector<uint8_t> &target, const BlockSet &locations,
86        const std::vector<uint8_t> &source);
87
88    int32_t LoadTargetBuffer(const Command &cmd, std::vector<uint8_t> &buffer, size_t &blockSize, size_t pos,
89        std::string &srcHash);
90    int32_t WriteZeroToBlock(int fd, bool isErase = true);
91
92    int32_t WriteDiffToBlock(const Command &cmd, std::vector<uint8_t> &sourceBuffer, uint8_t *patchBuffer,
93                             size_t patchLength, bool isImgDiff = true);
94
95    // Read data from block
96    size_t ReadDataFromBlock(int fd, std::vector<uint8_t> &buffer);
97
98    // write data to block
99    size_t WriteDataToBlock(int fd, std::vector<uint8_t> &buffer);
100
101protected:
102    size_t blockSize_;
103    std::vector<BlockPair> blocks_;
104
105private:
106    void PushBack(BlockPair block_pair);
107    void ClearBlocks();
108    bool CheckReliablePair(BlockPair pair);
109    int32_t LoadSourceBuffer(const Command &cmd, size_t &pos, std::vector<uint8_t> &sourceBuffer,
110        bool &isOverlap, size_t &srcBlockSize);
111};
112
113#ifdef __cplusplus
114#if __cplusplus
115extern "C" {
116#endif
117#endif /* __cpluscplus */
118int32_t BlockVerify(const Command &cmd, std::vector<uint8_t> &buffer,
119    const size_t size, const std::string srcHash, size_t &pos);
120#ifdef __cplusplus
121#if __cplusplus
122}
123#endif
124#endif /* __cpluscplus */
125
126} // namespace Updater
127#endif // UPDATER_BLOCKSET_H
128