#include "Json_Utilities.hpp" extern "C" { #include "stdio.h" #include "stdlib.h" } #include "functional" /** * @brief Json文件 格式检查 * @param path_to_file 文件路径串 * @return std::string 错误值 */ std::string JsonFile_FormatCheck(const char *path_to_file) { // 尝试打开文件 FILE *pFile = fopen(path_to_file, "rb"); if (pFile == nullptr) return "file \"" + std::string(path_to_file) + "\" open failed."; // 行列计数 size_t rol_count = 1; size_t column_count = 0; std::string err_str; // 跳过空白部分 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 ' ': column_count++; read_count++; break; case '\r': if (fgetc(pFile) == '\n') { read_count += 2; rol_count++; column_count = 0; } else { fseek(pFile, -2, SEEK_CUR); return read_count; } break; case '\n': read_count++; rol_count++; column_count = 0; break; default: fseek(pFile, -1, SEEK_CUR); return read_count; } } }; // 函数封装 std::function Check_Object; std::function Check_Value; std::function Check_Arry; std::function Check_Pair; // 函数定义 Check_Object = [&](void) -> std::string { Lambda_skip_blank(); char ch_get = fgetc(pFile); if (ch_get != '{') { if (ch_get == EOF) return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; else return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'."; } column_count++; while (true) { Lambda_skip_blank(); ch_get = fgetc(pFile); column_count++; switch (ch_get) { case '}': return std::string(); case '\"': fseek(pFile, -1, SEEK_CUR); column_count--; { std::string err_str = Check_Pair(); if (!err_str.empty()) return err_str; // 结束后读取段 size_t now_rol_count = rol_count; size_t now_column_count = column_count; Lambda_skip_blank(); char ch_get = fgetc(pFile); if ((ch_get != '}') && (ch_get != ',')) { if (ch_get == ']') return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing '}'."; else if (ch_get == EOF) return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; else return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing comma."; } fseek(pFile, -1, SEEK_CUR); } break; case ',': { size_t now_rol_count = rol_count; size_t now_column_count = column_count; Lambda_skip_blank(); if (fgetc(pFile) != '\"') return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Unexpected ','."; fseek(pFile, -1, SEEK_CUR); break; } case EOF: return std::string(path_to_file) + ':' + std::to_string(rol_count - 1) + ':' + std::to_string(column_count) + ": Unexpected EOF."; default: return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'."; } } }; Check_Value = [&](void) -> std::string { Lambda_skip_blank(); size_t begin_rol = rol_count; size_t begin_column = column_count; bool is_string = false; char ch_get = fgetc(pFile); // 判定第一个字符 switch (ch_get) { case EOF: return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; case '\"': is_string = true; break; case '{': fseek(pFile, -1, SEEK_CUR); return Check_Object(); case '[': fseek(pFile, -1, SEEK_CUR); return Check_Arry(); default: break; } // 判定为字符串 if (is_string) { column_count++; while (true) { ch_get = fgetc(pFile); column_count++; switch (ch_get) { case '\"': return std::string(); case '\\': // 转义符 ch_get = fgetc(pFile); if (ch_get != EOF) { column_count++; continue; } case EOF: return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; case '\n': return std::string(path_to_file) + ':' + std::to_string(begin_rol) + ':' + std::to_string(begin_column) + ": Unfinished string."; default: continue; } } } else fseek(pFile, -1, SEEK_CUR); // 识别有效数值 std::string segment_read; while (true) { bool segment_finish = false; ch_get = fgetc(pFile); column_count++; 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 ',': case '}': case ']': column_count--; fseek(pFile, -1, SEEK_CUR); case ' ': case '\n': segment_finish = true; break; default: segment_read += ch_get; } if (segment_finish) break; } if ((segment_read == "true") || (segment_read == "false") || (segment_read == "null")) return std::string(); // 数值识别 { char *end_ptr; strtod(segment_read.c_str(), &end_ptr); // 未被完全转化、出现先导0、先导+、尾缀小数点时非法 if ((size_t(end_ptr - segment_read.c_str()) < segment_read.size()) || ((segment_read.c_str()[0] == '0') && (segment_read.size() > 1)) || (segment_read.c_str()[0] == '+') || end_ptr[-1] == '.') return std::string(path_to_file) + ':' + std::to_string(begin_rol) + ':' + std::to_string(begin_column) + ": Invalid value \"" + segment_read + "\"."; } return std::string(); }; Check_Arry = [&](void) -> std::string { Lambda_skip_blank(); char ch_get = fgetc(pFile); if (ch_get != '[') { if (ch_get == EOF) return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; else return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'."; } column_count++; while (true) { Lambda_skip_blank(); ch_get = fgetc(pFile); column_count++; switch (ch_get) { case ']': return std::string(); case ',': { size_t now_rol_count = rol_count; size_t now_column_count = column_count; Lambda_skip_blank(); if (fgetc(pFile) == ']') return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Unexpected ','."; fseek(pFile, -1, SEEK_CUR); break; } case EOF: return std::string(path_to_file) + ':' + std::to_string(rol_count - 1) + ':' + std::to_string(column_count) + ": Unexpected EOF."; default: { column_count--; fseek(pFile, -1, SEEK_CUR); std::string err_str = Check_Value(); if (!err_str.empty()) return err_str; // 结束后读取段 size_t now_rol_count = rol_count; size_t now_column_count = column_count; Lambda_skip_blank(); char ch_get = fgetc(pFile); if ((ch_get != ',') && (ch_get != ']')) { if (ch_get == '}') return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing ']'."; else if (ch_get == EOF) return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; else return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing comma."; } fseek(pFile, -1, SEEK_CUR); } } } }; Check_Pair = [&](void) -> std::string { Lambda_skip_blank(); char ch_get = fgetc(pFile); if (ch_get != '\"') { if (ch_get == EOF) return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; else return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'."; } column_count++; // 遍历下一个引号 bool key_end = false; while (true) { ch_get = fgetc(pFile); column_count++; switch (ch_get) { case '\"': key_end = true; break; case '\n': rol_count++; column_count = 0; break; case EOF: return std::string(path_to_file) + ':' + std::to_string(rol_count - 1) + ':' + std::to_string(column_count) + ": Unexpected EOF."; } if (key_end) break; } // 寻找键值对标记 Lambda_skip_blank(); ch_get = fgetc(pFile); if (ch_get != ':') { if (ch_get == EOF) return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; else return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'. ':' is needed."; } column_count++; return Check_Value(); }; // 跳过空白检查第一个字符 Lambda_skip_blank(); switch (fgetc(pFile)) { case '[': fseek(pFile, -1, SEEK_CUR); err_str = Check_Arry(); break; case '{': fseek(pFile, -1, SEEK_CUR); err_str = Check_Object(); break; case EOF: err_str = std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF."; break; default: err_str = std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Syntax error. Must begin with '{' or '['."; } // 关闭文件 fclose(pFile); return err_str; } // std::string 构造 Json_Value::Json_Value(std::string str) : private_type(TYPE_STR), p_mem(malloc(sizeof(str))) { if (p_mem != nullptr) new (p_mem) std::string(str); else this->private_type = TYPE_NULL; } // Json_Arry 构造 Json_Value::Json_Value(Json_Arry arry) : private_type(TYPE_ARRY), p_mem(malloc(sizeof(arry))) { if (p_mem != nullptr) new (p_mem) Json_Arry(arry); else this->private_type = TYPE_NULL; } // Json_Object 构造 Json_Value::Json_Value(Json_Object object) : private_type(TYPE_OBJ), p_mem(malloc(sizeof(object))) { if (p_mem != nullptr) new (p_mem) Json_Object(object); else this->private_type = TYPE_NULL; } // 整数值 构造 Json_Value::Json_Value(int64_t num_integer) : private_type(TYPE_NUM_INTEGER), p_mem(malloc(sizeof(num_integer))) { if (p_mem != nullptr) *(decltype(num_integer) *)p_mem = num_integer; else this->private_type = TYPE_NULL; } // 浮点值 构造 Json_Value::Json_Value(double num_float) : private_type(TYPE_NUM_FLOAT), p_mem(malloc(sizeof(num_float))) { if (p_mem != nullptr) *(decltype(num_float) *)p_mem = num_float; else this->private_type = TYPE_NULL; } // Boolean 逻辑值构造 Json_Value::Json_Value(bool boolean) : private_type(TYPE_BOOLEAN), p_mem(malloc(sizeof(boolean))) { if (p_mem != nullptr) *(decltype(boolean) *)p_mem = boolean; else this->private_type = TYPE_NULL; } // 浅拷贝构造 Json_Value::Json_Value(const Json_Value &temp) : private_type(TYPE_NULL), p_mem(nullptr) { // 执行深拷贝 *this = temp; } // 深拷贝 Json_Value &Json_Value::operator=(const Json_Value &another) { if (this != &another) { // 先析构释放内存 this->~Json_Value(); // 重新赋值 this->private_type = another.type; switch (another.type) { case TYPE_STR: this->p_mem = malloc(sizeof(std::string)); if (this->p_mem != nullptr) new (this->p_mem) std::string(*((std::string *)another.p_mem)); break; case TYPE_ARRY: this->p_mem = malloc(sizeof(Json_Arry)); if (this->p_mem != nullptr) new (this->p_mem) Json_Arry(*((Json_Arry *)another.p_mem)); break; case TYPE_OBJ: this->p_mem = malloc(sizeof(Json_Object)); if (this->p_mem != nullptr) new (this->p_mem) Json_Object(*((Json_Object *)another.p_mem)); break; case TYPE_NUM_INTEGER: this->p_mem = malloc(sizeof(int64_t)); if (this->p_mem != nullptr) *((int64_t *)this->p_mem) = *((int64_t *)another.p_mem); break; case TYPE_NUM_FLOAT: this->p_mem = malloc(sizeof(double)); if (this->p_mem != nullptr) *((double *)this->p_mem) = *((double *)another.p_mem); break; case TYPE_BOOLEAN: this->p_mem = malloc(sizeof(bool)); if (this->p_mem != nullptr) *((bool *)this->p_mem) = *((bool *)another.p_mem); break; default: this->p_mem = nullptr; } } return *this; } // 析构 Json_Value::~Json_Value() { this->private_type = TYPE_NULL; if (this->p_mem != nullptr) { // 对象析构 switch (this->type) { case TYPE_STR: ((std::string *)p_mem)->~basic_string(); break; case TYPE_ARRY: ((Json_Arry *)p_mem)->~Json_Arry(); break; case TYPE_OBJ: ((Json_Object *)p_mem)->~Json_Object(); break; default: break; }; // 释放内存 free(p_mem); } } // 作为直接值获取 std::string Json_Value::asString(void) { if (this->type == TYPE_STR) return *(std::string *)this->p_mem; else return std::string(""); } // 作为 Json_Arry 获取 Json_Arry Json_Value::asArry(void) { if (this->type == TYPE_ARRY) return *(Json_Arry *)this->p_mem; else return Json_Arry(); } // 作为 Json_Object 获取 Json_Object Json_Value::asObject(void) { if (this->type == TYPE_OBJ) return *(Json_Object *)this->p_mem; else return Json_Object(); } // 作为 int64 获取 int64_t Json_Value::asInteger(void) { if (this->type == TYPE_NUM_INTEGER) return *(int64_t *)this->p_mem; else return 0; } // 作为 double 获取 double Json_Value::asFloat(void) { if (this->type == TYPE_NUM_FLOAT) return *(double *)this->p_mem; else return 0; } // 作为 Boolean 逻辑值获取 bool Json_Value::asBoolean(void) { if (this->type == TYPE_BOOLEAN) return *(bool *)this->p_mem; else return 0; } // 是否为空 bool Json_Value::isNull(void) { return (this->private_type == TYPE_NULL); } // ================================================================================================= // 浅拷贝构造 Json_Pair::Json_Pair(const Json_Pair &temp) { *this = temp; } // 深拷贝 Json_Pair &Json_Pair::operator=(const Json_Pair &another) { if (this != &another) { this->Null_Flag = another.Null_Flag; this->private_key_str = another.private_key_str; this->private_value = another.private_value; } return *this; } // 空判定 bool Json_Pair::isNull() { return this->Null_Flag; } // ================================================================================================= // 深拷贝 Json_Arry &Json_Arry::operator=(const Json_Arry &another) { if (this != &another) { this->private_element_list = another.private_element_list; } return *this; } // 获取元素大小 size_t Json_Arry::size(void) { return this->private_element_list.size(); } // 数组索引重载 Json_Value Json_Arry::operator[](size_t index) { if (index < this->private_element_list.size()) return this->private_element_list[index]; else return Json_Value(); } // 是否为空 bool Json_Arry::isNull(void) { return (this->private_element_list.size() == 0); } // ================================================================================================= // 深拷贝 Json_Object &Json_Object::operator=(const Json_Object &another) { if (this != &another) { this->private_element_list = another.private_element_list; } return *this; } // 获取元素大小 size_t Json_Object::size(void) { return this->private_element_list.size(); } // 数组索引重载 Json_Pair Json_Object::operator[](size_t index) { if (index < this->private_element_list.size()) return this->private_element_list[index]; else return Json_Pair(); } // 由Key 查找值 Json_Value Json_Object::get(std::string key) { for (auto pair : this->private_element_list) if (pair.key == key) return pair.value; return Json_Value(); } // 是否为空 bool Json_Object::isNull(void) { return (this->private_element_list.size() == 0); }