* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ------------------------------------------------------------------------- */
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <sstream>
#include <thread>
#include "utility/serializer.h"
#include "file_mapping.h"
namespace {
using namespace Sanitizer;
using FileMapType = FileMapping::FileMapType;
struct Stream {
std::vector<char> buffer;
std::size_t offset;
};
* 到不满足谓语的字符时返回 false
* @param s 要解析的字节流
* @param pred 对当前字节进行判断的谓语
* @param str 解析得到的字符串
*/
template <typename Pred>
bool ParseWhile(Stream &s, Pred pred, std::string &str)
{
std::size_t beg = s.offset;
for (; s.offset < s.buffer.size() && pred(s.buffer[s.offset]); ++s.offset) { }
if (s.offset == s.buffer.size()) {
return false;
}
str.assign(s.buffer.data() + beg, s.offset - beg);
return true;
}
* @param s 要解析的字节流
* @param ch 解析得到的字符
*/
bool ParseAnyChar(Stream &s, char &ch)
{
if (s.offset >= s.buffer.size()) {
return false;
}
ch = s.buffer[s.offset];
++s.offset;
return true;
}
* 匹配不到 nul 字符时返回 false
* @param s 要解析的字节流
* @param str 解析得到的字符串
*/
bool ParseString(Stream &s, std::string &str)
{
if (!ParseWhile(s, [](char c) { return c != '\0'; }, str)) {
return false;
}
char c;
return ParseAnyChar(s, c);
}
* @param s 要解析的字节流
* @param t 解析得到的变量
*/
template <typename T>
bool ParseType(Stream &s, T &v)
{
constexpr std::size_t size = sizeof(T);
if (s.offset + size > s.buffer.size()) {
return false;
}
if (!Deserialize<T>(std::string(s.buffer.data() + s.offset, size), v)) {
return false;
}
s.offset += size;
return true;
}
bool ParseEachPair(Stream &s, FileMapType &fileMap)
{
std::string str;
if (!ParseWhile(s, [](char c) { return c == '\0'; }, str)) {
return false;
}
std::string filename;
if (!ParseString(s, filename)) {
return false;
}
uint64_t uuid{};
if (!ParseType(s, uuid)) {
return false;
}
if (fileMap.find(uuid) == fileMap.end()) {
fileMap[uuid] = {static_cast<int16_t>(fileMap.size()), filename};
}
return true;
}
}
namespace Sanitizer {
FileInfo FileMapping::Query(uint64_t fileNo) const
{
typename FileMapType::const_iterator it = fileMap_.find(fileNo);
return it == fileMap_.cend() ? FileInfo{-1, "unknown"} : it->second;
}
void FileMapping::Load(std::vector<char> const& buffer)
{
Stream stream{buffer, 0UL};
while (ParseEachPair(stream, fileMap_)) { }
}
}