* 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 UPDATER_BLOCKSET_H
#define UPDATER_BLOCKSET_H
#include <string>
#include <vector>
#ifndef SIZE_MAX
#define SIZE_MAX (~(size_t)0)
#endif
using BlockPair = std::pair<size_t, size_t>;
static constexpr int H_BLOCK_SIZE = 4096;
static constexpr int H_CMD_ARGS_LIMIT = 2;
static constexpr int H_NEW_CMD_ARGS_START = 1;
static constexpr int H_DIFF_CMD_ARGS_START = 3;
static constexpr int H_MOVE_CMD_ARGS_START = 1;
static constexpr int H_MOVE_CMD_SRC_START = 2;
static constexpr int H_MOVE_CMD_TGT_START = 4;
static constexpr int H_COPY_CMD_ARGS_START = 1;
static constexpr int H_ZERO_NUMBER = 0;
static constexpr int H_ONE_NUMBER = 1;
namespace Updater {
class Command;
class BlockSet {
public:
BlockSet();
explicit BlockSet(size_t offset);
explicit BlockSet(std::vector<BlockPair> &&pairs);
BlockSet(const std::string &blockStr, size_t offset);
~BlockSet() {}
bool ParserAndInsert(const std::string &blockStr);
bool ParserAndInsert(const std::vector<std::string> &blockToken);
size_t CountOfRanges() const;
size_t TotalBlockSize() const;
std::vector<BlockPair>::iterator Begin();
std::vector<BlockPair>::iterator End();
std::vector<BlockPair>::const_iterator CBegin() const;
std::vector<BlockPair>::const_iterator CEnd() const;
std::vector<BlockPair>::const_reverse_iterator CrBegin() const;
std::vector<BlockPair>::const_reverse_iterator CrEnd() const;
const BlockPair& operator[] (size_t index) const
{
return blocks_[index];
}
static int32_t VerifySha256(const std::vector<uint8_t> &buffer, const size_t size,
const std::string &expected, std::string &hexDigest);
static bool IsTwoBlocksOverlap(const BlockSet &source, BlockSet &target);
static void MoveBlock(std::vector<uint8_t> &target, const BlockSet &locations,
const std::vector<uint8_t> &source);
int32_t LoadTargetBuffer(const Command &cmd, std::vector<uint8_t> &buffer, size_t &blockSize, size_t pos,
std::string &srcHash);
int32_t WriteZeroToBlock(int fd, bool isErase = true);
int32_t WriteDiffToBlock(const Command &cmd, std::vector<uint8_t> &sourceBuffer, uint8_t *patchBuffer,
size_t patchLength, bool isImgDiff = true);
int32_t LoadStashBuffer(const Command &cmd, size_t &pos, const std::string &storeBase,
std::vector<uint8_t> &sourceBuffer);
int32_t LoadStreamStashBuffer(const Command &cmd, const std::string &storeBase, std::vector<uint8_t> &stash,
const std::vector<std::string> &stashTokens, const std::vector<std::string> &tokens);
size_t ReadDataFromBlock(int fd, std::vector<uint8_t> &buffer);
size_t WriteDataToBlock(int fd, std::vector<uint8_t> &buffer);
bool CompareDataFromBlock(int fd, const std::vector<uint8_t> &buffer) const;
protected:
size_t blockSize_ {0};
std::vector<BlockPair> blocks_;
size_t offset_ {0};
private:
void PushBack(BlockPair block_pair);
void ClearBlocks();
bool CheckReliablePair(BlockPair pair);
int32_t LoadSourceBuffer(const Command &cmd, size_t &pos, std::vector<uint8_t> &sourceBuffer,
bool &isOverlap, size_t &srcBlockSize);
bool CompareBlocks(const uint8_t *lhs, const uint8_t *rhs, size_t size) const;
};
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
int32_t BlockVerify(const Command &cmd, std::vector<uint8_t> &buffer,
const size_t size, const std::string srcHash, size_t &pos);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
}
#endif