使用json11封装读取配置的方式
json11的一些使用方法:
见https://www.cnblogs.com/bwbfight/p/18135452
json11的实现方式
AutoSdkType.hpp
#ifndef __AUTOCOMMON_FRAMEWORK_CORE_AUTOSDKTYPE_HPP_ #define __AUTOCOMMON_FRAMEWORK_CORE_AUTOSDKTYPE_HPP_ #include <stdint.h> #include "MDmsStatus.h" // this header file is for c++(framework) impletementation typedefine. namespace AutoSDK { using char8_t = char; // NOLINT using uchar8_t = unsigned char; // NOLINT using float32_t = float; // NOLINT using float64_t = double; // NOLINT using DmsBool = int32_t; } // namespace AutoSDK #endif // __AUTOCOMMON_FRAMEWORK_CORE_AUTOSDKTYPE_HPP_
MDmsStatus.h
#ifndef _MATRIX_SDK_MMDMS_STATUS_H_ #define _MATRIX_SDK_MMDMS_STATUS_H_ #ifdef __cplusplus extern "C" { #endif /** A enum to represent running status */ typedef enum MDmsStatus { MDMS_SUCCESS = 0, //!< success MDMS_MODULE_UNINIT = 1, //!< module uninit MDMS_PARAM_INVALID = 2, //!< input parameter is invalid MDMS_FILE_OPEN_FAIL = 3, //!< open file failed // MDMS config errors MDMS_CONFIG_OPEN_FAIL = 100, //!< config file open failed MDMS_CONFIG_PARSE_FAIL = 101, //!< config parse failed MDMS_CONFIG_PARAM_MISSING = 102, //!< the parameter is missing in config file MDMS_CONFIG_PARAM_INVALID = 103, //!< the value of parameter is invalid MDMS_CONFIG_MISSING_MODEL = 104, //!< config missing model file, or model cannot load // MDMS license errors MDMS_LICENSE_EXPIRE = 200, //!< license expire MDMS_LICENSE_UDID_MISMATCH = 201, //!< uuid is invalid MDMS_LICENSE_ONLINE_ACTIVATE_FAIL = 202, //!< online activate failed MDMS_LICENSE_ACTIVATIONS_RUN_OUT = 203, //!< license run out MDMS_LICENSE_UNAUTH = 204, //!< module is unauthorized MDMS_CONFIG_MISSING_LICENSE = 105, //!< config missing license file, or license file cannot open MDMS_LICENSE_INVALID = 205, //!< license file is invalid MDMS_FUNC_HANDLE_INVALID = 300, //!< input invalid handle called api functions MDMS_FUNC_PIXEL_FMT_INVALID = 302, //!< the format of input image is invalid MDMS_FUNC_MODEL_FMT_INVALID = 303, //!< the format of loaded model is invalid MDMS_RECOGNITION_FACE_LOW_QUALITY = 400, //!< recongnition face low quality MDMS_RECOGNITION_FACE_NOT_FOUND = 401, //!< recongnition face not found, valid face is not detected. MDMS_MODULEMANAGER_MODULE_DISABLE = 600, //!< the module has not been enabled. MDMS_INTERNAL_ERROR = 1000 //!< internal error } MDmsStatus; #ifdef __cplusplus } // extern "C" #endif #endif
MJsonConfig.hpp
#ifndef __AUTOCOMMON_AUTOSDK_INCLUDE_FRAMEWORK_UTILS_MJSONCONFIG_HPP__ #define __AUTOCOMMON_AUTOSDK_INCLUDE_FRAMEWORK_UTILS_MJSONCONFIG_HPP__ #include "AutoSdkType.hpp" #include "MDmsStatus.h" #include "json11/json11.hpp" namespace AutoSDK { class MJsonConfig final { public: enum class RequiredType : uint32_t { REQUIRED, OPTIONAL }; MJsonConfig() = default; explicit MJsonConfig(json11::Json const& json) : json_obj_{json} {} inline std::string Dump() { return json_obj_.dump(); } MDmsStatus ParseFile(std::string const& json_file); MDmsStatus GetJsonKeys(std::vector<std::string>& keys) const; MDmsStatus GetJsonObj(std::string const& key, RequiredType const& required_type, MJsonConfig* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonInt(std::string const& key, RequiredType const& required_type, int32_t* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonStr(std::string const& key, RequiredType const& required_type, std::string* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonFloat(std::string const& key, RequiredType const& required_type, float32_t* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonBool(std::string const& key, RequiredType const& required_type, bool* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr1DInt(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<int32_t>* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr1DStr(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<std::string>* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr1DFloat(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<float32_t>* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr1DBool(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<bool>* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr1DObj(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<MJsonConfig>* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr2DInt(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<int32_t> >* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr2DStr(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<std::string> >* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr2DFloat(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<float32_t> >* const val, bool* is_found = nullptr) const; MDmsStatus GetJsonArr2DBool(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<bool> >* const val, bool* is_found = nullptr) const; private: json11::Json json_obj_; }; } // namespace AutoSDK #endif // __AUTOCOMMON_AUTOSDK_INCLUDE_FRAMEWORK_UTILS_MJSONCONFIG_HPP__
MJsonConfig.cpp实现
#include "MJsonConfig.hpp" #include <fstream> #include "log.hpp" namespace AutoSDK { /*
各枚举值的说明:
-
JSON_INT32:
- 代表一个 32 位整数类型的值。通常用于表示整数数据,比如
123
。
- 代表一个 32 位整数类型的值。通常用于表示整数数据,比如
-
JSON_FLOAT32:
- 代表一个 32 位浮点数类型的值。通常用于表示小数值,比如
3.14
。
- 代表一个 32 位浮点数类型的值。通常用于表示小数值,比如
-
JSON_STRING:
- 代表一个字符串类型的值。字符串数据通常用双引号括起来,比如
"Hello, World!"
。
- 代表一个字符串类型的值。字符串数据通常用双引号括起来,比如
-
JSON_BOOL:
- 代表一个布尔值。布尔值只能是
true
或false
,常用于表示逻辑状态或开关。
- 代表一个布尔值。布尔值只能是
-
JSON_OBJ:
- 代表一个 JSON 对象类型。JSON 对象是一组键值对的集合,用大括号
{}
包围,比如{"name": "John", "age": 30}
。
- 代表一个 JSON 对象类型。JSON 对象是一组键值对的集合,用大括号
-
JSON_ARRAY:
- 代表一个 JSON 数组类型。JSON 数组是一组有序的值,值可以是任意类型,使用方括号
[]
包围,比如[1, 2, 3]
或["apple", "banana", "cherry"]
。
- 代表一个 JSON 数组类型。JSON 数组是一组有序的值,值可以是任意类型,使用方括号
总结:
这个枚举类型 JsonValDataType
主要是为了方便在处理 JSON 数据时标记每个值的具体类型。这可以用于 JSON 解析、序列化、类型检查等操作。比如在编写 JSON 解析器时,可以根据 JsonValDataType
来确定如何处理某个 JSON 值(如是否将其转换为整数、浮点数、字符串等)
*/ enum class JsonValDataType : uint32_t { JSON_INT32, JSON_FLOAT32, JSON_STRING, JSON_BOOL, JSON_OBJ, JSON_ARRAY }; MDmsStatus MJsonConfig::ParseFile(std::string const& json_file) { MDmsStatus status{MDMS_SUCCESS}; do { std::ifstream file_stream{json_file}; if (!file_stream.is_open()) { SDK_LOG_ERROR("jsonconfig file ({}) could not be opened.", json_file); status = MDmsStatus::MDMS_CONFIG_OPEN_FAIL; break; } std::istreambuf_iterator<char8_t> const eos{}; std::string const json_str{std::istreambuf_iterator<char8_t>(file_stream), eos}; file_stream.close(); std::string error_info{}; json_obj_ = json11::Json::parse(json_str, error_info); if (!error_info.empty()) { SDK_LOG_ERROR("parse json string failed with error:\n {}.", error_info); status = MDmsStatus::MDMS_CONFIG_PARSE_FAIL; break; } } while (false); return status; } template <typename T> static T GetVal(json11::Json const& json) {} template <> int32_t GetVal(json11::Json const& json) { return json.int_value(); } template <> float32_t GetVal(json11::Json const& json) { return static_cast<float32_t>(json.number_value()); } template <> std::string GetVal(json11::Json const& json) { return json.string_value(); } template <> bool GetVal(json11::Json const& json) { return json.bool_value(); } template <> MJsonConfig GetVal(json11::Json const& json) { return MJsonConfig{json}; } static MDmsStatus CheckJsonValType(json11::Json const& json, JsonValDataType const type, MJsonConfig::RequiredType const required_type) { MDmsStatus status{MDMS_SUCCESS}; do { if (required_type == MJsonConfig::RequiredType::OPTIONAL) { break; } if (((type == JsonValDataType::JSON_INT32) && (json.is_number())) || ((type == JsonValDataType::JSON_FLOAT32) && (json.is_number())) || ((type == JsonValDataType::JSON_STRING) && (json.is_string())) || ((type == JsonValDataType::JSON_ARRAY) && (json.is_array())) || ((type == JsonValDataType::JSON_OBJ) && (json.is_object())) || ((type == JsonValDataType::JSON_BOOL) && (json.is_bool()))) { } else { SDK_LOG_ERROR("json value type is error: {}", json.dump()); status = MDMS_CONFIG_PARAM_INVALID; } } while (false); return status; } static MDmsStatus CheckJson(json11::Json const& json, std::string const& key, MJsonConfig::RequiredType const& required_type, JsonValDataType const type) { MDmsStatus status; do { if (!json.is_object()) { status = MDMS_CONFIG_PARSE_FAIL; break; } json11::Json::object const& object_items{json.object_items()}; size_t const kNum{object_items.count(key)}; if (kNum <= 0U) { if (MJsonConfig::RequiredType::OPTIONAL == required_type) { status = MDMS_SUCCESS; } else { status = MDMS_CONFIG_PARAM_MISSING; } break; } else { status = CheckJsonValType(object_items.at(key), type, required_type); } } while (false); return status; }
/*MJsonConfig::GetJsonKeys
是一个成员函数,它的主要作用是从json_obj_
中提取所有的键名(keys)并将它们存储到传入的keys
vector中
*/ MDmsStatus MJsonConfig::GetJsonKeys(std::vector<std::string>& keys) const { keys.resize(0); if (!this->json_obj_.is_object()) { SDK_LOG_ERROR("The MJsonConfig is not a object."); return MDmsStatus::MDMS_CONFIG_PARSE_FAIL; } const auto& object_items = this->json_obj_.object_items(); for (const auto& item : object_items) { keys.push_back(item.first); } return MDmsStatus::MDMS_SUCCESS; } MDmsStatus MJsonConfig::GetJsonObj(std::string const& key, RequiredType const& required_type, MJsonConfig* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, JsonValDataType::JSON_OBJ); if (MDMS_SUCCESS != status) { break; } json11::Json::object const& object_items{this->json_obj_.object_items()}; MJsonConfig const empty{}; *val = (object_items.count(key) > 0U) ? GetVal<MJsonConfig>(object_items.at(key)) : empty; if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonInt(std::string const& key, RequiredType const& required_type, int32_t* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, JsonValDataType::JSON_INT32); if (MDMS_SUCCESS != status) { break; } json11::Json::object const& object_items{this->json_obj_.object_items()}; *val = (object_items.count(key) > 0U) ? GetVal<int32_t>(object_items.at(key)) : 0; if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonFloat(std::string const& key, RequiredType const& required_type, float32_t* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, JsonValDataType::JSON_FLOAT32); if (MDMS_SUCCESS != status) { break; } json11::Json::object const& object_items{this->json_obj_.object_items()}; *val = (object_items.count(key) > 0U) ? GetVal<float32_t>(object_items.at(key)) : 0.F; if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonStr(std::string const& key, RequiredType const& required_type, std::string* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, JsonValDataType::JSON_STRING); if (MDMS_SUCCESS != status) { break; } json11::Json::object const& object_items{this->json_obj_.object_items()}; *val = (object_items.count(key) > 0U) ? GetVal<std::string>(object_items.at(key)) : ""; if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonBool(std::string const& key, RequiredType const& required_type, bool* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, JsonValDataType::JSON_BOOL); if (MDMS_SUCCESS != status) { break; } json11::Json::object const& object_items{this->json_obj_.object_items()}; *val = (object_items.count(key) > 0U) ? GetVal<bool>(object_items.at(key)) : false; if (nullptr != is_found) { *is_found = true; } } while (false); return status; } template <typename DataType> static std::vector<DataType> GetJson1DArr(json11::Json const& json, std::string const& key) { std::vector<DataType> res{}; json11::Json::object const& object_items{json.object_items()}; json11::Json::array const empty{}; size_t const kNum{object_items.count(key)}; json11::Json::array const* const array_items{(kNum > 0U) ? &object_items.at(key).array_items() : &empty}; for (size_t i{0U}; i < array_items->size(); ++i) { res.push_back(GetVal<DataType>(array_items->at(i))); } return res; } static MDmsStatus CheckJson(json11::Json const& json, std::string const& key, MJsonConfig::RequiredType const& required_type, int32_t const expected_size, JsonValDataType const type) { MDmsStatus status; do { status = CheckJson(json, key, required_type, JsonValDataType::JSON_ARRAY); if (MDMS_SUCCESS != status) { break; } json11::Json::object const& object_items{json.object_items()}; json11::Json::array const empty{}; size_t const kNum{object_items.count(key)}; json11::Json::array const* const array_items{ (kNum > 0U) ? &object_items.at(key).array_items() : &empty}; if ((static_cast<size_t>(expected_size) != array_items->size()) && (expected_size > 0)) { if (MJsonConfig::RequiredType::OPTIONAL == required_type) { status = MDMS_SUCCESS; } else { status = MDMS_CONFIG_PARAM_INVALID; } break; } for (size_t i{0U}; i < array_items->size(); ++i) { status = CheckJsonValType(array_items->at(i), type, required_type); if (MDMS_SUCCESS != status) { break; } } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr1DObj(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<MJsonConfig>* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size, JsonValDataType::JSON_OBJ); if (MDMS_SUCCESS != status) { } *val = GetJson1DArr<MJsonConfig>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr1DInt(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<int32_t>* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size, JsonValDataType::JSON_INT32); if (MDMS_SUCCESS != status) { break; } *val = GetJson1DArr<int32_t>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr1DStr(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<std::string>* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size, JsonValDataType::JSON_STRING); if (MDMS_SUCCESS != status) { break; } *val = GetJson1DArr<std::string>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr1DFloat(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<float32_t>* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size, JsonValDataType::JSON_FLOAT32); if (MDMS_SUCCESS != status) { break; } *val = GetJson1DArr<float32_t>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr1DBool(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<bool>* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size, JsonValDataType::JSON_BOOL); if (MDMS_SUCCESS != status) { break; } *val = GetJson1DArr<bool>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } template <typename DataType> static std::vector<std::vector<DataType> > GetJson2DArr(json11::Json const& json, std::string const& key) { json11::Json::object const& object_items{json.object_items()}; json11::Json::array const empty{}; size_t const kNum{object_items.count(key)}; json11::Json::array const* const array_items{(kNum > 0U) ? &object_items.at(key).array_items() : &empty}; std::vector<std::vector<DataType> > res{}; for (size_t i{0U}; i < array_items->size(); ++i) { std::vector<DataType> v1{}; json11::Json::array const* const array_items_tmp{&array_items->at(i).array_items()}; for (size_t j{0U}; j < array_items_tmp->size(); ++j) { v1.push_back(GetVal<DataType>(array_items_tmp->at(j))); } res.push_back(v1); } return res; } static MDmsStatus CheckJson(json11::Json const& json, std::string const& key, MJsonConfig::RequiredType const& required_type, int32_t const expected_size1, int32_t const expected_size2, JsonValDataType const& type) { MDmsStatus status; do { status = CheckJson(json, key, required_type, expected_size1, JsonValDataType::JSON_ARRAY); if (MDMS_SUCCESS != status) { break; } json11::Json::object const& object_items{json.object_items()}; json11::Json::array const empty{}; size_t const kNum{object_items.count(key)}; json11::Json::array const* const array_items{ (kNum > 0U) ? &object_items.at(key).array_items() : &empty}; for (size_t i{0U}; i < array_items->size(); ++i) { if (!array_items->at(i).is_array()) { if (MJsonConfig::RequiredType::OPTIONAL == required_type) { status = MDMS_SUCCESS; } else { status = MDMS_CONFIG_PARAM_INVALID; } break; } json11::Json::array const* const array_items_tmp{&array_items->at(i).array_items()}; if ((static_cast<size_t>(expected_size2) != array_items_tmp->size()) && (expected_size2 > 0)) { status = MDMS_CONFIG_PARAM_INVALID; break; } for (size_t j{0U}; j < array_items_tmp->size(); j++) { status = CheckJsonValType(array_items_tmp->at(j), type, required_type); if (MDMS_SUCCESS != status) { break; } } if (MDMS_SUCCESS != status) { break; } } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr2DInt(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<int32_t> >* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size1, expected_size2, JsonValDataType::JSON_INT32); if (MDMS_SUCCESS != status) { break; } *val = GetJson2DArr<int32_t>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr2DFloat(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<float32_t> >* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size1, expected_size2, JsonValDataType::JSON_FLOAT32); if (MDMS_SUCCESS != status) { break; } *val = GetJson2DArr<float32_t>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr2DStr(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<std::string> >* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size1, expected_size2, JsonValDataType::JSON_STRING); if (MDMS_SUCCESS != status) { break; } *val = GetJson2DArr<std::string>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } MDmsStatus MJsonConfig::GetJsonArr2DBool(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<bool> >* const val, bool* is_found) const { MDmsStatus status; do { if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } status = CheckJson(this->json_obj_, key, required_type, expected_size1, expected_size2, JsonValDataType::JSON_BOOL); if (MDMS_SUCCESS != status) { break; } *val = GetJson2DArr<bool>(this->json_obj_, key); if (nullptr != is_found) { *is_found = true; } } while (false); return status; } } // namespace AutoSDK
1) MDmsStatus MJsonConfig::ParseFile(std::string const& json_file)
- 这是
MJsonConfig
类的一个成员函数,名为ParseFile
。它接收一个参数json_file
,该参数是一个字符串,表示 JSON 文件的路径。
std::istreambuf_iterator<char8_t> const eos{};
std::string const json_str{std::istreambuf_iterator<char8_t>(file_stream), eos};
- 使用
std::istreambuf_iterator<char8_t>
读取文件的全部内容,将文件内容存储为一个std::string
,这个字符串将作为 JSON 数据。
ParseFile
函数的作用是:
- 打开指定路径的 JSON 配置文件。
- 读取文件内容并将其存储为一个字符串。
- 使用
json11
库解析 JSON 字符串。 - 如果文件打开失败或解析失败,函数会记录错误并返回相应的状态码。
template <typename T> static T GetVal(json11::Json const& json) {} template <> int32_t GetVal(json11::Json const& json) { return json.int_value(); } template <> float32_t GetVal(json11::Json const& json) { return static_cast<float32_t>(json.number_value()); } template <> std::string GetVal(json11::Json const& json) { return json.string_value(); } template <> bool GetVal(json11::Json const& json) { return json.bool_value(); } template <> MJsonConfig GetVal(json11::Json const& json) { return MJsonConfig{json}; } 这段代码展示了模板特化的应用,具体是一个 GetVal 函数模板的不同特化版本。模板特化允许针对特定类型实现不同的行为。以下是逐行的解释: template <typename T> static T GetVal(json11::Json const& json) {} 这是一个模板函数 GetVal 的声明,它接受一个 json11::Json 类型的参数,并返回类型为 T 的值。此函数模板没有实现,意味着它是一个通用模板,提供了一个默认的函数签名。 针对不同类型的模板特化 接下来的部分是针对不同数据类型的 GetVal 函数模板特化。 整数类型(int32_t)的特化: template <> int32_t GetVal(json11::Json const& json) { return json.int_value(); } 这是 GetVal 模板的特化版本,当 T 是 int32_t 时,调用 json.int_value() 来获取 json 对象中的整数值。json.int_value() 会提取 JSON 数据中的整数部分并返回。 浮点类型(float32_t)的特化: template <> float32_t GetVal(json11::Json const& json) { return static_cast<float32_t>(json.number_value()); } 这是 GetVal 模板的特化版本,当 T 是 float32_t 时,调用 json.number_value() 来获取 JSON 数据中的数字值(可能是浮点数)。然后,通过 static_cast<float32_t> 将该值转换为 float32_t 类型并返回。 字符串类型(std::string)的特化: template <> std::string GetVal(json11::Json const& json) { return json.string_value(); } 这是 GetVal 模板的特化版本,当 T 是 std::string 时,调用 json.string_value() 来获取 JSON 数据中的字符串值并返回。 布尔类型(bool)的特化: template <> bool GetVal(json11::Json const& json) { return json.bool_value(); } 这是 GetVal 模板的特化版本,当 T 是 bool 时,调用 json.bool_value() 来获取 JSON 数据中的布尔值并返回。 自定义类型(MJsonConfig)的特化: template <> MJsonConfig GetVal(json11::Json const& json) { return MJsonConfig{json}; } 这是 GetVal 模板的特化版本,当 T 是 MJsonConfig 时,返回一个构造的 MJsonConfig 对象,使用 json 作为构造函数的参数。这个特化表示将 json11::Json 对象转换为 MJsonConfig 类型。 总结 这段代码实现了模板函数 GetVal 的不同类型的特化版本,使得你可以根据不同的返回类型,从 json11::Json 对象中提取相应的数据: 对于整数,调用 int_value()。 对于浮点数,调用 number_value() 并进行类型转换。 对于字符串,调用 string_value()。 对于布尔值,调用 bool_value()。 对于自定义类型 MJsonConfig,通过构造函数将 json11::Json 转换为 MJsonConfig。 模板特化使得 GetVal 函数可以根据传入的模板类型返回不同类型的值。
函数 CheckJsonValType
和 CheckJson
主要用于检查 JSON 数据的类型和内容是否符合预期的结构。这些函数在 JSON 配置解析时非常有用,确保解析的数据符合预期的格式。下面是对这两个函数的详细说明:
1. CheckJsonValType 函数 函数声明: static MDmsStatus CheckJsonValType(json11::Json const& json, JsonValDataType const type, MJsonConfig::RequiredType const required_type); 函数功能: 目的:该函数检查传入的 json 数据是否符合预期的类型(由 type 参数指定)。 参数: json:待检查的 JSON 数据对象。 type:期望的 JSON 数据类型,使用 JsonValDataType 枚举表示。它可能是以下之一: JSON_INT32(整数) JSON_FLOAT32(浮点数) JSON_STRING(字符串) JSON_ARRAY(数组) JSON_OBJ(对象) JSON_BOOL(布尔值) required_type:表示该字段是否为必需的,使用 MJsonConfig::RequiredType 枚举表示。可能的值是: OPTIONAL(可选) REQUIRED(必需) 功能逻辑: 检查 JSON 类型是否匹配:首先,函数检查 required_type 是否为 OPTIONAL。如果是 OPTIONAL,则不进行类型检查,直接跳过。 类型匹配判断:根据 type 和 json 数据的类型(例如 json.is_number(), json.is_string() 等),判断 JSON 数据是否符合预期类型。如果匹配,则继续执行,否则返回错误状态 MDMS_CONFIG_PARAM_INVALID,并记录错误信息。 返回值:该函数返回一个 MDmsStatus 类型的值,表示检查结果。如果类型不匹配,则返回 MDMS_CONFIG_PARAM_INVALID,如果检查通过,则返回 MDMS_SUCCESS。 代码: static MDmsStatus CheckJsonValType(json11::Json const& json, JsonValDataType const type, MJsonConfig::RequiredType const required_type) { MDmsStatus status{MDMS_SUCCESS}; do { if (required_type == MJsonConfig::RequiredType::OPTIONAL) { break; } if (((type == JsonValDataType::JSON_INT32) && (json.is_number())) || ((type == JsonValDataType::JSON_FLOAT32) && (json.is_number())) || ((type == JsonValDataType::JSON_STRING) && (json.is_string())) || ((type == JsonValDataType::JSON_ARRAY) && (json.is_array())) || ((type == JsonValDataType::JSON_OBJ) && (json.is_object())) || ((type == JsonValDataType::JSON_BOOL) && (json.is_bool()))) { } else { SDK_LOG_ERROR("json value type is error: {}", json.dump()); status = MDMS_CONFIG_PARAM_INVALID; } } while (false); return status; } 2. CheckJson 函数 函数声明: static MDmsStatus CheckJson(json11::Json const& json, std::string const& key, MJsonConfig::RequiredType const& required_type, JsonValDataType const type); 函数功能: 目的:该函数用于检查 json 对象中是否包含指定的 key,并且该 key 对应的值是否符合预期的类型。 参数: json:待检查的 JSON 数据对象。 key:要查找的键。 required_type:该字段是否必需,MJsonConfig::RequiredType 类型,可能为 OPTIONAL 或 REQUIRED。 type:期望的值类型,JsonValDataType 类型(参考上文)。 功能逻辑: 检查 JSON 是否为对象:首先检查传入的 json 是否是一个 JSON 对象(json.is_object())。如果不是对象,返回 MDMS_CONFIG_PARSE_FAIL。 检查是否包含 key:如果 json 是一个对象,则查找是否包含指定的 key。如果没有该键: 如果 required_type 是 OPTIONAL,则认为该字段可选,返回 MDMS_SUCCESS。 如果 required_type 是 REQUIRED,则返回 MDMS_CONFIG_PARAM_MISSING,表示该字段缺失。 调用 CheckJsonValType:如果找到了 key,则调用 CheckJsonValType 函数检查该键对应的值是否符合预期类型。返回值由 CheckJsonValType 确定。 返回值: 返回一个 MDmsStatus 类型的值,表示检查结果。它可能是: MDMS_SUCCESS:检查成功。 MDMS_CONFIG_PARSE_FAIL:如果 JSON 解析失败(如不是对象)。 MDMS_CONFIG_PARAM_MISSING:如果缺少必需的键。 MDMS_CONFIG_PARAM_INVALID:如果键的值类型不匹配。 代码: static MDmsStatus CheckJson(json11::Json const& json, std::string const& key, MJsonConfig::RequiredType const& required_type, JsonValDataType const type) { MDmsStatus status; do { if (!json.is_object()) { status = MDMS_CONFIG_PARSE_FAIL; break; } json11::Json::object const& object_items{json.object_items()}; size_t const kNum{object_items.count(key)}; if (kNum <= 0U) { if (MJsonConfig::RequiredType::OPTIONAL == required_type) { status = MDMS_SUCCESS; } else { status = MDMS_CONFIG_PARAM_MISSING; } break; } else { status = CheckJsonValType(object_items.at(key), type, required_type); } } while (false); return status; } 总结 CheckJsonValType:检查给定的 JSON 值是否符合预期的类型。 CheckJson:检查 JSON 对象中是否包含指定的 key,并且该键的值是否符合预期的类型。如果缺少该键并且是必需的,则返回错误;否则,调用 CheckJsonValType 进一步检查类型。 这两个函数通常一起使用,用于解析和验证 JSON 配置文件中的数据,确保数据的完整性和类型的正确性。
MDmsStatus MJsonConfig::GetJsonObj
是一个成员函数,用于从 JSON 对象中提取指定键对应的值,并将其作为 MJsonConfig
对象返回。该函数还支持检查是否找到了指定键
函数签名 MDmsStatus MJsonConfig::GetJsonObj(std::string const& key, RequiredType const& required_type, MJsonConfig* const val, bool* is_found) const; 参数说明 key (std::string const&): 要在 JSON 对象中查找的键名。 required_type (RequiredType const&): 必须的 JSON 值类型,通常是一个枚举值或类型,用于检查从 JSON 获取的数据是否符合要求。 val (MJsonConfig* const): 一个指向 MJsonConfig 对象的指针,用于存储从 JSON 中提取到的值。如果找到了对应的键,提取的数据会被存储在这个对象中。 is_found (bool*): 一个指向布尔值的指针,用于指示是否找到了指定的键。如果提供了这个参数,函数将在操作完成后将其设置为 true 或 false,表示是否成功找到该键。 返回值 返回 MDmsStatus 类型,表示操作的状态。通常返回: MDMS_SUCCESS: 如果操作成功,即成功从 JSON 中提取了值。 MDMS_PARAM_INVALID: 如果参数无效(如 val 为 nullptr)。 其他错误状态,表示提取过程中出现了问题(如 JSON 数据格式错误等)。 函数流程 检查 is_found 是否为空: 如果 is_found 不是 nullptr,它会被初始化为 false,表示默认情况下没有找到该键。 检查 val 是否为 nullptr: 如果 val 为 nullptr,函数会立即返回 MDMS_PARAM_INVALID 错误,因为无法将数据填充到 nullptr 指针中。 检查键和类型: 使用 CheckJson 函数检查 JSON 对象中的 key 是否存在,并且它的数据类型是否符合 required_type。如果检查失败,函数会返回错误状态。 提取值: 如果键存在且类型匹配,函数从 JSON 对象中提取该键对应的值,并使用 GetVal<MJsonConfig> 将其转换成 MJsonConfig 类型存储到 val 中。如果该键不存在,则使用一个空的 MJsonConfig 对象。 设置 is_found: 如果提供了 is_found 参数且键存在,则将其设置为 true,表示找到了对应的键。如果没有找到键,则 is_found 保持为 false。 返回状态: 函数根据检查和提取结果返回适当的 MDmsStatus 状态。 示例代码 假设你有一个 MJsonConfig 对象 config,你希望从其中获取一个键为 "settings" 的子对象,并将其存储到一个新的 MJsonConfig 对象中。 cpp #include <iostream> #include "MJsonConfig.h" // 假设这是包含 GetJsonObj 定义的头文件 int main() { MJsonConfig config; // 假设该对象已经初始化并包含 JSON 数据 MJsonConfig val; // 用于存储提取的子 JSON 对象 bool is_found = false; // 用于指示是否找到键 MDmsStatus status = config.GetJsonObj("settings", /* required_type */ some_type, &val, &is_found); if (status == MDMS_SUCCESS && is_found) { std::cout << "Found 'settings' and successfully extracted the JSON object." << std::endl; // 你可以在这里操作提取到的 val(MJsonConfig 类型的对象) } else { std::cout << "Failed to find 'settings' or invalid type." << std::endl; } return 0; } 详细解析 CheckJson: CheckJson 函数用于验证 JSON 对象中的键是否存在,并且该键对应的值的类型是否符合 required_type。如果类型不匹配或键不存在,MDMS_SUCCESS 状态不会被返回。 json_obj_.object_items(): 该函数返回一个包含所有键值对的 json11::Json::object,即一个 std::map<std::string, json11::Json> 类型的对象。通过 object_items.count(key) 可以检查指定的键是否存在。 GetVal<MJsonConfig>: GetVal<MJsonConfig> 是一个模板函数,用于将提取的值转换成 MJsonConfig 类型。如果该键不存在,empty 对象(一个空的 MJsonConfig 对象)会被返回。 is_found: is_found 是一个布尔值指针,它会被设置为 true 或 false,表示是否成功从 JSON 对象中找到了指定的键。 注意事项 确保 val 参数不是 nullptr,否则函数会返回 MDMS_PARAM_INVALID 错误。 如果 is_found 不为 nullptr,它将指示是否找到了该键。 使用 required_type 来确保获取的数据类型正确。 确保 CheckJson 进行的类型验证与实际情况一致,否则可能会导致提取失败。 通过这个函数,你可以从 JSON 配置对象中获取嵌套的 MJsonConfig 对象,并且进行类型验证,同时获得是否找到该键的标志
这四个函数 (GetJsonBool
, GetJsonInt
, GetJsonFloat
, GetJsonStr
) 的基本逻辑非常相似,区别在于返回的数据类型不同:
GetJsonBool
用于提取布尔值。GetJsonInt
用于提取整数值。GetJsonFloat
用于提取浮点值。GetJsonStr
用于提取字符串值。
每个函数都需要指定一个键名 (key
),一个类型检查参数 (required_type
),并且通过传递指针来获取提取的值(如 val
)。如果找到了对应的键,函数会将值存储在 val
中,并返回成功状态。如果键未找到或者类型不匹配,返回相应的错误状态。
GetJson1DArr
是一个模板函数,用于从 JSON 对象中提取一维数组(std::vector
)数据。该函数可以适用于任何类型的数组,只要能将 JSON 数组中的元素转换为该类型。接下来,我将逐步解析函数的实现和其各个部分的功能。函数签名 template <typename DataType> static std::vector<DataType> GetJson1DArr(json11::Json const& json, std::string const& key); 参数说明: json (json11::Json const&): 这是输入的 JSON 对象,它包含了需要从中提取数据的键值对。json11::Json 是一个常见的 JSON 库中的数据类型,表示一个 JSON 对象。 key (std::string const&): 要查找的键名,在这个键下存储的应该是一个一维 JSON 数组。 返回值: std::vector<DataType>: 函数返回一个 std::vector,其元素类型为 DataType。该向量包含从 JSON 数组中提取的数据。 函数实现解析 1. 获取 JSON 对象 json11::Json::object const& object_items{json.object_items()}; 通过 json.object_items() 提取 JSON 对象中的所有键值对。此函数返回一个 json11::Json::object 类型的引用,它是一个以键(std::string)为索引、值为 json11::Json 类型的映射(即 std::map<std::string, json11::Json>)。 2. 初始化空数组 json11::Json::array const empty{}; 定义一个空的 JSON 数组 empty,如果指定的 key 不存在时,可以用它作为一个默认值来避免访问不存在的键时出错。 3. 查找指定键的数组 size_t const kNum{object_items.count(key)}; json11::Json::array const* const array_items{(kNum > 0U) ? &object_items.at(key).array_items() : &empty}; object_items.count(key) 返回键 key 在 JSON 对象中出现的次数。如果存在该键,返回该键对应的值;如果不存在,返回 0。 如果找到了该键(即 kNum > 0),则使用 object_items.at(key).array_items() 获取与该键对应的 JSON 数组,并将其赋值给 array_items。 如果没有找到该键,则使用空数组 empty 作为默认值。 4. 遍历 JSON 数组并提取数据 for (size_t i{0U}; i < array_items->size(); ++i) { res.push_back(GetVal<DataType>(array_items->at(i))); } 通过 array_items->size() 获取数组的元素个数,然后遍历数组中的每个元素。 array_items->at(i) 获取数组中的第 i 个元素。 GetVal<DataType>(array_items->at(i)) 将 JSON 数组元素转换为 DataType 类型,并将其添加到结果向量 res 中。 5. 返回结果 return res; 最后,返回填充好的 std::vector<DataType>,该向量包含了从 JSON 数组中提取并转换后的元素。 GetVal 函数 函数 GetVal<DataType>(...) 在这个函数内部被用来将 JSON 元素转换为特定的 DataType 类型。假设 GetVal 是一个模板函数,它能够处理不同的类型转换,依据传入的 DataType 自动选择合适的转换方法。 函数用途 这个函数的用途是从一个 JSON 对象中提取指定键(key)下的数组,并将数组中的每个元素转换为指定类型(DataType)并返回一个 std::vector<DataType>。 例如,如果 DataType 是 int,该函数可以从 JSON 数组中提取整数值并返回一个整数向量。 如果 DataType 是 std::string,它可以提取字符串数组并返回一个字符串向量。 使用场景 该函数适用于需要从 JSON 配置或响应中提取一维数组的场景,例如: 从一个 JSON 配置文件中读取多个数字。 从 API 响应中获取一组字符串或其他类型的数据。 示例 假设有以下 JSON 数据: json { "numbers": [1, 2, 3, 4, 5], "names": ["Alice", "Bob", "Charlie"] } 使用这个函数时: json11::Json json = /* 从某处获取 JSON 数据 */; std::vector<int> numbers = GetJson1DArr<int>(json, "numbers"); std::vector<std::string> names = GetJson1DArr<std::string>(json, "names"); numbers 将包含 {1, 2, 3, 4, 5},names 将包含 {"Alice", "Bob", "Charlie"}。 总结 该函数是一个模板函数,可以用于从 JSON 中提取任何类型的一维数组,并返回一个对应的 std::vector<DataType>。 通过传递不同的 DataType,可以灵活地处理不同类型的数组。 它利用 GetVal 函数将 JSON 中的每个元素转换为目标类型。
函数 CheckJson
的目的是检查 JSON 对象中的特定键对应的数组是否符合给定的要求,确保数组的大小和元素类型符合预期。让我们逐步分析这个函数的实现。
函数签名 cpp static MDmsStatus CheckJson(json11::Json const& json, std::string const& key, MJsonConfig::RequiredType const& required_type, int32_t const expected_size, JsonValDataType const type); 参数说明: json (json11::Json const&): 输入的 JSON 对象,包含需要检查的键值对。 key (std::string const&): 要检查的键名,函数会查找该键对应的值(预计是一个数组)。 required_type (MJsonConfig::RequiredType const&): 表示该键是否是必需的。它的类型是 MJsonConfig::RequiredType,可能包含 OPTIONAL(可选)和 REQUIRED(必需)等值。 expected_size (int32_t const): 期望的数组大小。如果该值大于 0,函数会验证数组的大小是否符合预期。 type (JsonValDataType const): 期望的数组元素的类型,函数会验证数组中每个元素是否符合该类型。 返回值: MDmsStatus: 函数返回一个 MDmsStatus 类型的状态,表示检查是否通过。如果成功返回 MDMS_SUCCESS,如果失败则返回错误状态(例如 MDMS_CONFIG_PARAM_INVALID)。 函数实现解析 1. 初始检查 JSON 数组 status = CheckJson(json, key, required_type, JsonValDataType::JSON_ARRAY); if (MDMS_SUCCESS != status) { break; } 该行调用了 CheckJson 函数来检查 json 对象中是否包含一个合法的数组类型。该检查的目的是确认 key 对应的值是一个 JSON 数组。 如果该数组的类型不匹配(即不是 JSON 数组),status 将被设定为非成功状态,函数会跳出检查。 2. 获取 JSON 对象和数组 json11::Json::object const& object_items{json.object_items()}; json11::Json::array const empty{}; size_t const kNum{object_items.count(key)}; json11::Json::array const* const array_items{ (kNum > 0U) ? &object_items.at(key).array_items() : &empty}; json.object_items() 提取 json 对象中的所有键值对,返回一个 std::map。 通过 object_items.count(key) 检查 key 是否存在。如果 key 存在,使用 object_items.at(key).array_items() 获取与该键对应的 JSON 数组。如果 key 不存在,则使用一个空数组 empty。 3. 检查数组的大小 if ((static_cast<size_t>(expected_size) != array_items->size()) && (expected_size > 0)) { if (MJsonConfig::RequiredType::OPTIONAL == required_type) { status = MDMS_SUCCESS; } else { status = MDMS_CONFIG_PARAM_INVALID; } break; } 如果 expected_size > 0 且数组的大小不等于 expected_size,则进入该判断。 如果该数组是 可选(required_type 为 OPTIONAL),即使数组大小不匹配,函数也返回 MDMS_SUCCESS。 如果该数组是 必需(required_type 为 REQUIRED),则返回 MDMS_CONFIG_PARAM_INVALID,表示参数无效。 4. 检查数组中每个元素的类型 for (size_t i{0U}; i < array_items->size(); ++i) { status = CheckJsonValType(array_items->at(i), type, required_type); if (MDMS_SUCCESS != status) { break; } } 遍历数组中的每个元素,调用 CheckJsonValType 函数检查每个元素的类型是否符合预期(type)。 如果有任何元素的类型不匹配,status 将被设定为错误状态,函数跳出循环。 5. 返回检查结果 return status; 最终,返回 status,表示检查的结果。如果所有检查都通过,则返回 MDMS_SUCCESS,否则返回适当的错误状态。 总结 这个函数的目的是对 JSON 中的一个键对应的数组进行全面的检查: 确保该键存在且值是一个 JSON 数组。 如果期望数组有特定的大小,检查数组的大小是否符合预期。 检查数组中每个元素的类型是否符合预期类型。 使用场景: 这个函数非常适合用于验证配置文件或 JSON 数据结构,特别是在对数组内容有严格要求时。例如,验证从 API 响应中获取的数组是否符合特定格式,或验证配置文件中的某个数组是否符合应用的要求。
GetJsonArr1DObj
的目的是从 JSON 对象中提取一个一维数组(每个元素是一个 JSON 对象),并将这些 JSON 对象存储到一个 std::vector<MJsonConfig>
容器中。它还通过一个指针 is_found
来表示是否成功找到并处理该键。
我们逐步解析该函数的实现:
函数签名 MDmsStatus MJsonConfig::GetJsonArr1DObj(std::string const& key, RequiredType const& required_type, int32_t const& expected_size, std::vector<MJsonConfig>* const val, bool* is_found) const; 参数说明: key (std::string const&): 需要查找的 JSON 键名。 required_type (RequiredType const&): 该键是否为必需,RequiredType 类型一般包含 REQUIRED(必需)和 OPTIONAL(可选)等枚举值。 expected_size (int32_t const&): 期望的数组大小。如果该值大于 0,函数会检查数组的大小是否与期望的大小匹配。 val (std::vector<MJsonConfig>* const): 一个指向 std::vector<MJsonConfig> 的指针,函数将把提取到的 JSON 数组(每个元素是一个 MJsonConfig 对象)存储在这个容器中。 is_found (bool*): 一个指向 bool 类型的指针,函数会在成功找到对应的 JSON 键时将其值设为 true,否则设为 false。 返回值: MDmsStatus: 函数返回一个 MDmsStatus 类型的状态,表示执行的结果。如果成功则返回 MDMS_SUCCESS,否则返回错误状态(例如 MDMS_PARAM_INVALID 或其他适当的错误状态)。 函数实现解析 1. 初始化和参数检查 if (nullptr != is_found) { *is_found = false; } if (val == nullptr) { status = MDMS_PARAM_INVALID; break; } 如果 is_found 不为 nullptr,将其值设置为 false,表示尚未找到指定的键。 如果 val 为 nullptr,说明传入的容器无效,函数会返回 MDMS_PARAM_INVALID 状态并中断执行。 2. 检查 JSON 对象 status = CheckJson(this->json_obj_, key, required_type, expected_size, JsonValDataType::JSON_OBJ); if (MDMS_SUCCESS != status) { } 调用 CheckJson 函数来检查 json_obj_ 中是否存在 key 键,并且该键对应的值是一个 JSON 对象数组。如果检查失败,status 将被设定为错误状态,但此处的 if 语句没有处理错误,这可能是一个冗余的部分。 3. 获取 JSON 数组 *val = GetJson1DArr<MJsonConfig>(this->json_obj_, key); 如果 CheckJson 检查成功,接下来调用 GetJson1DArr<MJsonConfig> 函数,从 json_obj_ 中提取对应 key 键的值,假设它是一个一维数组(数组的元素是 JSON 对象)。这些对象将被存储在 val 指向的容器中。 4. 更新 is_found if (nullptr != is_found) { *is_found = true; } 如果 is_found 不为 nullptr,说明成功找到了并处理了 key 键,此时将 is_found 设置为 true。 5. 返回状态 return status; 最终,返回 status,如果之前没有遇到错误,它的值应该是 MDMS_SUCCESS。 总结 该函数的主要任务是: 检查 JSON 对象中是否存在指定的键,并确保该键的值是一个 JSON 对象数组。 将该 JSON 对象数组中的元素提取并存储到 std::vector<MJsonConfig> 中。 如果提供了 is_found 指针,在成功处理完该键时将其设置为 true。 错误处理 如果 val 为 nullptr,函数立即返回 MDMS_PARAM_INVALID。 如果 CheckJson 函数检测到不匹配的类型或数组大小不符合要求,status 会被设置为错误状态,函数也会提前退出。 使用场景 这个函数适用于从 JSON 配置文件或响应中提取包含多个 JSON 对象的数组,并将其转化为一组 MJsonConfig 对象。例如,在处理来自 API 的响应时,如果返回的数据中包含一个对象数组,每个对象都需要转换成 MJsonConfig 实例,则可以使用这个函数来处理。
函数(如 GetJsonArr1DInt
, GetJsonArr1DStr
, GetJsonArr1DFloat
, GetJsonArr1DBool
)的主要作用是从 JSON 对象中提取一维数组,并根据传入的类型返回结果。每个函数的功能结构大致相同,区别在于它们处理的数据类型不同(整型、字符串、浮点型或布尔型)。
进一步处理二维:
这些代码片段是用来从 JSON 数据中提取二维数组,并且对 JSON 数据进行验证的。我们可以分成两个函数来看: 1. GetJson2DArr 这个模板函数 GetJson2DArr 的主要任务是从 JSON 数据中提取二维数组,并将其转换为 std::vector<std::vector<DataType>> 类型。以下是它的工作过程: 输入: json: 传入的 JSON 对象。 key: 要从 JSON 中提取的键名。 主要步骤: 通过 json.object_items() 提取 JSON 对象的键值对。 使用 object_items.count(key) 检查是否存在给定的 key。 如果找到了 key,则获取其对应的数组 array_items。 如果找不到该键,则使用一个空数组 empty 作为替代。 接下来,通过遍历 array_items 数组的每一项: 对每个数组项再次获取其内嵌的数组(array_items_tmp)。 使用 GetVal<DataType> 提取每个内嵌数组中的值,并将其填充到一个 std::vector<DataType> 中。 最终将每个内嵌的 std::vector<DataType> 添加到最终的 res 数组中。 输出: 返回一个 std::vector<std::vector<DataType>> 类型的二维数组。 总结: 这个函数的设计目标是处理 JSON 中嵌套的二维数组结构,假设 GetVal<DataType> 是用于将 JSON 元素转换为相应类型的函数。 2. CheckJson CheckJson 函数用于验证 JSON 数据的有效性,确保符合给定的配置要求。它是一个递归的验证函数,确保数组内的每一项满足特定的类型和大小要求。 输入: json: 传入的 JSON 对象。 key: 要验证的键名。 required_type: 需要的类型(例如:数组、对象、字符串等)。 expected_size1 和 expected_size2: 对数组大小的预期要求。 type: JSON 值的类型要求。 主要步骤: 调用 CheckJson 函数验证 JSON 是否包含指定的键 key,并且该键的值是否为数组类型。 使用 object_items.count(key) 查找该键是否存在。 如果找到了该键,提取其中的数组项(array_items),并且确保每个数组项本身也是一个数组。 然后,进一步检查数组中的每一项是否符合预期的大小(expected_size2),以及每一项是否符合指定的类型(通过 CheckJsonValType 来检查)。 如果数组中的某一项不符合预期,或者数组大小不符合要求,则返回 MDMS_CONFIG_PARAM_INVALID。 输出: 返回 MDmsStatus,表示 JSON 是否符合要求。 总结: 该函数用于验证 JSON 中的嵌套数组结构,确保数组的每一项满足特定的大小和类型要求,适用于复杂的 JSON 数据结构验证。 总体分析: GetJson2DArr: 该函数能够从 JSON 中提取一个二维数组结构,并将其转换为一个 std::vector<std::vector<DataType>> 类型。它适用于处理嵌套的 JSON 数组,并通过模板支持不同的数据类型(DataType)。它使用了双重循环来提取内嵌的数组并逐步填充结果。 CheckJson: 该函数用于验证 JSON 中的数据结构是否符合要求,主要检查指定键是否存在,并且键对应的值是否符合特定的类型和大小要求。它支持多层嵌套数组,并通过递归检查嵌套数组的结构和类型。 CheckJsonValType: CheckJson 函数中提到的 CheckJsonValType 是一个用于检查某个 JSON 值是否符合指定类型的函数,但没有提供实现细节。假设它是用来验证 JSON 值的类型,例如检查一个值是否是字符串、数字等。 改进建议: 性能优化: GetJson2DArr 需要通过双重循环遍历二维数组,若数据量较大时可能会影响性能,可以考虑优化遍历方式,尤其是对于嵌套数组较深的情况。 类型安全: 在 CheckJson 中,对于每个值的类型验证,CheckJsonValType 可能是一个很好的做法,但要确保类型检查函数能够覆盖所有可能的类型,并且对于未知类型能给出清晰的错误提示。 错误处理: 错误处理在 CheckJson 中是关键,当前在检查过程中,如果遇到任何问题就立即返回错误状态。虽然这种做法能够尽早停止处理,但在某些情况下可能需要更细致的错误信息,或对多个错误进行收集和处理。
进一步:
这些函数是 MJsonConfig 类的成员函数,用于从 JSON 数据中提取二维数组并转换为不同的数据类型(int32_t、float32_t、std::string、bool)。这些函数的模板结构非常类似,唯一的不同在于数据类型和对应的容器类型。下面是这些函数的详细分析以及一个示例。 函数解析 1. GetJsonArr2DInt
MDmsStatus MJsonConfig::GetJsonArr2DInt(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<int32_t> >* const val, bool* is_found) const; 功能:这个函数从 JSON 配置中提取一个二维整数数组,键名为 key。 参数说明: key:JSON 中存储二维数组的键名。 required_type:指定该键值的期望数据类型。 expected_size1 和 expected_size2:期望二维数组的大小,expected_size1 是外层数组的大小,expected_size2 是内层数组的大小。 val:函数输出,存储提取到的二维数组。 is_found:布尔类型指示是否找到了该键。 2. GetJsonArr2DFloat cpp MDmsStatus MJsonConfig::GetJsonArr2DFloat(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<float32_t> >* const val, bool* is_found) const; 功能:这个函数从 JSON 配置中提取一个二维浮点数组,键名为 key。 参数说明: key:JSON 中存储二维浮点数组的键名。 required_type:指定该键值的期望数据类型。 expected_size1 和 expected_size2:期望二维数组的大小。 val:函数输出,存储提取到的二维浮点数组。 is_found:布尔类型指示是否找到了该键。 3. GetJsonArr2DStr MDmsStatus MJsonConfig::GetJsonArr2DStr(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<std::string> >* const val, bool* is_found) const; 功能:这个函数从 JSON 配置中提取一个二维字符串数组,键名为 key。 参数说明: key:JSON 中存储二维字符串数组的键名。 required_type:指定该键值的期望数据类型。 expected_size1 和 expected_size2:期望二维数组的大小。 val:函数输出,存储提取到的二维字符串数组。 is_found:布尔类型指示是否找到了该键。 4. GetJsonArr2DBool MDmsStatus MJsonConfig::GetJsonArr2DBool(std::string const& key, RequiredType const& required_type, int32_t const& expected_size1, int32_t const& expected_size2, std::vector<std::vector<bool> >* const val, bool* is_found) const; 功能:这个函数从 JSON 配置中提取一个二维布尔数组,键名为 key。 参数说明: key:JSON 中存储二维布尔数组的键名。 required_type:指定该键值的期望数据类型。 expected_size1 和 expected_size2:期望二维数组的大小。 val:函数输出,存储提取到的二维布尔数组。 is_found:布尔类型指示是否找到了该键。 返回值: MDmsStatus:返回一个状态值,表示函数执行的结果(例如:是否成功提取了数据)。 举个例子: 假设我们有一个 JSON 配置文件如下: json { "intArray": [ [1, 2, 3], [4, 5, 6] ], "floatArray": [ [1.1, 2.2, 3.3], [4.4, 5.5, 6.6] ], "stringArray": [ ["apple", "banana"], ["cherry", "date"] ], "boolArray": [ [true, false], [false, true] ] } 我们可以使用这些函数来提取数据。 示例代码: MJsonConfig config; // 假设这个对象已经加载了 JSON 配置 std::vector<std::vector<int32_t>> intArray; std::vector<std::vector<float32_t>> floatArray; std::vector<std::vector<std::string>> stringArray; std::vector<std::vector<bool>> boolArray; bool isFound = false; // 提取二维整数数组 MDmsStatus status = config.GetJsonArr2DInt("intArray", RequiredType::Array, 2, 3, &intArray, &isFound); if (status == MDMS_OK && isFound) { // 成功获取数据 for (const auto& row : intArray) { for (int num : row) { std::cout << num << " "; } std::cout << std::endl; } } // 提取二维浮点数组 status = config.GetJsonArr2DFloat("floatArray", RequiredType::Array, 2, 3, &floatArray, &isFound); if (status == MDMS_OK && isFound) { // 成功获取数据 for (const auto& row : floatArray) { for (float num : row) { std::cout << num << " "; } std::cout << std::endl; } } // 提取二维字符串数组 status = config.GetJsonArr2DStr("stringArray", RequiredType::Array, 2, 2, &stringArray, &isFound); if (status == MDMS_OK && isFound) { // 成功获取数据 for (const auto& row : stringArray) { for (const auto& str : row) { std::cout << str << " "; } std::cout << std::endl; } } // 提取二维布尔数组 status = config.GetJsonArr2DBool("boolArray", RequiredType::Array, 2, 2, &boolArray, &isFound); if (status == MDMS_OK && isFound) { // 成功获取数据 for (const auto& row : boolArray) { for (bool b : row) { std::cout << (b ? "true" : "false") << " "; } std::cout << std::endl; } } 说明: 提取二维数组: GetJsonArr2DInt:提取二维整数数组并存储在 intArray 中。 GetJsonArr2DFloat:提取二维浮点数组并存储在 floatArray 中。 GetJsonArr2DStr:提取二维字符串数组并存储在 stringArray 中。 GetJsonArr2DBool:提取二维布尔数组并存储在 boolArray 中。 数据提取成功与否: 每个函数都返回一个 MDmsStatus,用于指示是否成功提取数据。 isFound 布尔变量指示是否找到了对应的键。 结果输出: 提取的二维数组会被遍历并输出到控制台。 这些函数帮助从复杂的 JSON 配置中提取和验证数据,适用于需要从 JSON 文件中处理不同类型的二维数组的场景。
使用的场景比如配置文件{
"license_manager": { "type": 0 }, "module_manager": { "thread_num_run": 1, "thread_num_init": 1, "hoi_iou_thres": 0.5, "high_performance": "Bigger", "activation_code_file": "/resources/sensetime/vehicle_activation_code", "log_level": 4, "modules": [ { "name": "FacePipeline", "default_enable": true, "parameters": { "strategy": "AIO+Track", "tracker_type": "OneThread"
}
] } }