Files
GdCpp12/include/json/jsonVCWrapper.h

574 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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> -> jsonT不要是指针类型模板匹配有问题
/// \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