LCOV - code coverage report
Current view: top level - acl/common - json_parser.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.6 % 324 274
Test Date: 2026-08-31 10:05:54 Functions: 100.0 % 16 16

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "json_parser.h"
      12              : 
      13              : #include <fstream>
      14              : #include <sstream>
      15              : #include <sys/stat.h>
      16              : #include "mmpa/mmpa_api.h"
      17              : 
      18              : namespace {
      19              : const std::string ACL_JSON_DEFAULT_DEVICE = "defaultDevice";
      20              : const std::string ACL_JSON_DEFAULT_DEVICE_ID = "default_device";
      21              : constexpr int32_t DECIMAL = 10;
      22              : 
      23            4 : bool IsDecimalDigits(const std::string& value, const size_t start)
      24              : {
      25           18 :     for (size_t i = start; i < value.size(); ++i) {
      26           15 :         if ((value[i] < '0') || (value[i] > '9')) {
      27            1 :             return false;
      28              :         }
      29              :     }
      30            3 :     return true;
      31              : }
      32              : 
      33            7 : bool IsZeroOrPositiveIntegerNoLeadingZero(const std::string& value)
      34              : {
      35            7 :     if (value.empty()) {
      36            0 :         return false;
      37              :     }
      38            7 :     if (value == "0") {
      39            4 :         return true;
      40              :     }
      41            3 :     return ((value[0] >= '1') && (value[0] <= '9') && IsDecimalDigits(value, 1U));
      42              : }
      43              : 
      44            5 : bool IsPositiveIntegerNoLeadingZero(const std::string& value)
      45              : {
      46            5 :     return (!value.empty() && (value[0] >= '1') && (value[0] <= '9') && IsDecimalDigits(value, 1U));
      47              : }
      48              : 
      49        23640 : void CountDepth(const char_t ch, size_t& objDepth, size_t& maxObjDepth, size_t& arrayDepth, size_t& maxArrayDepth)
      50              : {
      51        23640 :     switch (ch) {
      52          481 :         case '{': {
      53          481 :             ++objDepth;
      54          481 :             if (objDepth > maxObjDepth) {
      55          455 :                 maxObjDepth = objDepth;
      56              :             }
      57          481 :             break;
      58              :         }
      59          479 :         case '}': {
      60          479 :             if (objDepth > 0) {
      61          479 :                 --objDepth;
      62              :             }
      63          479 :             break;
      64              :         }
      65           75 :         case '[': {
      66           75 :             ++arrayDepth;
      67           75 :             if (arrayDepth > maxArrayDepth) {
      68           63 :                 maxArrayDepth = arrayDepth;
      69              :             }
      70           75 :             break;
      71              :         }
      72           75 :         case ']': {
      73           75 :             if (arrayDepth > 0) {
      74           75 :                 --arrayDepth;
      75              :             }
      76           75 :             break;
      77              :         }
      78        22530 :         default: {
      79        22530 :             return;
      80              :         }
      81              :     }
      82              : }
      83              : } // namespace
      84              : namespace acl {
      85              : // 配置文件最大字节数目10MBytes
      86              : constexpr int64_t MAX_CONFIG_FILE_BYTE = 10 * 1024 * 1024;
      87              : // 配置文件最大递归深度
      88              : constexpr size_t MAX_CONFIG_OBJ_DEPTH = 10U;
      89              : // 配置文件最大数组个数
      90              : constexpr size_t MAX_CONFIG_ARRAY_DEPTH = 10U;
      91              : 
      92          258 : bool JsonParser::IsValidFileName(const char_t* const fileName)
      93              : {
      94          258 :     char_t trustedPath[MMPA_MAX_PATH] = {};
      95          258 :     int32_t ret = mmRealPath(fileName, trustedPath, MMPA_MAX_PATH);
      96          258 :     if (ret != EN_OK) {
      97            4 :         const auto formatErrMsg = acl::AclGetErrorFormatMessage(mmGetErrorCode());
      98            4 :         acl::AclErrorLogManager::ReportInputError(
      99            8 :             acl::INVALID_PATH_MSG, std::vector<const char*>({"path", "reason"}),
     100            8 :             std::vector<const char*>({fileName, formatErrMsg.c_str()}));
     101            4 :         ACL_LOG_ERROR(
     102              :             "[Trans][RealPath]the file path %s is not like a real path, mmRealPath return %d, "
     103              :             "errMessage is %s",
     104              :             fileName, ret, formatErrMsg.c_str());
     105            4 :         return false;
     106            4 :     }
     107              : 
     108              :     mmStat_t pathStat;
     109          254 :     ret = mmStatGet(trustedPath, &pathStat);
     110          254 :     if (ret != EN_OK) {
     111            0 :         const auto formatErrMsg = acl::AclGetErrorFormatMessage(mmGetErrorCode());
     112            0 :         acl::AclErrorLogManager::ReportInputError(
     113            0 :             acl::INVALID_PATH_MSG, std::vector<const char*>({"path", "reason"}),
     114            0 :             std::vector<const char*>({trustedPath, formatErrMsg.c_str()}));
     115            0 :         ACL_LOG_ERROR(
     116              :             "[Get][FileStatus]cannot get config file status, which path is %s, "
     117              :             "maybe does not exist, return %d, errcode %d",
     118              :             trustedPath, ret, mmGetErrorCode());
     119            0 :         return false;
     120            0 :     }
     121          254 :     if ((pathStat.st_mode & S_IFMT) != S_IFREG) {
     122            0 :         acl::AclErrorLogManager::ReportInputError(
     123            0 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     124            0 :             std::vector<const char*>({trustedPath, "config file is not a regular file"}));
     125            0 :         ACL_LOG_ERROR(
     126              :             "[Config][ConfigFile]config file is not a regular file, which path is %s, "
     127              :             "mode is %u",
     128              :             trustedPath, pathStat.st_mode);
     129            0 :         return false;
     130              :     }
     131          254 :     if (pathStat.st_size > MAX_CONFIG_FILE_BYTE) {
     132              :         std::string reason = acl::AclErrorLogManager::FormatStr(
     133            0 :             "file size %ld exceeds maximum allowed size %ld", pathStat.st_size, MAX_CONFIG_FILE_BYTE);
     134            0 :         acl::AclErrorLogManager::ReportInputError(
     135            0 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     136            0 :             std::vector<const char*>({trustedPath, reason.c_str()}));
     137            0 :         ACL_LOG_ERROR(
     138              :             "[Check][FileSize]config file %s size[%ld] is larger than "
     139              :             "max config file Bytes[%ld]",
     140              :             trustedPath, pathStat.st_size, MAX_CONFIG_FILE_BYTE);
     141            0 :         return false;
     142            0 :     }
     143          254 :     return true;
     144              : }
     145              : 
     146          246 : void JsonParser::GetMaxNestedLayers(
     147              :     const char_t* const fileName, const size_t length, size_t& maxObjDepth, size_t& maxArrayDepth)
     148              : {
     149          246 :     if (length <= 0) {
     150            1 :         ACL_LOG_ERROR("[Check][Length]the length of file %s must be larger than 0.", fileName);
     151            3 :         return;
     152              :     }
     153              : 
     154          245 :     char_t* pBuffer = new (std::nothrow) char_t[length];
     155          245 :     if (pBuffer == nullptr) {
     156            0 :         ACL_LOG_ERROR("[Check][Malloc]Allocate memory failed, bufferSize=%zu.", length);
     157            0 :         const std::string lengthVal = std::to_string(length);
     158            0 :         acl::AclErrorLogManager::ReportInputError(
     159            0 :             acl::ALLOC_MEMORY_FAILED_MSG, std::vector<const char*>({"buf_size", "alloc_interface"}),
     160            0 :             std::vector<const char*>({lengthVal.c_str(), "new"}));
     161            0 :         return;
     162            0 :     }
     163          490 :     const std::shared_ptr<char_t> buffer(pBuffer, [](char_t* const deletePtr) { delete[] deletePtr; });
     164              : 
     165          245 :     std::ifstream fin(fileName);
     166          245 :     if (!fin.is_open()) {
     167            1 :         ACL_LOG_INNER_ERROR("[Open][File]Read file %s failed.", fileName);
     168            1 :         return;
     169              :     }
     170          244 :     (void)fin.seekg(0, fin.beg);
     171          244 :     (void)fin.read(buffer.get(), static_cast<int64_t>(length));
     172              : 
     173          244 :     size_t arrayDepth = 0U;
     174          244 :     size_t objDepth = 0U;
     175        23884 :     for (size_t i = 0U; i < length; ++i) {
     176        23641 :         const char_t v = buffer.get()[i];
     177        23641 :         if (v == '\0') {
     178            1 :             fin.close();
     179            1 :             return;
     180              :         }
     181        23640 :         CountDepth(v, objDepth, maxObjDepth, arrayDepth, maxArrayDepth);
     182              :     }
     183          243 :     fin.close();
     184          247 : }
     185              : 
     186          216 : aclError JsonParser::ParseJson(const char_t* const fileName, const char_t* const configStr, nlohmann::json& js)
     187              : {
     188          216 :     if (strlen(configStr) == 0UL) {
     189           11 :         ACL_LOG_DEBUG("buffer is empty, no need parse json.");
     190           11 :         return ACL_SUCCESS;
     191              :     }
     192              :     try {
     193          620 :         js = nlohmann::json::parse(std::string(configStr));
     194            5 :     } catch (const nlohmann::json::exception& e) {
     195            5 :         ACL_LOG_ERROR("[Check][JsonFile]invalid json buffer, exception:%s.", e.what());
     196            5 :         std::string reason = acl::AclErrorLogManager::FormatStr("Parse exception: %s", e.what());
     197            5 :         acl::AclErrorLogManager::ReportInputError(
     198           10 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     199           10 :             std::vector<const char*>({fileName, reason.c_str()}));
     200            5 :         return ACL_ERROR_PARSE_FILE;
     201            5 :     }
     202          200 :     ACL_LOG_DEBUG("parse json from buffer successfully.");
     203          200 :     return ACL_SUCCESS;
     204              : }
     205              : 
     206          259 : aclError JsonParser::GetConfigStrFromFile(const char_t* const fileName, std::string& configStr)
     207              : {
     208          259 :     if (fileName == nullptr) {
     209            1 :         ACL_LOG_DEBUG("filename is nullptr, no need to parse json");
     210            1 :         return ACL_SUCCESS;
     211              :     }
     212          258 :     ACL_LOG_DEBUG("before GetConfigStrFromFile in ParseJsonFromFile");
     213          258 :     if (!IsValidFileName(fileName)) {
     214            4 :         ACL_LOG_ERROR("[Check][File]invalid config file[%s]", fileName);
     215            4 :         return ACL_ERROR_INVALID_FILE;
     216              :     }
     217          254 :     std::ifstream fin(fileName, std::ios::binary);
     218          254 :     ACL_CHECK_INVALID_FILE_MSG_RET(
     219              :         !fin.is_open(), fileName, "File cannot be opened for reading", ACL_ERROR_INVALID_FILE);
     220          254 :     (void)fin.seekg(0, std::ios::end);
     221          254 :     const std::streampos fp = fin.tellg();
     222          254 :     if (static_cast<int32_t>(fp) == 0) {
     223           12 :         ACL_LOG_DEBUG("parse file is null");
     224           12 :         fin.close();
     225           12 :         return ACL_SUCCESS;
     226              :     }
     227              :     // checking the depth of file
     228          242 :     size_t maxObjDepth = 0U;
     229          242 :     size_t maxArrayDepth = 0U;
     230          242 :     GetMaxNestedLayers(fileName, static_cast<size_t>(fp), maxObjDepth, maxArrayDepth);
     231          242 :     if ((maxObjDepth > MAX_CONFIG_OBJ_DEPTH) || (maxArrayDepth > MAX_CONFIG_ARRAY_DEPTH)) {
     232              :         std::string reason = acl::AclErrorLogManager::FormatStr(
     233              :             "object depth %zu exceeds max %zu or array depth %zu exceeds max %zu", maxObjDepth, MAX_CONFIG_OBJ_DEPTH,
     234            0 :             maxArrayDepth, MAX_CONFIG_ARRAY_DEPTH);
     235            0 :         acl::AclErrorLogManager::ReportInputError(
     236            0 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     237            0 :             std::vector<const char*>({fileName, reason.c_str()}));
     238            0 :         ACL_LOG_ERROR(
     239              :             "[Check][MaxArrayDepth]invalid json file, the object's depth[%zu] is larger than %zu, "
     240              :             "or the array's depth[%zu] is larger than %zu.",
     241              :             maxObjDepth, MAX_CONFIG_OBJ_DEPTH, maxArrayDepth, MAX_CONFIG_ARRAY_DEPTH);
     242            0 :         fin.close();
     243            0 :         return ACL_ERROR_PARSE_FILE;
     244            0 :     }
     245          242 :     ACL_LOG_DEBUG("json file's obj's depth is %zu, array's depth is %zu", maxObjDepth, maxArrayDepth);
     246          242 :     std::stringstream buffer;
     247          242 :     fin.seekg(0, std::ios::beg);
     248          242 :     buffer << fin.rdbuf();
     249          242 :     configStr = buffer.str();
     250          242 :     fin.close();
     251          242 :     return ACL_SUCCESS;
     252          254 : }
     253              : 
     254          219 : aclError JsonParser::ParseJsonFromFile(const char_t* const fileName, nlohmann::json& js)
     255              : {
     256          219 :     std::string configStr;
     257          219 :     auto ret = GetConfigStrFromFile(fileName, configStr);
     258          219 :     if (ret != ACL_SUCCESS) {
     259            3 :         ACL_LOG_ERROR("[Parse][File]Get Buffer from file[%s] failed.", fileName);
     260            3 :         return ret;
     261              :     }
     262              : 
     263          216 :     ret = ParseJson(fileName, configStr.c_str(), js);
     264          216 :     if (ret != ACL_SUCCESS) {
     265            5 :         ACL_LOG_ERROR("[Parse][File]parse config file[%s] to json failed.", fileName);
     266            5 :         return ACL_ERROR_PARSE_FILE;
     267              :     }
     268              : 
     269          211 :     ACL_LOG_DEBUG("parse json from file[%s] successfully.", fileName);
     270          211 :     return ACL_SUCCESS;
     271          219 : }
     272              : 
     273           73 : aclError JsonParser::GetJsonCtxByKey(
     274              :     const char_t* const fileName, std::string& strJsonCtx, const std::string& subStrKey, bool& found)
     275              : {
     276           73 :     found = false;
     277           73 :     nlohmann::json js;
     278           73 :     aclError ret = acl::JsonParser::ParseJsonFromFile(fileName, js);
     279           73 :     if (ret != ACL_SUCCESS) {
     280            2 :         ACL_LOG_ERROR("parse json from file failed, errorCode = %d", ret);
     281            2 :         return ret;
     282              :     }
     283           71 :     const auto configIter = js.find(subStrKey);
     284           71 :     if (configIter != js.end()) {
     285           10 :         strJsonCtx = configIter->dump();
     286           10 :         found = true;
     287              :     }
     288           71 :     return ACL_SUCCESS;
     289           73 : }
     290              : 
     291            7 : aclError JsonParser::GetAttrConfigFromFile(const char_t* const fileName, std::map<aclCannAttr, CannInfo>& cannInfoMap)
     292              : {
     293            7 :     nlohmann::json js;
     294            7 :     aclError ret = JsonParser::ParseJsonFromFile(fileName, js);
     295            7 :     if (ret != ACL_SUCCESS) {
     296            1 :         ACL_LOG_ERROR("parse swFeatureList.json from file[%s] failed, ret = %d", fileName, ret);
     297            1 :         return ret;
     298              :     }
     299              :     try {
     300           24 :         for (auto& item : cannInfoMap) {
     301           18 :             auto& cannInfo = item.second;
     302           18 :             const auto config = js.find(cannInfo.readableAttrName);
     303           18 :             if (config != js.end()) {
     304           14 :                 const auto runtimeIter = config->find(SW_CONFIG_RUNTIME);
     305           14 :                 if (runtimeIter != config->end()) {
     306           14 :                     ACL_REQUIRES_OK(CannInfoUtils::ParseVersionValue(
     307              :                         runtimeIter->get<std::string>(), &cannInfo.minimumRuntimeVersion));
     308              :                 }
     309              :             }
     310              :         }
     311            0 :     } catch (const nlohmann::json::exception& e) {
     312            0 :         std::string reason = acl::AclErrorLogManager::FormatStr("JSON parse exception: %s", e.what());
     313            0 :         acl::AclErrorLogManager::ReportInputError(
     314            0 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     315            0 :             std::vector<const char*>({fileName, reason.c_str()}));
     316            0 :         ACL_LOG_ERROR("invalid config file [%s], exception: %s", fileName, e.what());
     317            0 :         return ACL_ERROR_INTERNAL_ERROR;
     318            0 :     }
     319            6 :     ACL_LOG_INFO("Finish parsing swFeatureList.json");
     320            6 :     return ACL_SUCCESS;
     321            7 : }
     322              : 
     323           30 : aclError JsonParser::GetDefaultDeviceIdFromFile(const char_t* const fileName, int32_t& devId)
     324              : {
     325           30 :     ACL_LOG_DEBUG("start to execute GetDefaultDeviceIdFromFile.");
     326           30 :     nlohmann::json js;
     327           30 :     std::string enableFlagStr, defaultDeviceIdStr;
     328           30 :     aclError ret = acl::JsonParser::ParseJsonFromFile(fileName, js);
     329           30 :     if (ret != ACL_SUCCESS) {
     330            0 :         ACL_LOG_ERROR("[Parse][JsonFromFile]parse default config from file[%s] failed, errorCode = %d", fileName, ret);
     331            0 :         return ret;
     332              :     }
     333              : 
     334              :     try {
     335           30 :         if (!JsonParser::ContainKey(js, ACL_JSON_DEFAULT_DEVICE)) {
     336           21 :             ACL_LOG_WARN("no defaultDevice item!");
     337           21 :             return ACL_SUCCESS;
     338              :         }
     339            9 :         const nlohmann::json& jsDefaultDeviceConfig = JsonParser::GetCfgJsonByKey(js, ACL_JSON_DEFAULT_DEVICE);
     340            9 :         if (!JsonParser::ContainKey(jsDefaultDeviceConfig, ACL_JSON_DEFAULT_DEVICE_ID)) {
     341            1 :             ACL_LOG_WARN("no default_device in acl.json!");
     342            1 :             return ACL_SUCCESS;
     343              :         }
     344              : 
     345            8 :         defaultDeviceIdStr = JsonParser::GetCfgStrByKey(jsDefaultDeviceConfig, ACL_JSON_DEFAULT_DEVICE_ID);
     346            1 :     } catch (const nlohmann::json::exception& e) {
     347            1 :         std::string reason = acl::AclErrorLogManager::FormatStr("JSON parse exception: %s", e.what());
     348            1 :         acl::AclErrorLogManager::ReportInputError(
     349            2 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     350            2 :             std::vector<const char*>({fileName, reason.c_str()}));
     351            1 :         ACL_LOG_ERROR("parse config file [%s], exception: %s", fileName, e.what());
     352            1 :         return ACL_ERROR_INTERNAL_ERROR;
     353            1 :     }
     354              : 
     355            7 :     if (!IsZeroOrPositiveIntegerNoLeadingZero(defaultDeviceIdStr)) {
     356            3 :         acl::AclErrorLogManager::ReportInputError(
     357            6 :             acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
     358            3 :             std::vector<const char*>(
     359            3 :                 {"Parsing the default device ID from the configuration file", defaultDeviceIdStr.c_str(),
     360            6 :                  "default_device", "value must be 0 or a positive integer"}));
     361            3 :         ACL_LOG_ERROR("default_device %s in acl.json is neither 0 nor positive integer.", defaultDeviceIdStr.c_str());
     362            3 :         return ACL_ERROR_INVALID_PARAM;
     363              :     }
     364            4 :     devId = static_cast<int32_t>(std::strtol(defaultDeviceIdStr.c_str(), nullptr, DECIMAL));
     365            4 :     ACL_LOG_DEBUG("successfully parse defaultDevice, devId:%d", devId);
     366            4 :     return ACL_SUCCESS;
     367           30 : }
     368              : 
     369           15 : aclError JsonParser::GetEventModeFromFile(const char_t* const fileName, uint8_t& event_mode, bool& found)
     370              : {
     371           15 :     nlohmann::json js;
     372           15 :     std::string eventModeStr;
     373           15 :     aclError ret = acl::JsonParser::ParseJsonFromFile(fileName, js);
     374           15 :     if (ret != ACL_SUCCESS) {
     375            1 :         ACL_LOG_ERROR("[Parse][JsonFromFile]parse json from file[%s] failed, errorCode = %d", fileName, ret);
     376            1 :         return ret;
     377              :     }
     378           28 :     const std::string ACL_GRAPH_CONFIG_NAME = "acl_graph";
     379           14 :     const std::string ACL_EVENT_MODE_CONFIG_NAME = "event_mode";
     380              : 
     381           14 :     if (!JsonParser::ContainKey(js, ACL_GRAPH_CONFIG_NAME)) {
     382           10 :         ACL_LOG_INFO("No acl_graph in json file!");
     383           10 :         return ACL_SUCCESS;
     384              :     }
     385            4 :     const nlohmann::json& jsAclGraphConfig = JsonParser::GetCfgJsonByKey(js, ACL_GRAPH_CONFIG_NAME);
     386            4 :     if (!JsonParser::ContainKey(jsAclGraphConfig, ACL_EVENT_MODE_CONFIG_NAME)) {
     387            1 :         ACL_LOG_INFO("No event_mode under acl_graph in json file!");
     388            1 :         return ACL_SUCCESS;
     389              :     }
     390            3 :     eventModeStr = JsonParser::GetCfgStrByKey(jsAclGraphConfig, ACL_EVENT_MODE_CONFIG_NAME);
     391              : 
     392              :     // 校验 event_mode 是否为合法整数,只允许 0 或 1
     393            3 :     if ((eventModeStr != "0") && (eventModeStr != "1")) {
     394            1 :         ACL_LOG_ERROR("event_mode value [%s] in json is not a valid integer.", eventModeStr.c_str());
     395            1 :         acl::AclErrorLogManager::ReportInputError(
     396            2 :             acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
     397            1 :             std::vector<const char*>(
     398            2 :                 {"Getting event mode", eventModeStr.c_str(), "event_mode", "value must be 0 or 1"}));
     399            1 :         return ACL_ERROR_INVALID_PARAM;
     400              :     }
     401              : 
     402            2 :     event_mode = static_cast<uint8_t>(std::strtol(eventModeStr.c_str(), nullptr, DECIMAL));
     403            2 :     found = true;
     404            2 :     ACL_LOG_INFO("Successfully parse event_mode: %d, event_mode_str: %s", event_mode, eventModeStr.c_str());
     405            2 :     return ACL_SUCCESS;
     406           15 : }
     407              : 
     408           90 : aclError JsonParser::GetStackSizeByType(
     409              :     const char_t* const fileName, const std::string& typeName, size_t& outSize, bool& outExist)
     410              : {
     411           90 :     ACL_LOG_DEBUG("start to execute GetStackSizeByType, typeName = %s.", typeName.c_str());
     412           90 :     outExist = false;
     413           90 :     outSize = 0U;
     414           90 :     nlohmann::json js;
     415           90 :     aclError ret = acl::JsonParser::ParseJsonFromFile(fileName, js);
     416           90 :     if (ret != ACL_SUCCESS) {
     417            2 :         ACL_LOG_ERROR("[Parse][JsonFromFile]parse default config from file[%s] failed, errorCode = %d", fileName, ret);
     418            2 :         acl::AclErrorLogManager::ReportInputError(
     419            4 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     420            4 :             std::vector<const char*>({fileName, "Parse config file failed"}));
     421            2 :         return ret;
     422              :     }
     423              : 
     424              :     try {
     425              :         // 检查 "StackSize" 键是否存在
     426           88 :         if (js.find("StackSize") == js.end()) {
     427           66 :             ACL_LOG_DEBUG("StackSize key not found in config file [%s]", fileName);
     428           66 :             outExist = false; // 明确设置 outExist 为 false
     429           66 :             return ACL_SUCCESS;
     430              :         }
     431              : 
     432           22 :         const nlohmann::json& stackSizeJs = js["StackSize"];
     433           22 :         if (stackSizeJs.find(typeName.c_str()) != stackSizeJs.end()) {
     434           19 :             size_t rawSize = stackSizeJs.at(typeName.c_str()).get<size_t>();
     435           18 :             outSize = rawSize;
     436           18 :             outExist = true;
     437           18 :             ACL_LOG_INFO("successfully parse %s, size is %zu", typeName.c_str(), outSize);
     438              :         }
     439            1 :     } catch (const nlohmann::json::exception& e) {
     440            1 :         ACL_LOG_ERROR("parse config file [%s], exception: %s", fileName, e.what());
     441            1 :         std::string reason = acl::AclErrorLogManager::FormatStr("Parse exception: %s", e.what());
     442            1 :         acl::AclErrorLogManager::ReportInputError(
     443            2 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     444            2 :             std::vector<const char*>({fileName, reason.c_str()}));
     445            1 :         return ACL_ERROR_INTERNAL_ERROR;
     446            1 :     }
     447              : 
     448           21 :     ACL_LOG_DEBUG("successfully parse StackSize by type");
     449           21 :     return ACL_SUCCESS;
     450           90 : }
     451              : 
     452           31 : aclError JsonParser::GetPrintFifoSizeByType(
     453              :     const char_t* const fileName, const std::string& typeName, size_t& fifoSize, bool& found)
     454              : {
     455           31 :     ACL_LOG_DEBUG("start to execute GetPrintFifoSizeByType, typeName = %s.", typeName.c_str());
     456           31 :     std::string fifoSizeStr;
     457           31 :     found = false;
     458              : 
     459           31 :     auto ret = acl::JsonParser::GetJsonCtxByKey(fileName, fifoSizeStr, typeName, found);
     460           31 :     if (ret != ACL_SUCCESS) {
     461            0 :         acl::AclErrorLogManager::ReportInputError(
     462            0 :             acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
     463            0 :             std::vector<const char*>({fileName, ("cannot parse config for " + typeName).c_str()}));
     464            0 :         ACL_LOG_ERROR(
     465              :             "can not parse config from file[%s], config[%s], errorCode = %d", fileName, typeName.c_str(), ret);
     466            0 :         return ret;
     467              :     }
     468           31 :     if (!found) {
     469           26 :         return ACL_SUCCESS;
     470              :     }
     471              : 
     472            5 :     if (!IsPositiveIntegerNoLeadingZero(fifoSizeStr)) {
     473            2 :         acl::AclErrorLogManager::ReportInputError(
     474            4 :             acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
     475            2 :             std::vector<const char*>(
     476            2 :                 {"Getting print fifo size", fifoSizeStr.c_str(), "fifoSize",
     477            4 :                  "value must be a positive integer in acl.json"}));
     478            2 :         ACL_LOG_ERROR("fifoSize %s in acl.json is not a positive integer.", fifoSizeStr.c_str());
     479            2 :         return ACL_ERROR_INVALID_PARAM;
     480              :     }
     481              : 
     482            3 :     fifoSize = static_cast<size_t>(std::strtol(fifoSizeStr.c_str(), nullptr, DECIMAL));
     483            3 :     ACL_LOG_DEBUG("successfully parse print fifo size by type");
     484            3 :     return ACL_SUCCESS;
     485           31 : }
     486              : } // namespace acl
        

Generated by: LCOV version 2.0-1