Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef MIXBYTES_INTERVIEW_JSON_H
- #define MIXBYTES_INTERVIEW_JSON_H
- #include <cstdlib>
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <list>
- #include <map>
- using std::string;
- using std::stringstream;
- class Value {
- public:
- Value(): value_() {}
- void SetValue(const std::string &val) {
- value_ = val;
- }
- std::string GetValue() const {
- return value_;
- }
- virtual ~Value() {}
- private:
- std::string value_;
- };
- class Elements {
- public:
- Elements(): values_() {}
- void insert(Value *val) {
- values_.push_front(val);
- }
- ~Elements() {
- for(std::list<Value *>::iterator it = values_.begin();
- it != values_.end(); it++) {
- delete *it;
- }
- }
- private:
- std::list<Value *> values_;
- };
- class Array : public Value{
- public:
- Array(): elems_(NULL) {}
- explicit Array(Elements *elems): elems_(elems) {}
- ~Array() {
- delete elems_;
- }
- private:
- Elements *elems_;
- };
- class Members {
- public:
- Members(): pairs_() {}
- void insert(std::pair<std::string, Value *> p) {
- pairs_.insert(p);
- }
- ~Members() {
- typedef std::map<std::string, Value*>::iterator map_iterator;
- for (map_iterator it = pairs_.begin();
- it != pairs_.end(); it++) {
- delete it->second;
- }
- }
- private:
- std::map<std::string, Value*> pairs_;
- };
- class Object : public Value {
- public:
- Object(): members_() {}
- explicit Object(Members *mem): members_(mem) {}
- private:
- Members *members_;
- };
- class ParseError : public std::exception {
- public:
- ParseError(const std::string &msg): message_(msg) {}
- virtual const char* what() const throw() {
- return message_.c_str();
- }
- virtual ~ParseError() throw() {}
- private:
- std::string message_;
- };
- class Parser {
- public:
- explicit Parser(std::istream *stream): stream_(stream) {}
- ~Parser() {}
- Value *jValue();
- private:
- std::istream *stream_;
- char readCharacter();
- Object *jObject();
- Members *jMembers();
- std::pair<std::string, Value*> jPair();
- Array *jArray();
- Elements *jElements();
- Value *jString();
- void parseError(const std::string&, char);
- };
- char Parser::readCharacter() {
- char c = stream_->get();
- return c;
- }
- Object *Parser::jObject() {
- char c;
- if ((c = readCharacter()) != '{') {
- parseError("character '{'", c);
- }
- Object *ret = NULL;
- if ((c = readCharacter()) == '}') {
- ret = new Object();
- } else {
- stream_->unget();
- ret = new Object(jMembers());
- if ((c = readCharacter()) != '}') {
- parseError("character '}'", c);
- }
- }
- return ret;
- }
- Members *Parser::jMembers() {
- std::pair<std::string, Value*> pair = jPair();
- Members *ret;
- char c = readCharacter();
- if (c == ',') {
- ret = jMembers();
- } else {
- stream_->unget();
- ret = new Members();
- }
- ret->insert(pair);
- return ret;
- }
- std::pair<string, Value*> Parser::jPair() {
- Value *str = jString();
- char c = readCharacter();
- if (c != ':') {
- parseError("character ':'", c);
- }
- Value *val = jValue();
- std::string key = str->GetValue();
- key = key.substr(key.find_first_of("\"") + 1, key.find_last_of("\"") - 1);
- std::pair<std::string, Value*> ret(key, val);
- delete str;
- return ret;
- }
- Array *Parser::jArray() {
- char c;
- if ((c = readCharacter()) != '[') {
- parseError("character '['", c);
- }
- Array *ret = NULL;
- if ((c = readCharacter()) == ']') {
- ret = new Array();
- } else {
- stream_->unget();
- ret = new Array(jElements());
- if ((c = readCharacter()) != ']') {
- parseError("character ']'", c);
- }
- }
- return ret;
- }
- Elements *Parser::jElements() {
- Value *val = jValue();
- Elements *ret;
- char c;
- if ((c = readCharacter()) == ',') {
- ret = jElements();
- } else {
- stream_->unget();
- ret = new Elements();
- }
- ret->insert(val);
- return ret;
- }
- Value *Parser::jValue() {
- Value *ret = NULL;
- char c = readCharacter();
- switch(c) {
- case '"':
- stream_->unget();
- ret = jString();
- break;
- case '{':
- stream_->unget();
- ret = jObject();
- break;
- case '[':
- stream_->unget();
- ret = jArray();
- break;
- default:
- parseError("JSON Value", c);
- break;
- };
- return ret;
- }
- Value *Parser::jString() {
- string str;
- char c = stream_->get();
- if (c != '"') {
- parseError("character '\"'", c);
- }
- while((c = stream_->get()) != '"') {
- str.push_back(c);
- }
- Value *ret = new Value();
- ret->SetValue("\"" + str + "\"");
- return ret;
- }
- void Parser::parseError(const std::string &expected, char found) {
- if (found == -1) {
- throw ParseError("unexpected end of file");
- }
- stringstream msg;
- msg << "Expected " << expected;
- throw ParseError(msg.str());
- }
- #endif //MIXBYTES_INTERVIEW_JSON_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement