daily pastebin goal
38%
SHARE
TWEET

json.h

justefg Jan 16th, 2019 72 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top