574 lines
16 KiB
C++
574 lines
16 KiB
C++
#ifndef JSON_VC_WRAPPER_H
|
||
#define JSON_VC_WRAPPER_H
|
||
|
||
#include "_nlohmann_json_wrapper.h"
|
||
#include <atlstr.h> // for CString
|
||
#include <atltypes.h> // for CPoint, CSize, CRect
|
||
|
||
#include "StringHelper.h"
|
||
|
||
// wchar_t定义to_json没用,直接用j["keyname"] = utf16_8(wstr);
|
||
// GDCPP_API void to_json(jsonobj& j, const wchar_t * p);
|
||
|
||
// wstring定义to_json没用,直接用j["keyname"] = utf16_8(wstr);
|
||
// GDCPP_API void to_json(jsonobj& j, const std::wstring& p);
|
||
|
||
// std::wstring用from_josn会报错,用下面的toWstring
|
||
//GDCPP_API void from_json(const jsonobj& j, std::wstring& p);
|
||
bool toWstring(const jsonobj& j, std::wstring& dst);
|
||
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int readWstring(const jsonobj& j, KeyT key, std::wstring& dst)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
|
||
if (it->is_string()) { // 判断是否为string类型的数据,避免get函数抛出异常
|
||
dst = utf8_16(it->get<std::string>());
|
||
return 1;
|
||
}
|
||
else {
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int readWstringVector(const jsonobj& j, KeyT key, std::vector<std::wstring>& dst, bool clearbeforeread)
|
||
{
|
||
if (clearbeforeread) {
|
||
dst.clear();
|
||
}
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if (!it->is_array()) { //not array
|
||
return -1;
|
||
}
|
||
std::string str;
|
||
for (auto& i : *it) {
|
||
str = i.get<std::string>();
|
||
dst.push_back(utf8_16(str));
|
||
}
|
||
return int(it->size());
|
||
}
|
||
|
||
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int readWstring(const jsonobj& j, KeyT key, std::wstring& dst, const std::wstring &def)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
dst = def;
|
||
return 0;
|
||
}
|
||
|
||
if (it->is_string()) { // 判断是否为string类型的数据,避免get函数抛出异常
|
||
dst = utf8_16(it->get<std::string>());
|
||
return 1;
|
||
}
|
||
else {
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
void to_json(jsonobj& j, const CString& p);
|
||
void from_json(const jsonobj& j, CString& p);
|
||
|
||
void to_json(jsonobj& j, const CPoint& p);
|
||
void from_json(const jsonobj& j, CPoint& p);
|
||
|
||
void to_json(jsonobj& j, const CSize& p);
|
||
void from_json(const jsonobj& j, CSize& p);
|
||
|
||
void to_json(jsonobj& j, const CRect& p);
|
||
void from_json(const jsonobj& j, CRect& p);
|
||
|
||
|
||
/** @addtogroup Vector
|
||
* @brief std::vector <---> jsonobj
|
||
* @{*/
|
||
/// \brief std::vector <T> -> json,T不要是指针类型,模板匹配有问题
|
||
/// \details 注意会先清空j,如果j之前不是array也会强制变成array.
|
||
template <typename T>
|
||
void to_json(jsonobj& j, const std::vector <T>& p) {
|
||
j = jsonobj::array(); //先清空
|
||
int num = int(p.size());
|
||
for (int i = 0; i < num; i++) {
|
||
j.push_back(p.at(i));
|
||
}
|
||
}
|
||
|
||
/// \brief json -> std::vector <T>,T不要是指针类型,模板匹配有问题
|
||
/// \details 注意会先清空p!不想清空就用\ref readVector
|
||
template <typename T>
|
||
void from_json(const jsonobj& j, std::vector <T>& p) {
|
||
p.clear(); //先清空
|
||
if (j.is_array()) {
|
||
size_t num = j.size();
|
||
for (size_t i = 0; i < num; i++) {
|
||
p.push_back(j.at(i).get<T>());
|
||
}
|
||
}
|
||
}
|
||
|
||
/// \brief json --> std::vector<ValueT>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证
|
||
///
|
||
/// \param j nlohmann::json对象
|
||
/// \param key 键值,类型KeyT支持类型const char *, std::string
|
||
/// \param dst 目标变量。
|
||
/// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename = JsonKey<KeyT>::Type, typename ValueT>
|
||
int readVector(const jsonobj& j, KeyT key, std::vector<ValueT>& dst)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if (!it->is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(it->size());
|
||
for (int i = 0; i < num; i++) {
|
||
// 基础类不能用from_json,只能用get_to
|
||
dst.push_back(it->at(i).template get<ValueT>());
|
||
}
|
||
return num;
|
||
}
|
||
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename = JsonKey<KeyT>::Type, typename ValueT>
|
||
int readVector2D(const jsonobj& j, std::vector< std::vector<ValueT>>& dst)
|
||
{
|
||
if (!j.is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(j.size());
|
||
for (int i = 0; i < num; i++) {
|
||
std::vector<ValueT> sub;
|
||
readVector(j.at(i), sub);
|
||
dst.push_back(sub);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename = JsonKey<KeyT>::Type, typename ValueT>
|
||
int readVector2D(const jsonobj& j, KeyT key, std::vector< std::vector<ValueT>>& dst)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if (!it->is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(it->size());
|
||
for (int i = 0; i < num; i++) {
|
||
std::vector<ValueT> sub;
|
||
readVector(it->at(i), sub);
|
||
dst.push_back(sub);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
|
||
|
||
/// \brief json --> std::vector<ValueT>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证
|
||
///
|
||
/// \param j nlohmann::json对象
|
||
/// \param dst 目标变量。
|
||
/// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。
|
||
template <typename ValueT>
|
||
int readVector(const jsonobj& j, std::vector<ValueT>& dst)
|
||
{
|
||
if (!j.is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(j.size());
|
||
for (int i = 0; i < num; i++) {
|
||
ValueT tmp;
|
||
j.at(i).template get_to<ValueT>(tmp);
|
||
dst.push_back(tmp);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief json --> std::vector<ValueT*>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证
|
||
///
|
||
/// \param j nlohmann::json对象
|
||
/// \param key 键值,类型KeyT支持类型const char *, std::string
|
||
/// \param dst 目标变量。
|
||
/// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
|
||
int readPtrVector(const jsonobj& j, KeyT key, std::vector<ValueT*>& dst)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if (!it->is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(it->size());
|
||
for (int i = 0; i < num; i++) {
|
||
auto* item = new ValueT();
|
||
it->at(i).template get_to<ValueT>(*item);
|
||
dst.push_back(item);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief json --> std::vector<ValueT*>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证
|
||
///
|
||
/// \param j nlohmann::json对象
|
||
/// \param dst 目标变量。
|
||
/// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。
|
||
template <typename ValueT>
|
||
int readPtrVector(const jsonobj& j, std::vector<ValueT*>& dst)
|
||
{
|
||
if (!j.is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(j.size());
|
||
for (int i = 0; i < num; i++) {
|
||
auto* item = new ValueT();
|
||
j.at(i).template get_to<ValueT>(*item);
|
||
dst.push_back(item);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief std::vector<T> -> json
|
||
/// \details
|
||
template <typename T>
|
||
int writeVector(jsonobj& j, const std::vector<T>& p, bool clean=false) {
|
||
if (clean) {//写入前强制清空
|
||
j = jsonobj::array();
|
||
}else if (!j.is_array()) {
|
||
return -1;
|
||
}
|
||
int num = int(p.size());
|
||
for (int i = 0; i < num; i++) {
|
||
jsonobj x;
|
||
to_json(x, p.at(i));
|
||
j.push_back(x);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief std::vector<T> -> json
|
||
/// \details
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename T>
|
||
int writeVector(jsonobj& j, KeyT key, const std::vector<T>& p, bool clean = false) {
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null() || clean) {//没找到或强制清空
|
||
j[key] = jsonobj::array(); //先清空
|
||
}
|
||
else if (!it->is_array()) {
|
||
return -1;
|
||
}
|
||
int num = int(p.size());
|
||
for (int i = 0; i < num; i++) {
|
||
jsonobj x;
|
||
to_json(x, p.at(i));
|
||
j[key].push_back(x);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief std::vector<T*> -> json
|
||
/// \details
|
||
template <typename T>
|
||
int writePtrVector(jsonobj& j, const std::vector<T*>& p, bool clean = false) {
|
||
if (clean) {//写入前强制清空
|
||
j = jsonobj::array();
|
||
}
|
||
else if (!j.is_array()) {
|
||
return -1;
|
||
}
|
||
int num = int(p.size());
|
||
for (int i = 0; i < num; i++) {
|
||
jsonobj x;
|
||
to_json(x, *p.at(i));
|
||
j.push_back(x);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief std::vector<T*> -> json
|
||
/// \details
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename T>
|
||
int writePtrVector(jsonobj& j, KeyT key, const std::vector<T*>& p, bool clean=false) {
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null() || clean) {//没找到或强制清空
|
||
j[key] = jsonobj::array(); //先清空
|
||
}
|
||
else if (!it->is_array()) {
|
||
return -1;
|
||
}
|
||
int num = int(p.size());
|
||
for (int i = 0; i < num; i++) {
|
||
jsonobj x;
|
||
to_json(x, *p.at(i));
|
||
j[key].push_back(x);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief json --> std::vector<std::shared_ptr<ValueT>>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证
|
||
///
|
||
/// \param j nlohmann::json对象
|
||
/// \param key 键值,类型KeyT支持类型const char *, std::string
|
||
/// \param dst 目标变量。
|
||
/// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
|
||
int readSharedPtrVector(const jsonobj& j, KeyT key, std::vector<std::shared_ptr<ValueT>>& dst)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if (!it->is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(it->size());
|
||
for (int i = 0; i < num; i++) {
|
||
auto item = std::shared_ptr<ValueT>::create();
|
||
it->at(i).template get_to<ValueT>(*item);
|
||
dst.append(item);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief json --> std::vector<std::shared_ptr<ValueT>>,不会清除原有数据。注意没有判断json里的数据是否与ValueT类型匹配,需要应用层保证
|
||
///
|
||
/// \param j nlohmann::json对象
|
||
/// \param dst 目标变量。
|
||
/// \return 没找到返回0,找到但不是数组类型-1,有数据返回读到的数据类型。
|
||
template <typename ValueT>
|
||
int readSharedPtrVector(const jsonobj& j, std::vector<std::shared_ptr<ValueT>>& dst)
|
||
{
|
||
if (!j.is_array()) { //not array
|
||
return -1;
|
||
}
|
||
int num = int(j.size());
|
||
for (int i = 0; i < num; i++) {
|
||
auto item = std::shared_ptr<ValueT>::create();
|
||
j.at(i).template get_to<ValueT>(*item);
|
||
dst.append(item);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief std::vector<std::shared_ptr<T>> -> json
|
||
/// \details
|
||
template <typename T>
|
||
int writeSharedPtrVector(jsonobj& j, const std::vector<std::shared_ptr<T>>& p) {
|
||
if (!j.is_array()) {
|
||
return -1;
|
||
}
|
||
int num = int(p.count());
|
||
for (int i = 0; i < num; i++) {
|
||
jsonobj x;
|
||
to_json(x, *p.at(i));
|
||
j.push_back(x);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/// \brief std::vector<std::shared_ptr<T>> -> json
|
||
/// \details
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename T>
|
||
int writeSharedPtrVector(jsonobj& j, KeyT key, const std::vector<std::shared_ptr<T>>& p) {
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
j[key] = jsonobj::array(); //先清空
|
||
}
|
||
else if (!it->is_array()) {
|
||
return -1;
|
||
}
|
||
int num = int(p.count());
|
||
for (int i = 0; i < num; i++) {
|
||
jsonobj x;
|
||
to_json(x, *p.at(i));
|
||
j[key].push_back(x);
|
||
}
|
||
return num;
|
||
}
|
||
|
||
/** @} vector*/
|
||
|
||
|
||
/** @addtogroup Array
|
||
* @brief Array <---> jsonobj
|
||
* @{*/
|
||
|
||
/// \brief json --> 数组ValueT dst[maxnum]
|
||
/// 如果json中的数量超过maxnum,只读maxnum个,不报错。
|
||
/// \return 返回读到数据个数。<br>
|
||
/// 0表示没有找到key或数值为空,<br>
|
||
/// -1表示json[key]不是数组,<br>
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
|
||
int readArray(const jsonobj &j, KeyT key, ValueT* dst, unsigned maxnum)
|
||
{
|
||
auto it = j.find(key);
|
||
if(it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if(!it->is_array()){ //not array
|
||
return -1;
|
||
}
|
||
uint32_t num = uint32_t(it->size());
|
||
uint32_t readnum = (num > maxnum) ? maxnum : num;
|
||
|
||
for(uint32_t i=0; i< readnum; i++){
|
||
it->at(i).template get_to<ValueT>(dst[i]);
|
||
}
|
||
return int(readnum);
|
||
}
|
||
|
||
/// \brief json --> 数组ValueT dst[maxnum]
|
||
/// 如果json中的数量超过maxnum,只读maxnum个,不报错。
|
||
/// \return 返回读到数据个数。<br>
|
||
/// 0表示没有找到key或数值为空,<br>
|
||
/// -1表示json[key]不是数组,<br>
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
|
||
int readAnyArray(const jsonobj& j, KeyT key, ValueT* dst, unsigned maxnum)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if (!it->is_array()) { //not array
|
||
return -1;
|
||
}
|
||
uint32_t num = uint32_t(it->size());
|
||
uint32_t readnum = (num > maxnum) ? maxnum : num;
|
||
|
||
for (uint32_t i = 0; i < readnum; i++) {
|
||
from_json(it->at(i), dst[i]);
|
||
}
|
||
return int(readnum);
|
||
|
||
}
|
||
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int readWStringArray(const jsonobj& j, KeyT key, std::wstring* dst, unsigned maxnum)
|
||
{
|
||
auto it = j.find(key);
|
||
if (it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if (!it->is_array()) { //not array
|
||
return -1;
|
||
}
|
||
uint32_t num = uint32_t(it->size());
|
||
uint32_t readnum = (num > maxnum) ? maxnum : num;
|
||
|
||
std::string str;
|
||
for (uint32_t i = 0; i < readnum; i++) {
|
||
it->at(i).get_to(str);
|
||
dst[i] = utf8_16(str);
|
||
}
|
||
return int(readnum);
|
||
|
||
}
|
||
|
||
///获取json中名为key的数组长度,不存在或null返回0,不是数组返回-1,数组返回数组长度
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int readArrayNum(const jsonobj &j, KeyT key)
|
||
{
|
||
auto it = j.find(key);
|
||
if(it == j.end() || it->is_null()) {//没找到
|
||
return 0;
|
||
}
|
||
if(!it->is_array()){ //not array
|
||
return -1;
|
||
}
|
||
return int(it->size());
|
||
}
|
||
|
||
/// \brief 数组 ValueT src[num] -> json
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
|
||
int writeArray(jsonobj &j, KeyT key, const ValueT* src, size_t num)
|
||
{
|
||
auto tmp = jsonobj::array();
|
||
for (size_t i = 0; i < num; i++) {
|
||
tmp.push_back(src[i]);
|
||
}
|
||
|
||
j[key] = tmp;
|
||
|
||
return int(num);
|
||
}
|
||
|
||
/// \brief 数组 ValueT src[num] -> json
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type, typename ValueT>
|
||
int writeAnyArray(jsonobj& j, KeyT key, const ValueT* src, size_t num)
|
||
{
|
||
auto tmp = jsonobj::array();
|
||
jsonobj sub;
|
||
for (size_t i = 0; i < num; i++) {
|
||
to_json(sub, src[i]);
|
||
tmp.push_back(sub);
|
||
}
|
||
|
||
j[key] = tmp;
|
||
|
||
return int(num);
|
||
}
|
||
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int writeWStringArray(jsonobj& j, KeyT key, const std::wstring* src, size_t num)
|
||
{
|
||
j[key] = jsonobj::array();
|
||
|
||
auto& it = j[key];
|
||
std::string str;
|
||
for (size_t i = 0; i < num; i++) {
|
||
str=utf16_8(src[i]);
|
||
it.push_back(str);
|
||
}
|
||
|
||
return int(num);
|
||
}
|
||
/// \brief 数组 ValueT src[num] -> json
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int writeArray(jsonobj& j, KeyT key, const wchar_t ** src, size_t num)
|
||
{
|
||
j[key] = jsonobj::array();
|
||
|
||
auto& it = j[key];
|
||
|
||
USES_CONVERSION;
|
||
for (size_t i = 0; i < num; i++) {
|
||
it.push_back(W2A(src[i]));
|
||
}
|
||
|
||
return int(num);
|
||
}
|
||
|
||
/// \brief 数组 ValueT src[num] -> json
|
||
template <typename KeyT, typename = typename JsonKey<KeyT>::Type>
|
||
int writeArray(jsonobj& j, KeyT key, const char** src, size_t num)
|
||
{
|
||
j[key] = jsonobj::array();
|
||
|
||
auto& it = j[key];
|
||
|
||
USES_CONVERSION;
|
||
for (size_t i = 0; i < num; i++) {
|
||
it.push_back(src[i]);
|
||
}
|
||
|
||
return int(num);
|
||
}
|
||
|
||
|
||
/** @} Array*/
|
||
|
||
|
||
|
||
#endif // JSON_VC_WRAPPER_H
|