抛弃GdCpp*.dll/pdb历史重新建库。libhv和Sqlite的dll保留
This commit is contained in:
249
include/json/CJsonFile.h
Normal file
249
include/json/CJsonFile.h
Normal file
@@ -0,0 +1,249 @@
|
||||
#ifndef CJSONFILE_H
|
||||
#define CJSONFILE_H
|
||||
|
||||
#include "_nlohmann_json_wrapper.h"
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <filesystem>
|
||||
#include <atlstr.h>
|
||||
namespace fs = std::filesystem;
|
||||
/** @addtogroup ksjson
|
||||
* @{
|
||||
* @addtogroup files
|
||||
* @brief json/bson file classes.
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief The CJsonFile class
|
||||
*/
|
||||
class CJsonFile // header only class
|
||||
{
|
||||
public:
|
||||
|
||||
CJsonFile()
|
||||
:needSave(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// \brief 构造函数
|
||||
/// \param filepath 指定文件绝对路径,只保存了文件名,并没有打开文件。
|
||||
/// 如果未设置,后续必须通过setFilePath()指定文件的绝对路径
|
||||
template<typename T>
|
||||
CJsonFile(T filepath)
|
||||
{
|
||||
setFilePath(filepath);
|
||||
}
|
||||
|
||||
/// 设置文件路径
|
||||
/// \param path 文件的绝对路径
|
||||
|
||||
void setFilePath(const char* path) { _filePath = path; }
|
||||
void setFilePath(const wchar_t* path) { _filePath = path; }
|
||||
void setFilePath(const fs::path& path) { _filePath = path; }
|
||||
#ifdef UNICODE
|
||||
void setFilePath(const CString& path) { _filePath = (const wchar_t*)path; }
|
||||
#endif
|
||||
|
||||
// 判断是否设置了路径,没有判断路径是否有效
|
||||
bool hasFilePath() const { return !_filePath.empty(); }
|
||||
|
||||
bool exists() const { return !_filePath.empty() && fs::exists(_filePath); }
|
||||
|
||||
virtual ~CJsonFile() = default;
|
||||
|
||||
protected:
|
||||
/// 参数文件完整路径。可以在构造函数里指定,或用setPath()指定
|
||||
fs::path _filePath;
|
||||
|
||||
public:
|
||||
/// 文件内容与内存变量之间中转的json格式cache。
|
||||
jsonobj cache;
|
||||
|
||||
/// 标记参数是否需要保存。
|
||||
int needSave = 0;
|
||||
|
||||
// 错误字符串
|
||||
std::string errStr;
|
||||
|
||||
/// 清空json缓存
|
||||
void clearCache() { cache = jsonobj(); }
|
||||
|
||||
/// 获取文件路径
|
||||
const fs::path& filePath() const { return _filePath; }
|
||||
|
||||
void reset() {
|
||||
cache.clear();
|
||||
_filePath.clear();
|
||||
}
|
||||
|
||||
enum {
|
||||
jFileNotExist=0,
|
||||
jFileOk =1,
|
||||
jFileFailOpenRead=-1,
|
||||
jFileFailOpenWrite=-2,
|
||||
jFileParseError=-3,
|
||||
jFileNull=-4,
|
||||
jFileOutputError=-5,
|
||||
jfileJsonToStructError=-6,
|
||||
jfileJsonFromStructError = -7,
|
||||
};
|
||||
|
||||
// ----保存和加载的函数相关 -----
|
||||
/// 从文件加载json/bson到cache,加载后关闭文件。
|
||||
/// 需要在构造函数中或用setFilePath()设置文件的完整路径
|
||||
/// \return 1: 文件打开ok,解析json正确;0:文件打开失败;-1:文件打开成功,解析json出错
|
||||
virtual int load()
|
||||
{
|
||||
// 调用处必须保证已经设置了路径
|
||||
_ASSERT(!_filePath.empty());
|
||||
|
||||
if (!fs::exists(_filePath)) {
|
||||
errStr = fmt::format("json文件不存在:{}", _filePath.string());
|
||||
return jFileNotExist;
|
||||
}
|
||||
|
||||
std::ifstream in(_filePath);
|
||||
if (in.is_open()) {
|
||||
try {
|
||||
in >> cache;
|
||||
needSave = 0;
|
||||
in.close();
|
||||
return jFileOk;
|
||||
}
|
||||
catch (jsonobj::exception& e) {
|
||||
//throw parse_error.101 in case of an unexpected token
|
||||
//throw parse_error.102 if to_unicode fails or surrogate error
|
||||
//throw parse_error.103 if to_unicode fails
|
||||
errStr = fmt::format("解析json出错:{}\n{}", _filePath.string(), e.what());
|
||||
in.close();
|
||||
return jFileParseError;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errStr = fmt::format("json文件只读打开失败:{}", _filePath.string());
|
||||
return jFileFailOpenRead;
|
||||
}
|
||||
}
|
||||
|
||||
/// 保存cache到指定的文件,覆盖文件内容,写完后关闭文件,但内存中保存json格式的cache。
|
||||
/// 需要在构造函数中或用setFilePath()设置文件的完整路径。
|
||||
/// \return 1: 文件保存成功;0: 文件创建失败;-1: json中有字符串不是utf-8
|
||||
virtual int save()
|
||||
{
|
||||
// 调用处必须保证已经设置了路径
|
||||
_ASSERT(!_filePath.empty());
|
||||
|
||||
std::ofstream o(_filePath, std::ofstream::trunc);
|
||||
if (o.is_open()) {
|
||||
try {
|
||||
o << std::setw(4) << cache << std::endl;
|
||||
o.flush();
|
||||
needSave = 0;
|
||||
return jFileOk;
|
||||
}
|
||||
catch (jsonobj::exception& e) {
|
||||
// throw type_error.316 if a string stored inside the JSON value is not UTF-8 encoded
|
||||
errStr = fmt::format("转换json文本出错:{}\n{}", _filePath.string(), e.what());
|
||||
return jFileOutputError;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errStr = fmt::format("json文件写入打开失败:{}", _filePath.string());
|
||||
return jFileFailOpenWrite;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int save(const T& src, bool clearBeforeSave=false) {
|
||||
if (clearBeforeSave) clearCache();
|
||||
try {
|
||||
to_json(cache, src);
|
||||
}
|
||||
catch (jsonobj::exception& e) {
|
||||
errStr = fmt::format("json<= 结构体出错:{}\n{}", _filePath.string(), e.what());
|
||||
return jfileJsonFromStructError;
|
||||
}
|
||||
|
||||
return save();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int load(T& dst) {
|
||||
|
||||
errStr.clear();
|
||||
int ret = jFileOk;
|
||||
do {
|
||||
ret = load();
|
||||
if (ret != 1) break;
|
||||
if (cache.is_null()) {
|
||||
errStr = fmt::format("读到的json是空的:{}", _filePath.string());
|
||||
ret = jFileNull;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
from_json(cache, dst);
|
||||
}
|
||||
catch (jsonobj::exception& e) {
|
||||
errStr = fmt::format("json => 结构体出错:{}\n{}", _filePath.string(), e.what());
|
||||
ret = jfileJsonToStructError;
|
||||
break;
|
||||
}
|
||||
return jFileOk;
|
||||
} while (0);
|
||||
alog->error(errStr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// 将cache中名为name的部分转到结构体T的实例dst
|
||||
template <typename T>
|
||||
int copyToStruct(const char* name, T& dst)
|
||||
{
|
||||
if (cache.contains(name)) {
|
||||
try {
|
||||
cache[name].get_to<T>(dst);
|
||||
}
|
||||
catch (jsonobj::exception& e) {
|
||||
errStr = fmt::format("json {} => 结构体出错:{}\n{}", name, _filePath.string(), e.what());
|
||||
return jfileJsonToStructError;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// 将结构体T的实例src内容转成json保存到cache中名为name的字段
|
||||
template <typename T>
|
||||
void saveToCache(const char* name, const T& src)
|
||||
{
|
||||
try {
|
||||
cache[name] = src;
|
||||
}
|
||||
catch (jsonobj::exception& e) {
|
||||
errStr = fmt::format("json {} <= 结构体出错:{}\n{}", name, _filePath.string(), e.what());
|
||||
return jfileJsonFromStructError;
|
||||
}
|
||||
needSave++;
|
||||
}
|
||||
};
|
||||
|
||||
class CBsonFile : public CJsonFile
|
||||
{
|
||||
public:
|
||||
/// 重载load函数,将json改成bson。
|
||||
virtual int load()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// 重载load函数,将json改成bson。
|
||||
virtual int save()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
/** @} files */
|
||||
/** @} ksjson */
|
||||
#endif // CJSONFILE_H
|
||||
Reference in New Issue
Block a user