Advertisement
justefg

json.h

Jan 16th, 2019
491
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.10 KB | None | 0 0
  1. #ifndef MIXBYTES_INTERVIEW_JSON_H
  2. #define MIXBYTES_INTERVIEW_JSON_H
  3.  
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <string>
  7. #include <sstream>
  8. #include <list>
  9. #include <map>
  10.  
  11. using std::string;
  12. using std::stringstream;
  13.  
  14. class Value {
  15. public:
  16.     Value(): value_() {}
  17.     void SetValue(const std::string &val) {
  18.       value_ = val;
  19.     }
  20.     std::string GetValue() const {
  21.         return value_;
  22.     }
  23.     virtual ~Value() {}
  24.  
  25.  
  26. private:
  27.     std::string value_;
  28. };
  29.  
  30. class Elements {
  31. public:
  32.     Elements(): values_() {}
  33.     void insert(Value *val) {
  34.         values_.push_front(val);
  35.     }
  36.  
  37.     ~Elements() {
  38.       for(std::list<Value *>::iterator it = values_.begin();
  39.           it != values_.end(); it++) {
  40.         delete *it;
  41.       }
  42.     }
  43. private:
  44.     std::list<Value *> values_;
  45. };
  46.  
  47. class Array : public Value{
  48. public:
  49.     Array(): elems_(NULL) {}
  50.     explicit Array(Elements *elems): elems_(elems) {}
  51.  
  52.     ~Array() {
  53.       delete elems_;
  54.     }
  55. private:
  56.     Elements *elems_;
  57. };
  58.  
  59. class Members {
  60. public:
  61.     Members(): pairs_() {}
  62.     void insert(std::pair<std::string, Value *> p) {
  63.         pairs_.insert(p);
  64.     }
  65.  
  66.     ~Members() {
  67.       typedef std::map<std::string, Value*>::iterator map_iterator;
  68.       for (map_iterator it = pairs_.begin();
  69.            it != pairs_.end(); it++) {
  70.         delete it->second;
  71.       }
  72.     }
  73. private:
  74.     std::map<std::string, Value*> pairs_;
  75. };
  76.  
  77. class Object : public Value {
  78. public:
  79.     Object(): members_() {}
  80.     explicit Object(Members *mem): members_(mem) {}
  81. private:
  82.     Members *members_;
  83. };
  84.  
  85. class ParseError : public std::exception {
  86. public:
  87.     ParseError(const std::string &msg): message_(msg) {}
  88.     virtual const char* what() const throw() {
  89.       return message_.c_str();
  90.     }
  91.     virtual ~ParseError() throw() {}
  92. private:
  93.     std::string message_;
  94. };
  95.  
  96. class Parser {
  97. public:
  98.     explicit Parser(std::istream *stream): stream_(stream) {}
  99.     ~Parser() {}
  100.     Value *jValue();
  101.  
  102. private:
  103.     std::istream *stream_;
  104.  
  105.     char readCharacter();
  106.  
  107.     Object *jObject();
  108.     Members *jMembers();
  109.     std::pair<std::string, Value*> jPair();
  110.     Array *jArray();
  111.     Elements *jElements();
  112.     Value *jString();
  113.     void parseError(const std::string&, char);
  114.  
  115. };
  116.  
  117. char Parser::readCharacter() {
  118.     char c = stream_->get();
  119.     return c;
  120. }
  121.  
  122. Object *Parser::jObject() {
  123.     char c;
  124.     if ((c  = readCharacter()) != '{') {
  125.     parseError("character '{'", c);
  126.     }
  127.  
  128.     Object *ret = NULL;
  129.     if ((c = readCharacter()) == '}') {
  130.     ret = new Object();
  131.     } else {
  132.     stream_->unget();
  133.     ret = new Object(jMembers());
  134.     if ((c = readCharacter()) != '}') {
  135.       parseError("character '}'", c);
  136.     }
  137.     }
  138.  
  139.     return ret;
  140. }
  141.  
  142. Members *Parser::jMembers() {
  143.     std::pair<std::string, Value*> pair = jPair();
  144.     Members *ret;
  145.     char c = readCharacter();
  146.     if (c == ',') {
  147.     ret = jMembers();
  148.     } else {
  149.     stream_->unget();
  150.     ret = new Members();
  151.     }
  152.  
  153.     ret->insert(pair);
  154.  
  155.     return ret;
  156. }
  157.  
  158. std::pair<string, Value*> Parser::jPair() {
  159.     Value *str = jString();
  160.     char c = readCharacter();
  161.     if (c != ':') {
  162.     parseError("character ':'", c);
  163.     }
  164.     Value *val = jValue();
  165.  
  166.     std::string key = str->GetValue();
  167.  
  168.     key = key.substr(key.find_first_of("\"") + 1, key.find_last_of("\"") - 1);
  169.     std::pair<std::string, Value*> ret(key, val);
  170.     delete str;
  171.     return ret;
  172. }
  173.  
  174.  
  175. Array *Parser::jArray() {
  176.     char c;
  177.     if ((c = readCharacter()) != '[') {
  178.     parseError("character '['", c);
  179.     }
  180.     Array *ret = NULL;
  181.     if ((c = readCharacter()) == ']') {
  182.     ret = new Array();
  183.     } else {
  184.     stream_->unget();
  185.     ret = new Array(jElements());
  186.     if ((c = readCharacter()) != ']') {
  187.       parseError("character ']'", c);
  188.     }
  189.     }
  190.  
  191.     return ret;
  192. }
  193.  
  194. Elements *Parser::jElements() {
  195.   Value *val = jValue();
  196.   Elements *ret;
  197.   char c;
  198.   if ((c = readCharacter()) == ',') {
  199.     ret = jElements();
  200.   } else {
  201.     stream_->unget();
  202.     ret = new Elements();
  203.   }
  204.  
  205.   ret->insert(val);
  206.   return ret;
  207. }
  208.  
  209. Value *Parser::jValue() {
  210.   Value *ret = NULL;
  211.  
  212.   char c = readCharacter();
  213.  
  214.   switch(c) {
  215.     case '"':
  216.       stream_->unget();
  217.       ret = jString();
  218.       break;
  219.     case '{':
  220.       stream_->unget();
  221.       ret = jObject();
  222.       break;
  223.     case '[':
  224.       stream_->unget();
  225.       ret = jArray();
  226.       break;
  227.     default:
  228.       parseError("JSON Value", c);
  229.       break;
  230.   };
  231.  
  232.   return ret;
  233. }
  234.  
  235. Value *Parser::jString() {
  236.     string str;
  237.  
  238.     char c = stream_->get();
  239.     if (c != '"') {
  240.     parseError("character '\"'", c);
  241.     }
  242.  
  243.     while((c = stream_->get()) != '"') {
  244.     str.push_back(c);
  245.     }
  246.  
  247.     Value *ret = new Value();
  248.     ret->SetValue("\"" + str + "\"");
  249.  
  250.     return ret;
  251. }
  252.  
  253.  
  254. void Parser::parseError(const std::string &expected, char found) {
  255.  
  256.     if (found == -1) {
  257.     throw ParseError("unexpected end of file");
  258.     }
  259.  
  260.     stringstream msg;
  261.     msg << "Expected " << expected;
  262.     throw ParseError(msg.str());
  263. }
  264.  
  265. #endif //MIXBYTES_INTERVIEW_JSON_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement