Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <any>
- #include <vector>
- #include <sstream>
- #include <string>
- #include <fstream>
- #include <vector>
- #include <exception>
- #include <map>
- #include <list>
- using namespace std;
- class Json {
- any data;
- public:
- // Конструктор из строки, содержащей Json-данные.
- Json(const std::string &s) {
- for (size_t i = 0; i < s.size(); i++) {
- if (s[i] == '{') {
- data = split_obj(s, i);
- } else {
- if (s[i] == '[') {
- data = split_arr(s, i);
- }
- else{
- throw std::logic_error("Error");
- }
- }
- }
- };
- Json(const map<string, any> &map) {
- data = map;
- }
- Json(const vector<any> &vector) {
- data = vector;
- }
- // Метод возвращает true, если данный экземпляр содержит в себе JSON-массив. Иначе false.
- bool is_array() const {
- try {
- any_cast<vector<any>>(data);
- return true;
- }
- catch (const bad_any_cast &e) {
- return false;
- }
- };
- // Метод возвращает true, если данный экземпляр содержит в себе JSON-объект. Иначе false.
- bool is_object() const {
- try {
- any_cast<map<string, any>>(data);
- return true;
- }
- catch (const bad_any_cast &e) {
- return false;
- }
- };
- // Метод возвращает значение по ключу key, если экземпляр является JSON-объектом.
- // Значение может иметь один из следующих типов: Json, std::string, double, bool или быть пустым.
- // Если экземпляр является JSON-массивом, генерируется исключение.
- std::any &operator[](const std::string &key) {
- try {
- if (is_object()) {
- //return data.key;
- }
- }
- catch (std::exception &e) {
- std::cout << e.what() << std::endl;
- }
- };
- // Метод возвращает значение по индексу index, если экземпляр является JSON-массивом.
- // Значение может иметь один из следующих типов: Json, std::string, double, bool или быть пустым.
- // Если экземпляр является JSON-объектом, генерируется исключение.
- std::any &operator[](int index) {
- try {
- if (is_array()) {
- //return data[index];
- }
- }
- catch (std::exception &e) {
- std::cout << e.what() << std::endl;
- }
- };
- // Метод возвращает объект класса Json из строки, содержащей Json-данные.
- static Json parse(const std::string &s) {
- return Json(s);
- };
- // Метод возвращает объекта класса Json из файла, содержащего Json-данные в текстовом формате.
- static Json parseFile(const std::string &path_to_file) {
- ifstream file;
- string s;
- string line;
- while (getline(file, line)) {
- s += line;
- }
- return Json(s);
- };
- string split_string(const string &str, size_t &j) {
- string result;
- std::string::size_type next;
- j = str.find('"', j);
- if (str[j] == '"') {
- next = str.find('"', j++);
- result = str.substr(j++, next--);
- j = next++;
- } else {
- throw std::logic_error("Error");
- /*j = str.find('"', j++);
- next = str.find('"', j++);
- result = str.substr(j++, next--);
- j = next;*/
- }
- /*else if(str[j] == ':' || str[j] == ',') {
- throw std::logic_error("Error");
- }*/
- return result;
- }
- bool split_bool(const string &str, size_t &j) {
- string string;
- for (size_t i = j; i < str.size(); ++i)
- {
- if (isalpha(str[i])) {
- string += str[i];
- }
- else if (str[i] == ',' || str[i] == ']' || str[i] == '}') {
- j = --i;
- if (string == "false") {
- return false;
- }
- else if (string == "true") {
- return true;
- }
- else {
- throw std::invalid_argument("Wrong argument");
- }
- }
- else {
- throw std::invalid_argument("Error");
- }
- }
- return false;
- }
- double split_double(const string &str, size_t &j) {
- string s;
- for (size_t i = j; i < str.find_first_not_of(isdigit(str[j])); ++i) {
- if (isdigit(str[i]) || str[i] == '.') {
- s += str[i];
- } else if (str[i] == ',' || str[i] == ']' || str[i] == '}'
- || isspace(str[i])) {
- j = --i;
- return stod(s);
- }
- else{
- throw std::logic_error("Error");
- }
- }
- }
- vector<any> split_arr(const string &str, size_t &j) {
- vector<any> result;
- j = str.find('[', j);
- size_t next = j;
- size_t exit = str.find(']', j++);
- if (str[j] == '[')
- while (next < exit)
- for (size_t i = j; i < str.find_last_of(']', j++); i++) {
- next = str.find('[', next++);
- exit = str.find(']', exit++);
- }
- if (str[j] == '[') {
- for (size_t i = j; i < exit; i++) {
- if (isdigit(str[i])) {
- result.emplace_back(split_double(str, i));
- i = j;
- } else if (isalpha(str[i])) {
- result.emplace_back(split_bool(str, i));
- i = j;
- } else if (str[i] == '"') {
- result.emplace_back(split_string(str, i));
- i = j;
- } else if (str[i] == '[') {
- result.emplace_back(Json(split_arr(str, i)));
- i = j;
- } else if (str[i] == '{') {
- result.emplace_back(Json(split_obj(str, i)));
- i = j;
- } else if (str[i] == ',') {
- i = str.find_first_not_of(isspace(str[i]), i++);
- i = j;
- } else if (str[i] == ']') {
- j = i;
- return result;
- }
- }
- }
- }
- map<string, any> split_obj(const string &str, size_t &j) {
- map<string, any> result;
- string key;
- bool iskey = true;
- j = str.find('{', j);
- size_t next = j;
- size_t exit = str.find('}', j++);
- if (str[j] == '{')
- while (next < exit)
- for (size_t i = j; i < str.find_last_of('}', j++); i++) {
- next = str.find('{', next++);
- exit = str.find('}', exit++);
- }
- if (str[j] == '{') {
- for (size_t i = j; i < exit; i++) {
- if (str[i] == '"' && iskey) {
- key = split_string(str, i);
- iskey = false;
- j = str.find(':', i);
- i = str.find_first_not_of(isspace(str[j]), j++);
- } else if (str[i] == '"' && !iskey) {
- result[key] = split_string(str, i);
- i = str.find('"', j);
- iskey = true;
- } else if (isdigit(str[i])) {
- result[key] = split_double(str, i);
- i = str.find('"', j);
- iskey = true;
- } else if (isalpha(str[i])) {
- result[key] = split_bool(str, i);
- i = str.find('"', j);
- iskey = true;
- } else if (str[i] == '[') {
- result[key] = split_arr(str, i);
- i = str.find('"', j);
- iskey = true;
- } else if (str[i] == '{') {
- result[key] = split_obj(str, i);
- i = str.find('"', j);
- iskey = true;
- } else if (str[i] == '}') {
- j = i;
- return result;
- }
- }
- }
- }
- void Json::print(any _data) {
- string type = _data.type().name();
- try {
- if (type == "i") {
- cout << any_cast<int> (_data);
- }
- else if (type == "d") {
- cout << any_cast<double> (_data);
- }
- else if (type == "b") {
- if (any_cast<bool> (_data)) std::cout << "true";
- else cout << "false";
- }
- else if (type == "Ss" || type == "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE") {
- cout << any_cast<string> (_data);
- }
- else if (type.find("St6vector") < type.length()) {
- std::vector <std::any> vec;
- vec = any_cast<vector<any>>(_data);
- unsigned int count = 0;
- cout << "[ ";
- for (const auto& c : vec) {
- count++;
- if (count > 1) std::cout << " , ";
- print(c);
- }
- cout << " ]";
- }
- else if (type.find("St3map") < type.length()) {
- map <string, any> _map;
- _map = std::any_cast<map <string, any>>(_data);
- cout << "{\n" ;
- unsigned int count = 0;
- for (const auto& c: _map) {
- count++;
- if (count > 1) cout << " ,\n";
- cout << "\t" << c.first << " : ";
- print(c.second);
- }
- cout << "\n\t}";
- }
- }
- catch(const std::bad_any_cast& e) {
- cout << e.what() << '\n';
- }
- }
- void Json::print_map() {
- cout << "{\n";
- int i = 0;
- for(const auto& p : any_cast<map<string, any>>(data)) {
- if (i != 0) cout <<",\n";
- cout << " "<< p.first << " : ";
- print(p.second);
- i++;
- }
- cout<< "}\n";
- }
- };
- using namespace std;
- int main() {
- string text;
- text = R"({ "lastname" : "Ivanov" , "firstname" : "Ivan" , "age" : 25,"islegal" : false,"marks" : [ 4 , 5 , 5 , 5 , 2 , 3 ],"address" : { "city" : "Moscow" , "street" : "Vozdvijenka" } })";
- Json object = Json::parse(text);
- cout<< endl;
- object.print_map();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement