抛弃GdCpp*.dll/pdb历史重新建库。libhv和Sqlite的dll保留

This commit is contained in:
Zhang Jianjun
2026-02-02 16:09:02 +08:00
parent f148ca49e3
commit 4a2a284ac0
292 changed files with 350450 additions and 0 deletions

View File

@@ -0,0 +1,421 @@
#ifndef JSONREADWITHVERIFY_H
#define JSONREADWITHVERIFY_H
#include "_nlohmann_json_wrapper.h"
#include "ParaHelper.h"
#include "alog.h"
/** @addtogroup ksjson
* @{
* @addtogroup readWithVerify
* @brief 从json转换到数值前判断key是否存在确认数值是否在一定[min, max]范围内,或在一个数组列表范围之内。
* @{
*/
/// \brief 尝试从obj读取键值为key的数据没找到不赋值返回false找到就给指针赋值并返回true。
/// \details 通常用于已经初始化为默认值的变量或结构体,找到就读,没找到就保持默认值。
/// 注意保存的格式要跟写入的格式一致别写个string当int读肯定会出问题的。这里就没法检验格式是否正确了。
///
/// \param obj nlohmann::json对象
/// \param key 键值类型KeyT支持类型const char *, std::string
/// \param dst 目标变量类型ValueT可以是所有支持的数据类型包括nlohmann::json标准的数据类型和定义了to_json和from_json的类型。
/// \return 没找到返回0找到返回1。
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
int tryRead(const jsonobj& obj, KeyT key, ValueT& dst)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) return 0; //没找到
it->template get_to<ValueT>(dst);
return 1;
}
/// 尝试从obj读取键值为key的数据没找到设置为缺省值并返回false找到就读取数值给指针赋值并返回true。
/// 类型ValueT可以是所有支持的数据类型包括nlohmann::json标准的数据类型和定义了to_json和from_json的类型。
/// \param obj nlohmann::json对象
/// \param dst 目标变量。
/// \param key 键值类型KeyT支持类型const char *, std::string
/// \param def 找不到键值使用的缺省值。def的数据类型ValueT2必须与dst的数据类型ValueT可以直接隐式转换或复制构造的
/// \return 没找到返回false找到返回true。
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT, typename ValueT2>
int readWithDefault(const jsonobj& obj, KeyT key, ValueT& dst, ValueT2 def)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
dst = def;
return 0;
}
it->template get_to<ValueT>(dst);
return 1;
}
/// \brief 在\ref readWithDefault 基础上增加了校验读到的值是否在[min, max]范围之内。
/// \details 类型ValueT通常是数值类型。其它支持的数据类型如果它支持用大于号/小于号比较的类型也行,估计很少会用到。
/// \param obj nlohmann::json对象
/// \param key 键值类型KeyT支持类型const char *, std::string
/// \param dst 目标变量。
/// \param def 找不到键值使用的缺省值。def的数据类型必须与dst的数据类型可以直接转换的
/// \param min 取值范围的下限min << value << max
/// \param max 取值范围的上限min << value << max
/// \return 返回读取状态。
/// 没找到返回0找到但数值超界返回-1找到并在有效范围内返回1。
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT, typename ValueT2, typename ValueT3>
int readInRange(const jsonobj& obj, KeyT key, ValueT& dst, const ValueT2& def, const ValueT3& min, const ValueT3& max)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
dst = ValueT(def);
return 0;
}
ValueT tmp = it->template get<ValueT>();
if (tmp < ValueT(min)) {
dst = ValueT(min);
return -1;
}
else if (tmp > ValueT(max)) {//超界
dst = ValueT(max);
return -1;
}
// 返回读取值
dst = tmp;
return 1;
}
/// \brief 重载\ref readInRange 用sParaRange<ValueT>做取值范围的校验。
/// \details 用sParaRange的成员变量Def, Min, Max替代\ref readInRange的def, min, max参数
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
inline int readInRange(const jsonobj& obj, KeyT key, ValueT& dst, const sParaRange<ValueT>& range)
{
return readInRange(obj, key, dst, range.Def, range.Min, range.Max);
}
/// \brief json --> ValueT并校验数值是否在数组list[num]范围类
/// \details
/// - 没找到返回值为0dst设置为def<br>
/// - 找到但数值布置在列表范围内:返回值-1dst设置为def<br>
/// - 找到并在列表范围内返回1dst设置为解析值。<br>
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT, typename NumT, typename = ArraySizeT<NumT>::Type>
int readInList(const jsonobj& obj, KeyT key, ValueT& dst, const ValueT& def, const ValueT* list, NumT num)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
dst = def;
return 0;
}
ValueT tmp = it->template get<ValueT>();
for (int i = 0; i < num; i++) { //不在列表中
if (tmp == list[i]) {
dst = tmp;
return 1;
}
}
dst = def;
return -1;
}
/// \brief json --> ValueT并校验数值是否在QVector<ValueT>列表范围类
/// \details
/// - 没找到返回值为0dst设置为def<br>
/// - 找到但数值布置在列表范围内:返回值-1dst设置为def<br>
/// - 找到并在列表范围内返回1dst设置为解析值。<br>
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
int readInList(const jsonobj& obj, KeyT key, ValueT& dst, const ValueT& def, std::vector<ValueT> list)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
dst = def;
return 0;
}
ValueT tmp = it->template get<ValueT>();
if (list.contains(tmp)) {
dst = tmp;
return 1;
}
dst = def;
return -1;
}
/// \brief json --> ValueT并校验数值是否在QList<ValueT>列表范围类
/// \details
/// - 没找到返回值为0dst设置为def<br>
/// - 找到但数值布置在列表范围内:返回值-1dst设置为def<br>
/// - 找到并在列表范围内返回1dst设置为解析值。<br>
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
int readInList(const jsonobj& obj, KeyT key, ValueT& dst, const ValueT& def, std::list<ValueT> list)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
dst = def;
return 0;
}
ValueT tmp = it->template get<ValueT>();
if (list.contains(tmp)) {
dst = tmp;
return 1;
}
dst = def;
return -1;
}
/// \brief 从json读入string, 与strlist里的字符串比较确定枚举值。
/// \details
/// \param strlist 字符串列表
/// \param num 字符串个数
/// \param vallist 枚举值列表。<br>
/// vallist可以为null代表枚举值如果是从0开始顺序递增的dst设置为strlist数组的下标。<br>
/// \return <br>
/// - 没找到返回值为0dst设置为def<br>
/// - 找到但字符串不在列表范围内:返回值-1dst设置为def<br>
/// - 找到并在列表范围内返回1。如果vallist为nulldst设置strlist数组的下表如果vallist非空dst设置为对于的数组。<br>
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
int readEnum(const jsonobj& obj, KeyT key, ValueT& dst, int def, const char* const* strlist, int num, const int* vallist = nullptr)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
alog->warn("readEnum 没找到{},返回缺省值", key);
dst = ValueT(def);
return 0;
}
if (it->is_string()) {
std::string str = it->template get<std::string>();
for (int i = 0; i < num; i++) {
if (str.compare(strlist[i]) == 0) {
if (vallist) dst = ValueT(vallist[i]);
else dst = ValueT(i);
return 1;
}
}
alog->warn("readEnum {}没有匹配到字符串{},返回缺省值", key);
dst = ValueT(def);
}
else if (it->is_number_integer()) {
int val = it->template get<int>();
if (vallist) {
for (int i = 0; i < num; i++) {
if (val == vallist[i]) {
dst = ValueT(val);
return 1;
}
}
alog->warn("readEnum {}数值不在列表中,返回缺省值", key);
dst = ValueT(def);
}
else {
if (val >= 0 && val < num) {
dst = ValueT(val);
return 1;
}
else {
alog->warn("readEnum {}数值超界,返回缺省值", key);
dst = ValueT(def);
}
}
}
else {
alog->error("{}的json类型错误应该是字符串或整形未修改结果", key);
}
return -1;
}
// 与上一版本的区别是没有缺省值
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
int readEnum(const jsonobj& obj, KeyT key, ValueT& dst, const char* const * strlist, int num, const int* vallist = nullptr)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
alog->warn("readEnum 没找到{},返回缺省值", key);
return 0;
}
if (it->is_string()) {
std::string str = it->template get<std::string>();
for (int i = 0; i < num; i++) {
if (str.compare(strlist[i]) == 0) {
if (vallist) dst = ValueT(vallist[i]);
else dst = ValueT(i);
return 1;
}
}
alog->warn("readEnum {}没有匹配到字符串{},未赋值", key);
}
else if (it->is_number_integer()) {
int val = it->template get<int>();
if (vallist) {
for (int i = 0; i < num; i++) {
if (val == vallist[i]) {
dst = ValueT(val);
return 1;
}
}
alog->warn("readEnum {}数值不在列表中,未赋值", key);
}
else {
if (val >= 0 && val < num) {
dst = ValueT(val);
return 1;
}
else {
alog->warn("readEnum {}数值超界,未赋值", key);
}
}
}
else {
alog->error("{}的json类型错误应该是字符串或整形未修改结果", key);
}
return -1;
}
/// \brief 从json读入string, 与strlist里的字符串比较确定枚举值。
/// \details
/// \param strlist 字符串列表
/// \param vallist 枚举值列表。<br>
/// \return <br>
/// - 没找到返回值为0dst设置为def<br>
/// - 找到但字符串不在列表范围内:返回值-1dst设置为def<br>
/// - 找到并在列表范围内返回1。如果vallist为nulldst设置strlist数组的下表如果vallist非空dst设置为对于的数组。<br>
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT, typename ValutT2>
int readEnum(const jsonobj& obj, KeyT key, ValueT& dst, ValutT2 def, const char** strlist, const std::vector<ValueT>& vallist)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到
dst = ValueT(def);
return 0;
}
std::string str = it->template get<std::string>();
for (int i = 0; i < vallist.size(); i++) {
if (str.compare(strlist[i]) == 0) {
dst = vallist[i];
return 1;
}
}
dst = ValueT(def);
return -1;
}
/// 将C++枚举数组转换为字符串数组写入json
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
void writeEnumArray(jsonobj& obj, KeyT key, const char* const* strlist, int strnum, const std::vector<ValueT> &valuelist)
{
auto arr=jsonobj::array();
for(auto &val : valuelist) {
if (val < 0 || val >= strnum) {
alog->error("writeEnum {}数值超界", key);
return;
}
arr.push_back(strlist[val]);
}
obj[key] = arr;
}
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
int readEnumArray(const jsonobj& obj, KeyT key, std::vector<ValueT>& dst, const char* const* strlist, int num)
{
auto it = obj.find(key);
if (it == obj.end()) {//没找到
alog->warn("readEnumArray 没找到{}", key);
return 0;
}
if (!it->is_array()) {
alog->error("readEnumArray {} 不是数组", key);
return 0;
}
if (it->size() == 0) {
alog->error("readEnumArray {} 是空数组", key);
return 0;
}
dst.clear();
for (auto& x : *it) {
if (x.is_string()) {
std::string str=x.get<std::string >();
int i = 0;
for (; i < num; i++) {
if (str.compare(strlist[i]) == 0) {
dst.push_back(ValueT(i));
break;
}
}
if(i==num )alog->warn("readEnumArray {}没有匹配到字符串{},未赋值", key, str);
}
else {
alog->error("{}的json类型错误应该是字符串未修改结果", key);
}
}
return int(dst.size());
}
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
int readStr(const jsonobj& obj, const KeyT& key, char* dst, int dstsize)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到,或空
memset(dst, 0, dstsize);
return 0;
}
if (!it->is_string()) { //不是字符串
return -1;
}
std::string str = it->template get<std::string>();
auto len = str.length();
if (len >= dstsize) {
return -2;
}
else if (len == 0) {
*dst = 0;
return 1;
}
else {
memcpy(dst, str.c_str(), len);
*(dst + len) = 0;
return 1;
}
}
/// <summary>
/// 读入char型数值如果长度刚好填满不用0结束
/// </summary>
/// <typeparam name="KeyT"></typeparam>
/// <param name="obj"></param>
/// <param name="key"></param>
/// <param name="dst"></param>
/// <param name="dstsize"></param>
/// <returns></returns>
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
int readCharArray(const jsonobj& obj, const KeyT& key, char* dst, int dstsize, char fill)
{
auto it = obj.find(key);
if (it == obj.end() || it->is_null()) {//没找到,或空
memset(dst, 0, dstsize);
return 0;
}
if (!it->is_string()) { //不是字符串
return -1;
}
std::string str = it->template get<std::string>();
auto len = str.length();
if (len > dstsize) {
return -2;
}
else {
memcpy(dst, str.c_str(), len);
if (len < dstsize) {
memset(dst + len, fill, dstsize - len);
}
return 1;
}
}
/** @} readWithCheck*/
/** @} json*/
#endif // JSONREADWITHVERIFY_H