#include #include #include #include class JsonValue { public: typedef enum ValueType { Integer, Float, String, Boolean, Object, Array, } ValueType; public: JsonValue() = default; virtual ~JsonValue() = default; virtual ValueType type() = 0; }; template class PrimeValue : public JsonValue { public: PrimeValue(const T &data) : data_(data) {} ValueType type() override { if (std::is_same_v) { return ValueType::Integer; } else if (std::is_same_v) { return ValueType::Boolean; } else if (std::is_same_v || std::is_same_v) { return ValueType::Float; } else if (std::is_same_v) { return ValueType::String; } else { static_assert("PrimeValue type instance failed!"); } } public: void set(const T &value) { data_ = value; } const T &get() const { return data_; } private: T data_; }; class ArrayValue : public JsonValue { public: ArrayValue() = default; ValueType type() override { return ValueType::Array; } void AddValue(const std::shared_ptr &value) { data_.push_back(value); } private: std::deque> data_; }; class NamedValue { public: NamedValue() = default; explicit NamedValue(const std::string &name) : name_(name) { std::cout << name << '\n'; } public: void setValue(const std::shared_ptr &value) { data_ = value; } template void setValue(const T &value) { data_ = std::make_shared>(value); } const std::string &getName() const { return name_; } template const T &getValue() { return (dynamic_pointer_cast>(data_))->get(); } private: std::string name_; std::shared_ptr data_; }; class ObjectValue : public JsonValue { public: ObjectValue() = default; explicit ObjectValue(const std::string &str) {} ValueType type() override { return ValueType::Object; } void AddValue(const std::shared_ptr &value) { data_.push_back(value); } bool Contains(const std::string &key) { return data_.end() != std::find_if(data_.begin(), data_.end(), [&key](const auto &item) { return key == item->getName(); }); } template T getValue(const std::string &key) const { auto it = std::find_if(data_.begin(), data_.end(), [&key](const auto &item) { return key == item->getName(); }); if (data_.end() != it) { return (*it)->template getValue(); } return T{}; } private: std::deque> data_; }; std::shared_ptr Parse(const std::string &json_string) { int pair_index{-1}; int colon_index{-1}; std::vector memory; std::shared_ptr root_node{nullptr}; std::vector> parents; std::shared_ptr parent_node{nullptr}; std::shared_ptr next_value{nullptr}; for (int i = 0; i < json_string.size(); ++i) { char c = json_string[i]; switch (c) { case '"': if (pair_index >= 0 && pair_index < memory.size()) { std::string str{}; std::cout << "i: " << i << ", pair_index: " << pair_index << ", memory.size(): " << memory.size() << '\n'; for (int j = pair_index + 1; j < memory.size(); ++j) { str += memory[j]; } printf("%s, size: %d\n", str.c_str(), str.size()); memory.erase(memory.begin() + pair_index, memory.end()); if (colon_index >= 0 && next_value) { next_value->setValue(str); std::shared_ptr parent_object = dynamic_pointer_cast(parent_node); parent_object->AddValue(next_value); next_value = nullptr; } else { if (colon_index < 0 && parent_node->type() == JsonValue::ValueType::Object) { next_value = std::make_shared(str); } else if (colon_index < 0 && parent_node->type() == JsonValue::ValueType::Array) { std::shared_ptr parent_array = dynamic_pointer_cast(parent_node); parent_array->AddValue(std::make_shared>(str)); } } pair_index = -1; } else { pair_index = memory.size(); memory.push_back(c); } break; case ',': { bool point_existed{false}; bool all_digit{true}; std::string tmp; for (int j = 0; j < memory.size(); ++j) { tmp += memory[j]; if (memory[j] == '.') { point_existed = true; } else if (all_digit && !std::isdigit(memory[j])) { all_digit = false; } } memory.clear(); printf("%s\n", tmp.c_str()); if (!tmp.empty()) { if (all_digit) { if (point_existed) { auto double_value = std::stod(tmp); if (next_value) { next_value->setValue(double_value); std::shared_ptr parent_object = dynamic_pointer_cast( parent_node); parent_object->AddValue(next_value); next_value.reset(); } else { std::shared_ptr parent_array = dynamic_pointer_cast( parent_node); parent_array->AddValue(std::make_shared>(double_value)); } } else { auto int_value = std::stoi(tmp); if (next_value) { next_value->setValue(int_value); std::shared_ptr parent_object = dynamic_pointer_cast( parent_node); parent_object->AddValue(next_value); next_value.reset(); } else { std::shared_ptr parent_array = dynamic_pointer_cast( parent_node); parent_array->AddValue(std::make_shared>(int_value)); } } } else { bool bool_value; if (tmp == "true") { bool_value = true; } else if (tmp == "false") { bool_value = false; } else { static_assert("Parse value error!"); } if (next_value) { next_value->setValue(bool_value); std::shared_ptr parent_object = dynamic_pointer_cast(parent_node); parent_object->AddValue(next_value); next_value.reset(); } else { std::shared_ptr parent_array = dynamic_pointer_cast(parent_node); parent_array->AddValue(std::make_shared>(bool_value)); } } } colon_index = -1; break; } case '{': parents.push_back(std::make_shared()); parent_node = parents.back(); if (parents.size() == 1) { root_node = parents[0]; } break; case '}': parents.pop_back(); parent_node = parents.back(); break; case '[': parents.push_back(std::make_shared()); parent_node = parents.back(); if (parents.size() == 1) { root_node = parents[0]; } case ']': parents.pop_back(); parent_node = parents.back(); break; case ':': colon_index = i; break; default: memory.push_back(c); break; } } return root_node; } int main() { auto json_obj = Parse(R"({"name":"tianlei","age":27,"is_student":true,"assets":["book","phone","computer",],})"); std::cout << json_obj->type() << '\n'; if (json_obj->type() == JsonValue::Object) { auto obj_value = std::dynamic_pointer_cast(json_obj); std::cout << "name: " << obj_value->getValue("name") << '\n'; std::cout << "age: " << obj_value->getValue("age") << '\n'; std::cout << "is_student: " << obj_value->getValue("is_student") << '\n'; } return 0; }