使用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 {
/*

各枚举值的说明:

  1. JSON_INT32:

    • 代表一个 32 位整数类型的值。通常用于表示整数数据,比如 123
  2. JSON_FLOAT32:

    • 代表一个 32 位浮点数类型的值。通常用于表示小数值,比如 3.14
  3. JSON_STRING:

    • 代表一个字符串类型的值。字符串数据通常用双引号括起来,比如 "Hello, World!"
  4. JSON_BOOL:

    • 代表一个布尔值。布尔值只能是 true 或 false,常用于表示逻辑状态或开关。
  5. JSON_OBJ:

    • 代表一个 JSON 对象类型。JSON 对象是一组键值对的集合,用大括号 {} 包围,比如 {"name": "John", "age": 30}
  6. JSON_ARRAY:

    • 代表一个 JSON 数组类型。JSON 数组是一组有序的值,值可以是任意类型,使用方括号 [] 包围,比如 [1, 2, 3] 或 ["apple", "banana", "cherry"]

总结:


这个枚举类型 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 函数的作用是:

  1. 打开指定路径的 JSON 配置文件。
  2. 读取文件内容并将其存储为一个字符串。
  3. 使用 json11 库解析 JSON 字符串。
  4. 如果文件打开失败或解析失败,函数会记录错误并返回相应的状态码。

 

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 函数可以根据传入的模板类型返回不同类型的值。

函数 CheckJsonValTypeCheckJson 主要用于检查 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*):

一个指向布尔值的指针,用于指示是否找到了指定的键。如果提供了这个参数,函数将在操作完成后将其设置为 truefalse,表示是否成功找到该键。
返回值
返回 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 是一个布尔值指针,它会被设置为 truefalse,表示是否成功从 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 设置为 true5. 返回状态
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::stringbool)。这些函数的模板结构非常类似,唯一的不同在于数据类型和对应的容器类型。下面是这些函数的详细分析以及一个示例。

函数解析
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"
}
] } }

 

posted @ 2025-04-08 15:18  白伟碧一些小心得  阅读(62)  评论(0)    收藏  举报