first
This commit is contained in:
@@ -0,0 +1 @@
|
||||
cmake-build-debug
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
Generated
+2
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
Generated
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PublishConfigData" remoteFilesAllowedToDisappearOnAutoupload="false">
|
||||
<serverData>
|
||||
<paths name="WSL (66c11979-4867-4a17-83c1-b6e47df43d39)">
|
||||
<serverdata>
|
||||
<mappings>
|
||||
<mapping local="$PROJECT_DIR$" web="/" />
|
||||
</mappings>
|
||||
</serverdata>
|
||||
</paths>
|
||||
<paths name="WSL (a4a5868f-4653-4e3e-a1e4-92d5c2007084)">
|
||||
<serverdata>
|
||||
<mappings>
|
||||
<mapping local="$PROJECT_DIR$" web="/" />
|
||||
</mappings>
|
||||
</serverdata>
|
||||
</paths>
|
||||
<paths name="WSL (ab0fb59d-77f8-4703-9979-f3a81cca500e)">
|
||||
<serverdata>
|
||||
<mappings>
|
||||
<mapping local="$PROJECT_DIR$" web="/" />
|
||||
</mappings>
|
||||
</serverdata>
|
||||
</paths>
|
||||
</serverData>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+4
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/SimpleJson.iml" filepath="$PROJECT_DIR$/.idea/SimpleJson.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,6 @@
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "Hello, World!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
+598
@@ -0,0 +1,598 @@
|
||||
//
|
||||
// Created by jun on 2023/12/29.
|
||||
//
|
||||
|
||||
#include "json.h"
|
||||
|
||||
namespace simpleJson {
|
||||
|
||||
/*************************************************class JsonNode*************************************************/
|
||||
JsonNode::JsonNode() : key(""), type(JSON_TYPE_NULL), string_value("") {
|
||||
child_head = nullptr;
|
||||
next = nullptr;
|
||||
prev = nullptr;
|
||||
children_size = 0;
|
||||
}
|
||||
|
||||
JsonNode::JsonNode(JsonValueTypeEnum type, const std::string &key = "") : key(key), type(type), string_value("") {
|
||||
child_head = nullptr;
|
||||
next = nullptr;
|
||||
prev = nullptr;
|
||||
children_size = 0;
|
||||
}
|
||||
|
||||
double JsonNode::get_number_value() const {
|
||||
if (type != JSON_TYPE_INT && type != JSON_TYPE_DOUBLE) {
|
||||
throw std::runtime_error("JsonNode::get_number_value() error: type is not number");
|
||||
} else if (type == JSON_TYPE_INT) {
|
||||
return (double) (value.int_value);
|
||||
} else {
|
||||
return value.double_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonNode::get_bool_value() const {
|
||||
if (type != JSON_TYPE_BOOL) {
|
||||
throw std::runtime_error("JsonNode::get_bool_value() error: type is not bool");
|
||||
} else {
|
||||
return value.bool_value;
|
||||
}
|
||||
}
|
||||
|
||||
std::string JsonNode::get_string_value() const {
|
||||
if (type != JSON_TYPE_STRING) {
|
||||
throw std::runtime_error("JsonNode::get_string_value() error: type is not string");
|
||||
} else {
|
||||
return string_value;
|
||||
}
|
||||
}
|
||||
|
||||
JsonNode &JsonNode::get_object_value() {
|
||||
if (type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::get_object_value() error: type is not object");
|
||||
} else {
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
int JsonNode::get_children_size() const {
|
||||
if (type != JSON_TYPE_LIST && type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::get_children_size() error: type is not list or object");
|
||||
} else {
|
||||
return children_size;
|
||||
}
|
||||
}
|
||||
|
||||
void JsonNode::set_value(double _value) {
|
||||
if (type != JSON_TYPE_INT && type != JSON_TYPE_DOUBLE && type != JSON_TYPE_BOOL) {
|
||||
throw std::runtime_error("JsonNode::set_value(double) error: type is not number");
|
||||
} else {
|
||||
value.double_value = 0;
|
||||
if (type == JSON_TYPE_INT) {
|
||||
value.int_value = (int) _value;
|
||||
} else if (type == JSON_TYPE_DOUBLE) {
|
||||
value.double_value = _value;
|
||||
} else {
|
||||
value.bool_value = _value > 0;
|
||||
}
|
||||
}
|
||||
children_size = 0;
|
||||
}
|
||||
|
||||
void JsonNode::set_value(const std::string &_value) {
|
||||
if (type != JSON_TYPE_STRING) {
|
||||
throw std::runtime_error("JsonNode::set_value(string) error: type is not string");
|
||||
} else {
|
||||
string_value = _value;
|
||||
}
|
||||
children_size = 0;
|
||||
}
|
||||
|
||||
void JsonNode::set_key(const std::string &_key) {
|
||||
key = _key;
|
||||
}
|
||||
|
||||
std::string JsonNode::get_key() const {
|
||||
return key;
|
||||
}
|
||||
|
||||
void JsonNode::push_back(simpleJson::JsonNodePtr node) {
|
||||
if (type != JSON_TYPE_LIST && type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::push_back() error: type is not list or object");
|
||||
} else {
|
||||
if (child_head == nullptr) {
|
||||
child_head = node;
|
||||
node->prev = nullptr;
|
||||
node->next = nullptr;
|
||||
} else {
|
||||
JsonNodePtr tail = child_head;
|
||||
while (tail->next != nullptr) {
|
||||
tail = tail->next;
|
||||
}
|
||||
tail->next = node;
|
||||
node->prev = tail;
|
||||
node->next = nullptr;
|
||||
}
|
||||
children_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void JsonNode::push_front(simpleJson::JsonNodePtr node) {
|
||||
if (type != JSON_TYPE_LIST && type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::push_front() error: type is not list or object");
|
||||
} else {
|
||||
if (child_head == nullptr) {
|
||||
child_head = node;
|
||||
node->prev = nullptr;
|
||||
node->next = nullptr;
|
||||
} else {
|
||||
child_head->prev = node;
|
||||
node->next = child_head;
|
||||
node->prev = nullptr;
|
||||
child_head = node;
|
||||
}
|
||||
children_size++;
|
||||
}
|
||||
}
|
||||
|
||||
void JsonNode::clear() {
|
||||
if (type != JSON_TYPE_LIST && type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::clear() error: type is not list or object");
|
||||
} else {
|
||||
child_head = nullptr;
|
||||
children_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonNode::set_list(int _size) {
|
||||
if (type == JSON_TYPE_NULL) {
|
||||
setValueType(JSON_TYPE_LIST);
|
||||
}
|
||||
if (type != JSON_TYPE_LIST) {
|
||||
throw std::runtime_error("JsonNode::set_list() error: type is not list");
|
||||
}
|
||||
try {
|
||||
clear();
|
||||
for (int i = 0; i < _size; i++) {
|
||||
push_back(JsonNodePtr(new JsonNode(JSON_TYPE_NULL)));
|
||||
}
|
||||
children_size = _size;
|
||||
} catch (std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
JsonNode &JsonNode::list_get(int index) {
|
||||
if (type != JSON_TYPE_LIST) {
|
||||
throw std::runtime_error("JsonNode::list_get() error: type is not list");
|
||||
} else if (index < 0 || index >= children_size) {
|
||||
throw std::runtime_error("JsonNode::list_get() error: index out of range");
|
||||
} else {
|
||||
JsonNodePtr node = child_head;
|
||||
for (int i = 0; i < index; i++) {
|
||||
node = node->next;
|
||||
}
|
||||
return *node;
|
||||
}
|
||||
}
|
||||
|
||||
void JsonNode::list_insert(int index, simpleJson::JsonNodePtr node) {
|
||||
if (type != JSON_TYPE_LIST) {
|
||||
throw std::runtime_error("JsonNode::list_insert() error: type is not list");
|
||||
} else if (index < 0 || index > children_size) {
|
||||
throw std::runtime_error("JsonNode::list_insert() error: index out of range");
|
||||
} else {
|
||||
if (index == 0) {
|
||||
push_front(node);
|
||||
} else if (index == children_size) {
|
||||
push_back(node);
|
||||
} else {
|
||||
JsonNodePtr p = child_head;
|
||||
for (int i = 0; i < index; i++) {
|
||||
p = p->next;
|
||||
}
|
||||
node->prev = p->prev;
|
||||
node->next = p;
|
||||
p->prev->next = node;
|
||||
p->prev = node;
|
||||
children_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsonNode::list_erase(int index) {
|
||||
if (type != JSON_TYPE_LIST) {
|
||||
throw std::runtime_error("JsonNode::list_erase() error: type is not list");
|
||||
} else if (index < 0 || index >= children_size) {
|
||||
throw std::runtime_error("JsonNode::list_erase() error: index out of range");
|
||||
} else {
|
||||
if (index == 0) {
|
||||
child_head = child_head->next;
|
||||
child_head->prev = nullptr;
|
||||
} else if (index == children_size - 1) {
|
||||
JsonNodePtr p = child_head;
|
||||
for (int i = 0; i < index - 1; i++) {
|
||||
p = p->next;
|
||||
}
|
||||
p->next = nullptr;
|
||||
} else {
|
||||
JsonNodePtr p = child_head;
|
||||
for (int i = 0; i < index; i++) {
|
||||
p = p->next;
|
||||
}
|
||||
p->prev->next = p->next;
|
||||
p->next->prev = p->prev;
|
||||
}
|
||||
children_size--;
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonNode::obj_has_item(const std::string &key) {
|
||||
if (type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::obj_has_item() error: type is not object");
|
||||
} else {
|
||||
JsonNodePtr p = child_head;
|
||||
while (p != nullptr) {
|
||||
if (p->key == key) {
|
||||
return true;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JsonNode& JsonNode::obj_get(const std::string &key) {
|
||||
if (type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::obj_get() error: type is not object");
|
||||
} else {
|
||||
JsonNodePtr p = child_head;
|
||||
while (p != nullptr) {
|
||||
if (p->key == key) {
|
||||
return *p;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
throw std::runtime_error("JsonNode::obj_get() error: key \""+key+"\" not found");
|
||||
}
|
||||
}
|
||||
|
||||
void JsonNode::obj_set(simpleJson::JsonNodePtr node) {
|
||||
if (type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::obj_set() error: type is not object");
|
||||
} else {
|
||||
if (obj_has_item(node->key)) {
|
||||
obj_get(node->key) = *node;
|
||||
} else {
|
||||
push_back(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JsonNode::to_json_string(std::string &_dst_str, bool _print_key, int _tab_dep, bool _one_line) const {
|
||||
for (int i = 0; i < _tab_dep; i++) {
|
||||
_dst_str += "\t";
|
||||
}
|
||||
if (key.size() != 0 && _print_key) {
|
||||
_dst_str += "\"" + key + "\":";
|
||||
}
|
||||
int dep = _one_line ? 0 : _tab_dep+1;
|
||||
switch (type) {
|
||||
case JSON_TYPE_INT: {
|
||||
_dst_str += std::to_string(value.int_value);
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_DOUBLE: {
|
||||
_dst_str += std::to_string(value.double_value);
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_BOOL: {
|
||||
_dst_str += value.bool_value ? "true" : "false";
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_STRING: {
|
||||
_dst_str += "\"" + string_value + "\"";
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_LIST: {
|
||||
_dst_str += "[";
|
||||
if (!_one_line) {
|
||||
_dst_str += "\n";
|
||||
}
|
||||
JsonNodePtr p = child_head;
|
||||
while (p != nullptr) {
|
||||
p->to_json_string(_dst_str, false, dep, _one_line);
|
||||
if (p->next != nullptr) {
|
||||
_dst_str += ",";
|
||||
}
|
||||
if (!_one_line) {
|
||||
_dst_str += "\n";
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
for (int i = 0; i < _tab_dep; i++) {
|
||||
_dst_str += "\t";
|
||||
}
|
||||
_dst_str += "]";
|
||||
break;
|
||||
}
|
||||
case JSON_TYPE_OBJECT: {
|
||||
_dst_str += "{";
|
||||
if (!_one_line) {
|
||||
_dst_str += "\n";
|
||||
}
|
||||
JsonNodePtr p = child_head;
|
||||
while (p != nullptr) {
|
||||
p->to_json_string(_dst_str, true, dep, _one_line);
|
||||
if (p->next != nullptr) {
|
||||
_dst_str += ",";
|
||||
}
|
||||
if (!_one_line) {
|
||||
_dst_str += "\n";
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
for (int i = 0; i < _tab_dep; i++) {
|
||||
_dst_str += "\t";
|
||||
}
|
||||
_dst_str += "}";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
JsonNode& JsonNode::operator[](const std::string & key) {
|
||||
if (type == JSON_TYPE_NULL) {
|
||||
setValueType(JSON_TYPE_OBJECT);
|
||||
}
|
||||
if (type != JSON_TYPE_OBJECT) {
|
||||
throw std::runtime_error("JsonNode::operator[]() error: type is not object");
|
||||
} else {
|
||||
if (obj_has_item(key)) {
|
||||
return obj_get(key);
|
||||
} else {
|
||||
JsonNodePtr node = JsonNodePtr(new JsonNode(JSON_TYPE_NULL, key));
|
||||
obj_set(node);
|
||||
return *node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JsonNode& JsonNode::operator[](int index) {
|
||||
if (type == JSON_TYPE_NULL) {
|
||||
setValueType(JSON_TYPE_LIST);
|
||||
}
|
||||
if (type != JSON_TYPE_LIST) {
|
||||
throw std::runtime_error("JsonNode::operator[]() error: type is not list");
|
||||
} else {
|
||||
if (index < 0 || index >= children_size) {
|
||||
throw std::runtime_error("JsonNode::operator[]() error: index out of range");
|
||||
} else {
|
||||
return list_get(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double JsonNode::operator=(double _value) {
|
||||
if (type == JSON_TYPE_NULL) {
|
||||
setValueType(JSON_TYPE_DOUBLE);
|
||||
}
|
||||
if (type == JSON_TYPE_DOUBLE) {
|
||||
value.double_value = _value;
|
||||
return _value;
|
||||
} else if (type == JSON_TYPE_INT) {
|
||||
value.int_value = static_cast<int>(_value);
|
||||
return _value;
|
||||
} else if (type == JSON_TYPE_BOOL) {
|
||||
value.bool_value = _value > 0;
|
||||
return _value;
|
||||
} else {
|
||||
throw std::runtime_error("JsonNode::operator=(double) error: type is not number");
|
||||
}
|
||||
}
|
||||
|
||||
int JsonNode::as_int() const {
|
||||
switch (type) {
|
||||
case JSON_TYPE_INT: {
|
||||
return value.int_value;
|
||||
}
|
||||
case JSON_TYPE_DOUBLE: {
|
||||
return static_cast<int>(value.double_value);
|
||||
}
|
||||
case JSON_TYPE_BOOL: {
|
||||
return value.bool_value ? 1 : 0;
|
||||
}
|
||||
case JSON_TYPE_NULL: {
|
||||
return 0;
|
||||
}
|
||||
default: {
|
||||
throw std::runtime_error("JsonNode::as_int() error: type is not number");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double JsonNode::as_double() const {
|
||||
switch (type) {
|
||||
case JSON_TYPE_INT: {
|
||||
return static_cast<double>(value.int_value);
|
||||
}
|
||||
case JSON_TYPE_DOUBLE: {
|
||||
return value.double_value;
|
||||
}
|
||||
case JSON_TYPE_BOOL: {
|
||||
return value.bool_value ? 1.0 : 0.0;
|
||||
}
|
||||
case JSON_TYPE_NULL: {
|
||||
return 0.0;
|
||||
}
|
||||
default: {
|
||||
throw std::runtime_error("JsonNode::as_double() error: type is not number");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string JsonNode::as_string() const {
|
||||
switch (type) {
|
||||
case JSON_TYPE_STRING: {
|
||||
return string_value;
|
||||
}
|
||||
case JSON_TYPE_INT: {
|
||||
return std::to_string(value.int_value);
|
||||
}
|
||||
case JSON_TYPE_DOUBLE: {
|
||||
return std::to_string(value.double_value);
|
||||
}
|
||||
case JSON_TYPE_BOOL: {
|
||||
return value.bool_value ? "true" : "false";
|
||||
}
|
||||
case JSON_TYPE_NULL: {
|
||||
return "NULL";
|
||||
}
|
||||
default: {
|
||||
throw std::runtime_error("JsonNode::as_string() error: type is not string");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<JsonNodePtr> JsonNode::as_vector() {
|
||||
std::vector<JsonNodePtr> vec;
|
||||
JsonNodePtr p = child_head;
|
||||
while (p != nullptr) {
|
||||
vec.push_back(p);
|
||||
p = p->next;
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
void JsonNode::setValueType(simpleJson::JsonValueTypeEnum _type) {
|
||||
type = _type;
|
||||
}
|
||||
/*****************************************************************************************************************/
|
||||
|
||||
/***********************************************JsonReader*******************************************************/
|
||||
JsonReader::JsonReader() {
|
||||
src_str = "";
|
||||
src_str_len = 0;
|
||||
curr_ptr = -1;
|
||||
curr_line = 0;
|
||||
curr_col = 0;
|
||||
|
||||
eof = 1;
|
||||
}
|
||||
|
||||
JsonReader::JsonReader(const std::string &_src_str) {
|
||||
src_str = _src_str;
|
||||
src_str_len = src_str.size();
|
||||
if (src_str_len <= 0) {
|
||||
curr_ptr = -1;
|
||||
curr_line = 0;
|
||||
curr_col = 0;
|
||||
eof = 1;
|
||||
} else {
|
||||
curr_ptr = 0;
|
||||
curr_line = 1;
|
||||
curr_col = 1;
|
||||
eof = 0;
|
||||
}
|
||||
}
|
||||
|
||||
JsonReader::JsonReader(std::ifstream & _input_file_stream) {
|
||||
if (!_input_file_stream) {
|
||||
throw std::runtime_error("JsonReader::JsonReader() error: input file stream is not valid");
|
||||
}
|
||||
std::string line = "";
|
||||
while (std::getline(_input_file_stream, line)) {
|
||||
src_str += line + "\n";
|
||||
}
|
||||
src_str_len = src_str.size();
|
||||
if (src_str_len <= 0) {
|
||||
curr_ptr = -1;
|
||||
curr_line = 0;
|
||||
curr_col = 0;
|
||||
eof = 1;
|
||||
} else {
|
||||
curr_ptr = 0;
|
||||
curr_line = 1;
|
||||
curr_col = 1;
|
||||
eof = 0;
|
||||
}
|
||||
}
|
||||
|
||||
char JsonReader::curr_char() const {
|
||||
if (curr_ptr < 0 || curr_ptr >= src_str_len) {
|
||||
throw std::runtime_error("JsonReader::curr_char() error: current pointer out of range");
|
||||
} else {
|
||||
return src_str[curr_ptr];
|
||||
}
|
||||
}
|
||||
|
||||
char JsonReader::get_char() {
|
||||
if (eof) {
|
||||
throw std::runtime_error("JsonReader::get_char() error: end of file");
|
||||
} else {
|
||||
curr_ptr++;
|
||||
if (curr_ptr >= src_str_len) {
|
||||
eof = 1;
|
||||
return '\0';
|
||||
} else {
|
||||
auto ch = src_str[curr_ptr++];
|
||||
if (src_str[curr_ptr] == '\n') {
|
||||
curr_line++;
|
||||
curr_col = 1;
|
||||
} else if (src_str[curr_ptr] == '\t') {
|
||||
curr_col += 4;
|
||||
} else if (src_str[curr_ptr] == '\r') {
|
||||
curr_col = 0;
|
||||
} else {
|
||||
curr_col++;
|
||||
}
|
||||
|
||||
if (curr_ptr >= src_str_len) {
|
||||
eof = 1;
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string JsonReader::str_ahead(int _len) const {
|
||||
return src_str.substr(curr_ptr, std::min(_len, src_str_len - curr_ptr));
|
||||
}
|
||||
|
||||
std::string JsonReader::get_str(int _len) {
|
||||
auto str = str_ahead(_len);
|
||||
if (curr_ptr >= src_str_len) {
|
||||
throw std::runtime_error("JsonReader::get_str() error: end of file");
|
||||
}
|
||||
curr_ptr += _len;
|
||||
return str;
|
||||
}
|
||||
|
||||
int JsonReader::get_curr_line() const {
|
||||
return curr_line;
|
||||
}
|
||||
|
||||
int JsonReader::get_curr_col() const {
|
||||
return curr_col;
|
||||
}
|
||||
|
||||
void JsonReader::skip_space() {
|
||||
while (curr_ptr < src_str_len && (src_str[curr_ptr] == ' ' || src_str[curr_ptr] == '\t' || src_str[curr_ptr] == '\n' || src_str[curr_ptr] == '\r')) {
|
||||
get_char();
|
||||
}
|
||||
if (curr_ptr >= src_str_len) {
|
||||
eof = 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonReader::is_eof() const {
|
||||
return eof;
|
||||
}
|
||||
/****************************************************************************************************************/
|
||||
|
||||
}
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// Created by jun on 2023/12/29.
|
||||
//
|
||||
|
||||
#ifndef SIMPLEJSON_JSON_H
|
||||
#define SIMPLEJSON_JSON_H
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
namespace simpleJson {
|
||||
|
||||
class JsonNode;
|
||||
|
||||
class JsonReader;
|
||||
|
||||
class JsonParser;
|
||||
|
||||
typedef std::shared_ptr<JsonNode> JsonNodePtr;
|
||||
|
||||
enum JsonValueTypeEnum {
|
||||
JSON_TYPE_NULL = 0,
|
||||
JSON_TYPE_INT,
|
||||
JSON_TYPE_DOUBLE,
|
||||
JSON_TYPE_BOOL,
|
||||
JSON_TYPE_STRING,
|
||||
JSON_TYPE_LIST,
|
||||
JSON_TYPE_OBJECT
|
||||
};
|
||||
union JsonValue {
|
||||
int int_value;
|
||||
double double_value;
|
||||
bool bool_value;
|
||||
// std::string string_value;
|
||||
// JsonNodePtr list_value;
|
||||
// JsonNodePtr object_value;
|
||||
};
|
||||
|
||||
class JsonNode : public std::enable_shared_from_this<JsonNode> {
|
||||
private:
|
||||
JsonNodePtr child_head;
|
||||
JsonNodePtr next;
|
||||
JsonNodePtr prev;
|
||||
|
||||
private:
|
||||
std::string key;
|
||||
JsonValueTypeEnum type;
|
||||
JsonValue value;
|
||||
std::string string_value;
|
||||
|
||||
int children_size;
|
||||
public:
|
||||
JsonNode();
|
||||
|
||||
JsonNode(JsonValueTypeEnum type, const std::string &key);
|
||||
|
||||
~JsonNode(){};
|
||||
|
||||
public:
|
||||
JsonValueTypeEnum get_value_type() const;
|
||||
|
||||
double get_number_value() const;
|
||||
|
||||
bool get_bool_value() const;
|
||||
|
||||
std::string get_string_value() const;
|
||||
|
||||
JsonNode &get_object_value();
|
||||
|
||||
int get_children_size() const;
|
||||
|
||||
void set_value(double _value);
|
||||
|
||||
void set_value(const std::string &_value);
|
||||
|
||||
void set_key(const std::string &_key);
|
||||
|
||||
std::string get_key() const;
|
||||
|
||||
public:
|
||||
void push_back(JsonNodePtr node);
|
||||
|
||||
void push_front(JsonNodePtr node);
|
||||
|
||||
void clear();
|
||||
|
||||
public:
|
||||
bool set_list(int _size = 0);
|
||||
|
||||
JsonNode &list_get(int index);
|
||||
|
||||
void list_insert(int index, JsonNodePtr node);
|
||||
|
||||
void list_erase(int index);
|
||||
|
||||
bool obj_has_item(const std::string &key);
|
||||
|
||||
JsonNode &obj_get(const std::string &key);
|
||||
|
||||
void obj_set(JsonNodePtr node);
|
||||
|
||||
public:
|
||||
void to_json_string(std::string &_dst_str, bool _print_key = 0, int _tab_dep = 0, bool _one_line = 0) const;
|
||||
|
||||
JsonNode &operator[](const std::string &key);
|
||||
|
||||
JsonNode &operator[](int index);
|
||||
|
||||
double operator=(double _value);
|
||||
|
||||
std::string operator=(const std::string &_value);
|
||||
|
||||
int as_int() const;
|
||||
|
||||
double as_double() const;
|
||||
|
||||
bool as_bool() const;
|
||||
|
||||
std::string as_string() const;
|
||||
|
||||
std::vector<JsonNodePtr> as_vector();
|
||||
|
||||
private:
|
||||
void setValueType(JsonValueTypeEnum _type);
|
||||
|
||||
friend class JsonParser;
|
||||
};
|
||||
|
||||
class JsonReader : public std::enable_shared_from_this<JsonReader> {
|
||||
private:
|
||||
std::string src_str;
|
||||
|
||||
int src_str_len;
|
||||
int curr_ptr;
|
||||
int curr_line, curr_col;
|
||||
|
||||
int eof;
|
||||
public:
|
||||
JsonReader();
|
||||
JsonReader(const std::string &_src_str);
|
||||
JsonReader(std::ifstream &_input_file_stream);
|
||||
~JsonReader(){};
|
||||
|
||||
public:
|
||||
char curr_char() const;
|
||||
char get_char();
|
||||
|
||||
std::string str_ahead(int _len) const;
|
||||
std::string get_str(int _len);
|
||||
int get_curr_line() const;
|
||||
int get_curr_col() const;
|
||||
|
||||
void skip_space();
|
||||
|
||||
bool is_eof() const;
|
||||
};
|
||||
|
||||
class JsonParser {
|
||||
private:
|
||||
JsonNodePtr root;
|
||||
bool is_parse_success;
|
||||
|
||||
public:
|
||||
JsonParser();
|
||||
JsonParser(const std::string &_src_str);
|
||||
JsonParser(std::ifstream &_input_file_stream);
|
||||
~JsonParser(){};
|
||||
|
||||
public:
|
||||
JsonNode & get_root();
|
||||
bool is_success() const;
|
||||
bool fail() const;
|
||||
|
||||
private:
|
||||
void parseValue(JsonReader &reader, JsonNodePtr &node);
|
||||
void parseObject(JsonReader &reader, JsonNodePtr &node);
|
||||
void parseList(JsonReader &reader, JsonNodePtr &node);
|
||||
void parseString(JsonReader &reader, JsonNodePtr &node);
|
||||
void parseNumber(JsonReader &reader, JsonNodePtr &node);
|
||||
|
||||
public:
|
||||
void to_json_string(std::string &_dst_str, bool _one_line = 0) const;
|
||||
|
||||
bool save_to_file(const std::string &_file_path, bool _one_line = 0) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //SIMPLEJSON_JSON_H
|
||||
Reference in New Issue
Block a user