Fixed memory leak issue caused by incorrect deallocation order in the Json_Value destructor && Fixed issue where copy construction of read-only reference members in Json_Value failed to pass && Added read-only reference members for Json_Object and Json_Array && Added const qualifiers to methods that do not modify class members && Implemented JSON file parsing && Implemented JSON file export, supporting minified export and pretty print.
This commit is contained in:
parent
b11e74e815
commit
e80d14d347
@ -21,6 +21,23 @@ class Json_Value; // Json 值(可以是数组、对象、字符串、浮点
|
|||||||
*/
|
*/
|
||||||
std::string JsonFile_FormatCheck(const char *path_to_file);
|
std::string JsonFile_FormatCheck(const char *path_to_file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 解析Json文件
|
||||||
|
* @param path_to_file 文件路径串
|
||||||
|
* @param pJson_Value Value 指针
|
||||||
|
* @return std::string 错误值
|
||||||
|
*/
|
||||||
|
std::string JsonFile_Parse(const char *path_to_file, Json_Value *pJson_Value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Json对象保存
|
||||||
|
* @param path_to_file 文件路径串
|
||||||
|
* @param value Json Value
|
||||||
|
* @param enable_pretty_print 启用美观打印
|
||||||
|
* @return std::string 错误值
|
||||||
|
*/
|
||||||
|
std::string Json_Export(const char *path_to_file, Json_Value value, bool enable_pretty_print = true);
|
||||||
|
|
||||||
// Json 数组
|
// Json 数组
|
||||||
class Json_Arry
|
class Json_Arry
|
||||||
{
|
{
|
||||||
@ -29,6 +46,9 @@ private:
|
|||||||
std::vector<Json_Value> private_element_list;
|
std::vector<Json_Value> private_element_list;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// 只读引用
|
||||||
|
const std::vector<Json_Value> &element_list = this->private_element_list;
|
||||||
|
|
||||||
// 默认构造
|
// 默认构造
|
||||||
Json_Arry() = default;
|
Json_Arry() = default;
|
||||||
// 列表构造
|
// 列表构造
|
||||||
@ -38,12 +58,12 @@ public:
|
|||||||
// 深拷贝
|
// 深拷贝
|
||||||
Json_Arry &operator=(const Json_Arry &another);
|
Json_Arry &operator=(const Json_Arry &another);
|
||||||
// 获取元素大小
|
// 获取元素大小
|
||||||
size_t size(void);
|
size_t size(void) const;
|
||||||
// 数组索引重载
|
// 数组索引重载
|
||||||
Json_Value operator[](size_t index);
|
Json_Value operator[](size_t index) const;
|
||||||
|
|
||||||
// 是否为空
|
// 是否为空
|
||||||
bool isNull(void);
|
bool isNull(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Json 值定义
|
// Json 值定义
|
||||||
@ -92,15 +112,15 @@ public:
|
|||||||
~Json_Value();
|
~Json_Value();
|
||||||
|
|
||||||
// 获取值
|
// 获取值
|
||||||
std::string asString(void);
|
std::string asString(void) const;
|
||||||
Json_Arry asArry(void);
|
Json_Arry asArry(void) const;
|
||||||
Json_Object asObject(void);
|
Json_Object asObject(void) const;
|
||||||
int64_t asInteger(void);
|
int64_t asInteger(void) const;
|
||||||
double asFloat(void);
|
double asFloat(void) const;
|
||||||
bool asBoolean(void);
|
bool asBoolean(void) const;
|
||||||
|
|
||||||
// 是否为空
|
// 是否为空
|
||||||
bool isNull(void);
|
bool isNull(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Json 键值对定义
|
// Json 键值对定义
|
||||||
@ -126,7 +146,7 @@ public:
|
|||||||
Json_Pair &operator=(const Json_Pair &another);
|
Json_Pair &operator=(const Json_Pair &another);
|
||||||
|
|
||||||
// 空判定
|
// 空判定
|
||||||
bool isNull();
|
bool isNull() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Json 对象
|
// Json 对象
|
||||||
@ -137,6 +157,9 @@ private:
|
|||||||
std::vector<Json_Pair> private_element_list;
|
std::vector<Json_Pair> private_element_list;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// 只读引用
|
||||||
|
std::vector<Json_Pair> const &element_list = this->private_element_list;
|
||||||
|
|
||||||
// 默认构造
|
// 默认构造
|
||||||
Json_Object() = default;
|
Json_Object() = default;
|
||||||
// 列表构造
|
// 列表构造
|
||||||
@ -147,15 +170,15 @@ public:
|
|||||||
Json_Object &operator=(const Json_Object &another);
|
Json_Object &operator=(const Json_Object &another);
|
||||||
|
|
||||||
// 获取元素大小
|
// 获取元素大小
|
||||||
size_t size(void);
|
size_t size(void) const;
|
||||||
// 数组索引重载
|
// 数组索引重载
|
||||||
Json_Pair operator[](size_t index);
|
Json_Pair operator[](size_t index) const;
|
||||||
|
|
||||||
// 由Key 查找值
|
// 由Key 查找值
|
||||||
Json_Value get(std::string key);
|
Json_Value get(std::string key) const;
|
||||||
|
|
||||||
// 是否为空
|
// 是否为空
|
||||||
bool isNull(void);
|
bool isNull(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -4,6 +4,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "functional"
|
#include "functional"
|
||||||
@ -211,14 +212,13 @@ std::string JsonFile_FormatCheck(const char *path_to_file)
|
|||||||
column_count++;
|
column_count++;
|
||||||
switch (ch_get)
|
switch (ch_get)
|
||||||
{
|
{
|
||||||
case EOF:
|
|
||||||
return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
|
|
||||||
case '\r':
|
case '\r':
|
||||||
case ',':
|
case ',':
|
||||||
case '}':
|
case '}':
|
||||||
case ']':
|
case ']':
|
||||||
column_count--;
|
column_count--;
|
||||||
fseek(pFile, -1, SEEK_CUR);
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
case EOF:
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\n':
|
case '\n':
|
||||||
segment_finish = true;
|
segment_finish = true;
|
||||||
@ -385,7 +385,8 @@ std::string JsonFile_FormatCheck(const char *path_to_file)
|
|||||||
err_str = std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
|
err_str = std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err_str = std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Syntax error. Must begin with '{' or '['.";
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
err_str = Check_Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭文件
|
// 关闭文件
|
||||||
@ -393,6 +394,417 @@ std::string JsonFile_FormatCheck(const char *path_to_file)
|
|||||||
return err_str;
|
return err_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 解析Json文件
|
||||||
|
* @param path_to_file 文件路径串
|
||||||
|
* @param pJson_Value Value 指针
|
||||||
|
* @return std::string 错误值
|
||||||
|
*/
|
||||||
|
std::string JsonFile_Parse(const char *path_to_file, Json_Value *pJson_Value)
|
||||||
|
{
|
||||||
|
// 存在格式错误时返回NULL值,通过格式检查时信任后续的输入
|
||||||
|
std::string err_str = JsonFile_FormatCheck(path_to_file);
|
||||||
|
if (!err_str.empty())
|
||||||
|
return err_str;
|
||||||
|
|
||||||
|
// 尝试打开文件
|
||||||
|
FILE *pFile = fopen(path_to_file, "rb");
|
||||||
|
if (pFile == nullptr)
|
||||||
|
return "file \"" + std::string(path_to_file) + "\" open failed.";
|
||||||
|
|
||||||
|
// 跳过空白部分 return -> skip count
|
||||||
|
auto Lambda_skip_blank = [&](void) -> size_t
|
||||||
|
{
|
||||||
|
size_t read_count = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
switch (fgetc(pFile))
|
||||||
|
{
|
||||||
|
case EOF:
|
||||||
|
return read_count;
|
||||||
|
case ' ':
|
||||||
|
read_count++;
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
if (fgetc(pFile) == '\n')
|
||||||
|
{
|
||||||
|
read_count += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fseek(pFile, -2, SEEK_CUR);
|
||||||
|
return read_count;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
read_count++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
return read_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 函数封装
|
||||||
|
std::function<Json_Object(void)> Parse_Object;
|
||||||
|
std::function<Json_Value(void)> Parse_Value;
|
||||||
|
std::function<Json_Arry(void)> Parse_Arry;
|
||||||
|
std::function<Json_Pair(void)> Parse_Pair;
|
||||||
|
|
||||||
|
// 函数定义
|
||||||
|
Parse_Object = [&](void) -> Json_Object
|
||||||
|
{
|
||||||
|
Json_Object temp_obj;
|
||||||
|
Lambda_skip_blank();
|
||||||
|
|
||||||
|
// 拿掉第一个 '{'
|
||||||
|
char ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Lambda_skip_blank();
|
||||||
|
ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
switch (ch_get)
|
||||||
|
{
|
||||||
|
case '}':
|
||||||
|
return temp_obj;
|
||||||
|
case '\"':
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
{
|
||||||
|
std::vector<Json_Pair> pair_list = temp_obj.element_list;
|
||||||
|
pair_list.push_back(Parse_Pair());
|
||||||
|
temp_obj = Json_Object(pair_list);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Parse_Value = [&](void) -> Json_Value
|
||||||
|
{
|
||||||
|
Lambda_skip_blank();
|
||||||
|
|
||||||
|
bool is_string = false;
|
||||||
|
char ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
// 判定第一个字符
|
||||||
|
switch (ch_get)
|
||||||
|
{
|
||||||
|
case '\"':
|
||||||
|
is_string = true;
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
return Parse_Object();
|
||||||
|
case '[':
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
return Parse_Arry();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判定为字符串
|
||||||
|
if (is_string)
|
||||||
|
{
|
||||||
|
std::string value_str;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
switch (ch_get)
|
||||||
|
{
|
||||||
|
case '\"':
|
||||||
|
return value_str;
|
||||||
|
case '\\': // 转义符
|
||||||
|
ch_get = fgetc(pFile);
|
||||||
|
value_str.push_back('\\');
|
||||||
|
value_str.push_back(ch_get);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value_str.push_back(ch_get);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
|
||||||
|
// 识别非字符串类型Json值
|
||||||
|
std::string segment_read;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
bool segment_finish = false;
|
||||||
|
|
||||||
|
ch_get = fgetc(pFile);
|
||||||
|
switch (ch_get)
|
||||||
|
{
|
||||||
|
case '\r':
|
||||||
|
case ',':
|
||||||
|
case '}':
|
||||||
|
case ']':
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
case EOF:
|
||||||
|
case ' ':
|
||||||
|
case '\n':
|
||||||
|
segment_finish = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
segment_read += ch_get;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment_finish)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 逻辑值识别
|
||||||
|
if (segment_read == "true")
|
||||||
|
return true;
|
||||||
|
if (segment_read == "false")
|
||||||
|
return false;
|
||||||
|
if (segment_read == "null")
|
||||||
|
return Json_Value();
|
||||||
|
|
||||||
|
// 数值识别
|
||||||
|
if (strstr(segment_read.c_str(), "e") || strstr(segment_read.c_str(), "."))
|
||||||
|
return strtod(segment_read.c_str(), nullptr);
|
||||||
|
else
|
||||||
|
return strtoll(segment_read.c_str(), nullptr, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
Parse_Arry = [&](void) -> Json_Arry
|
||||||
|
{
|
||||||
|
Lambda_skip_blank();
|
||||||
|
|
||||||
|
// 拿掉第一个 '['
|
||||||
|
char ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
std::vector<Json_Value> value_list;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Lambda_skip_blank();
|
||||||
|
ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
switch (ch_get)
|
||||||
|
{
|
||||||
|
case ']':
|
||||||
|
return value_list;
|
||||||
|
case ',':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
value_list.push_back(Parse_Value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Parse_Pair = [&](void) -> Json_Pair
|
||||||
|
{
|
||||||
|
std::string key_str;
|
||||||
|
Lambda_skip_blank();
|
||||||
|
|
||||||
|
// 拿掉第一个 '\"'
|
||||||
|
char ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
// 遍历下一个引号
|
||||||
|
bool key_end = false;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
switch (ch_get)
|
||||||
|
{
|
||||||
|
case '\"':
|
||||||
|
key_end = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
key_str.push_back(ch_get);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_end)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拿掉键值对标记
|
||||||
|
Lambda_skip_blank();
|
||||||
|
ch_get = fgetc(pFile);
|
||||||
|
|
||||||
|
// 返回键值对
|
||||||
|
return Json_Pair(key_str, Parse_Value());
|
||||||
|
};
|
||||||
|
|
||||||
|
// 跳过空白检查第一个字符
|
||||||
|
Lambda_skip_blank();
|
||||||
|
switch (fgetc(pFile))
|
||||||
|
{
|
||||||
|
case '[':
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
*pJson_Value = Parse_Arry();
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
*pJson_Value = Parse_Object();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fseek(pFile, -1, SEEK_CUR);
|
||||||
|
*pJson_Value = Parse_Value();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(pFile);
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Json对象保存
|
||||||
|
* @param path_to_file 文件路径串
|
||||||
|
* @param value Json Value
|
||||||
|
* @param enable_pretty_print 启用美观打印
|
||||||
|
* @return std::string 错误值
|
||||||
|
*/
|
||||||
|
std::string Json_Export(const char *path_to_file, Json_Value value, bool enable_pretty_print)
|
||||||
|
{
|
||||||
|
// 打开文件
|
||||||
|
FILE *pFile = fopen(path_to_file, "wb");
|
||||||
|
if (pFile == nullptr)
|
||||||
|
{
|
||||||
|
fclose(pFile);
|
||||||
|
return "file \"" + std::string(path_to_file) + "\" open failed.";
|
||||||
|
}
|
||||||
|
// 函数封装
|
||||||
|
std::function<void(const Json_Object &, size_t, bool)> Export_Object;
|
||||||
|
std::function<void(const Json_Value &, size_t, bool)> Export_Value;
|
||||||
|
std::function<void(const Json_Arry &, size_t, bool)> Export_Arry;
|
||||||
|
std::function<void(const Json_Pair &, size_t)> Export_Pair;
|
||||||
|
|
||||||
|
// 函数定义
|
||||||
|
Export_Object = [&](const Json_Object &obj, size_t depth, bool first_line_indent)
|
||||||
|
{
|
||||||
|
// 首行缩进
|
||||||
|
if (enable_pretty_print && first_line_indent)
|
||||||
|
for (size_t count = 0; count < depth; count++)
|
||||||
|
fprintf(pFile, " ");
|
||||||
|
|
||||||
|
// 对象起始
|
||||||
|
fprintf(pFile, "{");
|
||||||
|
if (enable_pretty_print && (!obj.isNull()))
|
||||||
|
fprintf(pFile, "\r\n");
|
||||||
|
|
||||||
|
// 输出键值对
|
||||||
|
for (auto pair : obj.element_list)
|
||||||
|
{
|
||||||
|
Export_Pair(pair, depth + 1);
|
||||||
|
fprintf(pFile, enable_pretty_print ? ",\r\n" : ",");
|
||||||
|
}
|
||||||
|
if (!obj.isNull())
|
||||||
|
{
|
||||||
|
fseek(pFile, enable_pretty_print ? -3 : -1, SEEK_CUR);
|
||||||
|
if (enable_pretty_print)
|
||||||
|
fprintf(pFile, "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尾部缩进
|
||||||
|
if (enable_pretty_print && (!obj.isNull()))
|
||||||
|
for (size_t count = 0; count < depth; count++)
|
||||||
|
fprintf(pFile, " ");
|
||||||
|
|
||||||
|
// 对象结束
|
||||||
|
fprintf(pFile, "}");
|
||||||
|
};
|
||||||
|
|
||||||
|
Export_Value = [&](const Json_Value &value, size_t depth, bool indent)
|
||||||
|
{
|
||||||
|
if (enable_pretty_print && indent)
|
||||||
|
for (size_t count = 0; count < depth; count++)
|
||||||
|
fprintf(pFile, " ");
|
||||||
|
switch (value.type)
|
||||||
|
{
|
||||||
|
case Json_Value::TYPE_NULL: // 空值
|
||||||
|
fprintf(pFile, "null");
|
||||||
|
break;
|
||||||
|
case Json_Value::TYPE_STR: // 字符串
|
||||||
|
fprintf(pFile, "\"%s\"", value.asString().c_str());
|
||||||
|
break;
|
||||||
|
case Json_Value::TYPE_ARRY: // 数组
|
||||||
|
Export_Arry(value.asArry(), depth, false);
|
||||||
|
break;
|
||||||
|
case Json_Value::TYPE_OBJ: // 对象
|
||||||
|
Export_Object(value.asObject(), depth, false);
|
||||||
|
break;
|
||||||
|
case Json_Value::TYPE_NUM_INTEGER: // 整数常数
|
||||||
|
fprintf(pFile, "%lld", value.asInteger());
|
||||||
|
break;
|
||||||
|
case Json_Value::TYPE_NUM_FLOAT: // 浮点常数
|
||||||
|
fprintf(pFile, "%e", value.asFloat());
|
||||||
|
break;
|
||||||
|
case Json_Value::TYPE_BOOLEAN: // 布尔逻辑值
|
||||||
|
if (value.asBoolean() == true)
|
||||||
|
fprintf(pFile, "true");
|
||||||
|
else
|
||||||
|
fprintf(pFile, "false");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Export_Pair = [&](const Json_Pair &pair, size_t depth)
|
||||||
|
{
|
||||||
|
if (enable_pretty_print)
|
||||||
|
for (size_t count = 0; count < depth; count++)
|
||||||
|
fprintf(pFile, " ");
|
||||||
|
|
||||||
|
fprintf(pFile, "\"%s\":", pair.key.c_str());
|
||||||
|
if (enable_pretty_print)
|
||||||
|
fprintf(pFile, " ");
|
||||||
|
Export_Value(pair.value, depth, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
Export_Arry = [&](const Json_Arry &arry, size_t depth, bool first_line_indent)
|
||||||
|
{
|
||||||
|
// 首行缩进
|
||||||
|
if (enable_pretty_print && first_line_indent)
|
||||||
|
for (size_t count = 0; count < depth; count++)
|
||||||
|
fprintf(pFile, " ");
|
||||||
|
|
||||||
|
// 数组起始
|
||||||
|
fprintf(pFile, "[");
|
||||||
|
if (enable_pretty_print && (!arry.isNull()))
|
||||||
|
fprintf(pFile, "\r\n");
|
||||||
|
|
||||||
|
// 输出数组数值
|
||||||
|
for (auto value : arry.element_list)
|
||||||
|
{
|
||||||
|
Export_Value(value, depth + 1, true);
|
||||||
|
fprintf(pFile, enable_pretty_print ? ",\r\n" : ",");
|
||||||
|
}
|
||||||
|
if (!arry.isNull())
|
||||||
|
{
|
||||||
|
fseek(pFile, enable_pretty_print ? -3 : -1, SEEK_CUR);
|
||||||
|
if (enable_pretty_print)
|
||||||
|
fprintf(pFile, "\r\n");
|
||||||
|
}
|
||||||
|
// 尾部缩进
|
||||||
|
if (enable_pretty_print && (!value.isNull()))
|
||||||
|
for (size_t count = 0; count < depth; count++)
|
||||||
|
fprintf(pFile, " ");
|
||||||
|
|
||||||
|
// 对象结束
|
||||||
|
fprintf(pFile, "]");
|
||||||
|
};
|
||||||
|
|
||||||
|
if (value.type == Json_Value::TYPE_OBJ)
|
||||||
|
Export_Object(value.asObject(), 0, false);
|
||||||
|
else if (value.type == Json_Value::TYPE_ARRY)
|
||||||
|
Export_Arry(value.asArry(), 0, false);
|
||||||
|
else
|
||||||
|
Export_Value(value, 0, false);
|
||||||
|
|
||||||
|
fclose(pFile);
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
// std::string 构造
|
// std::string 构造
|
||||||
Json_Value::Json_Value(std::string str) : private_type(TYPE_STR), p_mem(malloc(sizeof(str)))
|
Json_Value::Json_Value(std::string str) : private_type(TYPE_STR), p_mem(malloc(sizeof(str)))
|
||||||
{
|
{
|
||||||
@ -469,17 +881,26 @@ Json_Value &Json_Value::operator=(const Json_Value &another)
|
|||||||
case TYPE_STR:
|
case TYPE_STR:
|
||||||
this->p_mem = malloc(sizeof(std::string));
|
this->p_mem = malloc(sizeof(std::string));
|
||||||
if (this->p_mem != nullptr)
|
if (this->p_mem != nullptr)
|
||||||
new (this->p_mem) std::string(*((std::string *)another.p_mem));
|
{
|
||||||
|
new (this->p_mem) std::string();
|
||||||
|
*((std::string *)this->p_mem) = *((std::string *)another.p_mem);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_ARRY:
|
case TYPE_ARRY:
|
||||||
this->p_mem = malloc(sizeof(Json_Arry));
|
this->p_mem = malloc(sizeof(Json_Arry));
|
||||||
if (this->p_mem != nullptr)
|
if (this->p_mem != nullptr)
|
||||||
new (this->p_mem) Json_Arry(*((Json_Arry *)another.p_mem));
|
{
|
||||||
|
new (this->p_mem) Json_Arry();
|
||||||
|
*((Json_Arry *)this->p_mem) = *((Json_Arry *)another.p_mem);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_OBJ:
|
case TYPE_OBJ:
|
||||||
this->p_mem = malloc(sizeof(Json_Object));
|
this->p_mem = malloc(sizeof(Json_Object));
|
||||||
if (this->p_mem != nullptr)
|
if (this->p_mem != nullptr)
|
||||||
new (this->p_mem) Json_Object(*((Json_Object *)another.p_mem));
|
{
|
||||||
|
new (this->p_mem) Json_Object();
|
||||||
|
*((Json_Object *)this->p_mem) = *((Json_Object *)another.p_mem);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_NUM_INTEGER:
|
case TYPE_NUM_INTEGER:
|
||||||
this->p_mem = malloc(sizeof(int64_t));
|
this->p_mem = malloc(sizeof(int64_t));
|
||||||
@ -507,12 +928,10 @@ Json_Value &Json_Value::operator=(const Json_Value &another)
|
|||||||
// 析构
|
// 析构
|
||||||
Json_Value::~Json_Value()
|
Json_Value::~Json_Value()
|
||||||
{
|
{
|
||||||
this->private_type = TYPE_NULL;
|
|
||||||
|
|
||||||
if (this->p_mem != nullptr)
|
if (this->p_mem != nullptr)
|
||||||
{
|
{
|
||||||
// 对象析构
|
// 对象析构
|
||||||
switch (this->type)
|
switch (this->private_type)
|
||||||
{
|
{
|
||||||
case TYPE_STR:
|
case TYPE_STR:
|
||||||
((std::string *)p_mem)->~basic_string();
|
((std::string *)p_mem)->~basic_string();
|
||||||
@ -530,10 +949,11 @@ Json_Value::~Json_Value()
|
|||||||
// 释放内存
|
// 释放内存
|
||||||
free(p_mem);
|
free(p_mem);
|
||||||
}
|
}
|
||||||
|
this->private_type = TYPE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 作为直接值获取
|
// 作为直接值获取
|
||||||
std::string Json_Value::asString(void)
|
std::string Json_Value::asString(void) const
|
||||||
{
|
{
|
||||||
if (this->type == TYPE_STR)
|
if (this->type == TYPE_STR)
|
||||||
return *(std::string *)this->p_mem;
|
return *(std::string *)this->p_mem;
|
||||||
@ -542,7 +962,7 @@ std::string Json_Value::asString(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 作为 Json_Arry 获取
|
// 作为 Json_Arry 获取
|
||||||
Json_Arry Json_Value::asArry(void)
|
Json_Arry Json_Value::asArry(void) const
|
||||||
{
|
{
|
||||||
if (this->type == TYPE_ARRY)
|
if (this->type == TYPE_ARRY)
|
||||||
return *(Json_Arry *)this->p_mem;
|
return *(Json_Arry *)this->p_mem;
|
||||||
@ -551,7 +971,7 @@ Json_Arry Json_Value::asArry(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 作为 Json_Object 获取
|
// 作为 Json_Object 获取
|
||||||
Json_Object Json_Value::asObject(void)
|
Json_Object Json_Value::asObject(void) const
|
||||||
{
|
{
|
||||||
if (this->type == TYPE_OBJ)
|
if (this->type == TYPE_OBJ)
|
||||||
return *(Json_Object *)this->p_mem;
|
return *(Json_Object *)this->p_mem;
|
||||||
@ -560,7 +980,7 @@ Json_Object Json_Value::asObject(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 作为 int64 获取
|
// 作为 int64 获取
|
||||||
int64_t Json_Value::asInteger(void)
|
int64_t Json_Value::asInteger(void) const
|
||||||
{
|
{
|
||||||
if (this->type == TYPE_NUM_INTEGER)
|
if (this->type == TYPE_NUM_INTEGER)
|
||||||
return *(int64_t *)this->p_mem;
|
return *(int64_t *)this->p_mem;
|
||||||
@ -569,7 +989,7 @@ int64_t Json_Value::asInteger(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 作为 double 获取
|
// 作为 double 获取
|
||||||
double Json_Value::asFloat(void)
|
double Json_Value::asFloat(void) const
|
||||||
{
|
{
|
||||||
if (this->type == TYPE_NUM_FLOAT)
|
if (this->type == TYPE_NUM_FLOAT)
|
||||||
return *(double *)this->p_mem;
|
return *(double *)this->p_mem;
|
||||||
@ -578,7 +998,7 @@ double Json_Value::asFloat(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 作为 Boolean 逻辑值获取
|
// 作为 Boolean 逻辑值获取
|
||||||
bool Json_Value::asBoolean(void)
|
bool Json_Value::asBoolean(void) const
|
||||||
{
|
{
|
||||||
if (this->type == TYPE_BOOLEAN)
|
if (this->type == TYPE_BOOLEAN)
|
||||||
return *(bool *)this->p_mem;
|
return *(bool *)this->p_mem;
|
||||||
@ -587,7 +1007,7 @@ bool Json_Value::asBoolean(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否为空
|
// 是否为空
|
||||||
bool Json_Value::isNull(void)
|
bool Json_Value::isNull(void) const
|
||||||
{
|
{
|
||||||
return (this->private_type == TYPE_NULL);
|
return (this->private_type == TYPE_NULL);
|
||||||
}
|
}
|
||||||
@ -614,7 +1034,7 @@ Json_Pair &Json_Pair::operator=(const Json_Pair &another)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 空判定
|
// 空判定
|
||||||
bool Json_Pair::isNull()
|
bool Json_Pair::isNull() const
|
||||||
{
|
{
|
||||||
return this->Null_Flag;
|
return this->Null_Flag;
|
||||||
}
|
}
|
||||||
@ -633,13 +1053,13 @@ Json_Arry &Json_Arry::operator=(const Json_Arry &another)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取元素大小
|
// 获取元素大小
|
||||||
size_t Json_Arry::size(void)
|
size_t Json_Arry::size(void) const
|
||||||
{
|
{
|
||||||
return this->private_element_list.size();
|
return this->private_element_list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数组索引重载
|
// 数组索引重载
|
||||||
Json_Value Json_Arry::operator[](size_t index)
|
Json_Value Json_Arry::operator[](size_t index) const
|
||||||
{
|
{
|
||||||
if (index < this->private_element_list.size())
|
if (index < this->private_element_list.size())
|
||||||
return this->private_element_list[index];
|
return this->private_element_list[index];
|
||||||
@ -648,7 +1068,7 @@ Json_Value Json_Arry::operator[](size_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否为空
|
// 是否为空
|
||||||
bool Json_Arry::isNull(void)
|
bool Json_Arry::isNull(void) const
|
||||||
{
|
{
|
||||||
return (this->private_element_list.size() == 0);
|
return (this->private_element_list.size() == 0);
|
||||||
}
|
}
|
||||||
@ -667,13 +1087,13 @@ Json_Object &Json_Object::operator=(const Json_Object &another)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取元素大小
|
// 获取元素大小
|
||||||
size_t Json_Object::size(void)
|
size_t Json_Object::size(void) const
|
||||||
{
|
{
|
||||||
return this->private_element_list.size();
|
return this->private_element_list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数组索引重载
|
// 数组索引重载
|
||||||
Json_Pair Json_Object::operator[](size_t index)
|
Json_Pair Json_Object::operator[](size_t index) const
|
||||||
{
|
{
|
||||||
if (index < this->private_element_list.size())
|
if (index < this->private_element_list.size())
|
||||||
return this->private_element_list[index];
|
return this->private_element_list[index];
|
||||||
@ -682,7 +1102,7 @@ Json_Pair Json_Object::operator[](size_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 由Key 查找值
|
// 由Key 查找值
|
||||||
Json_Value Json_Object::get(std::string key)
|
Json_Value Json_Object::get(std::string key) const
|
||||||
{
|
{
|
||||||
for (auto pair : this->private_element_list)
|
for (auto pair : this->private_element_list)
|
||||||
if (pair.key == key)
|
if (pair.key == key)
|
||||||
@ -692,7 +1112,7 @@ Json_Value Json_Object::get(std::string key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否为空
|
// 是否为空
|
||||||
bool Json_Object::isNull(void)
|
bool Json_Object::isNull(void) const
|
||||||
{
|
{
|
||||||
return (this->private_element_list.size() == 0);
|
return (this->private_element_list.size() == 0);
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user