1 /********************************************** 2 3 License: BSD 4 Project Webpage: http://cajun-jsonapi.sourceforge.net/ 5 Author: Terry Caton 6 7 ***********************************************/ 8 9 #pragma once 10 11 #include "elements.h" 12 13 #include <vector> 14 15 namespace json 16 { 17 18 class Reader { 19 public: 20 // this structure will be reported in one of the exceptions defined below 21 struct Location { 22 unsigned int m_nLine = 0; // document line, zero-indexed 23 unsigned int m_nLineOffset = 0; // character offset from beginning of line, zero indexed 24 unsigned int m_nDocOffset = 0; // character offset from entire document, zero indexed 25 }; 26 27 // thrown during the first phase of reading. generally catches low-level 28 // problems such as errant characters or corrupt/incomplete documents 29 class ScanException final : public Exception { 30 public: ScanException(std::string const & sMessage,Reader::Location locError)31 ScanException(std::string const& sMessage, Reader::Location locError) 32 : Exception(sMessage) 33 , m_locError(std::move(locError)) 34 { } 35 36 Reader::Location m_locError; 37 }; 38 39 // thrown during the second phase of reading. generally catches 40 // higher-level problems such as missing commas or brackets 41 class ParseException final : public Exception { 42 public: ParseException(std::string const & sMessage,Reader::Location locTokenBegin,Reader::Location locTokenEnd)43 ParseException(std::string const& sMessage, Reader::Location locTokenBegin, Reader::Location locTokenEnd) 44 : Exception(sMessage) 45 , m_locTokenBegin(std::move(locTokenBegin)) 46 , m_locTokenEnd(std::move(locTokenEnd)) 47 { } 48 49 Reader::Location m_locTokenBegin; 50 Reader::Location m_locTokenEnd; 51 }; 52 53 static void Read(UnknownElement& elementRoot, std::istream& istr); 54 55 private: 56 struct Token { 57 enum Type { 58 TOKEN_OBJECT_BEGIN, // { 59 TOKEN_OBJECT_END, // } 60 TOKEN_ARRAY_BEGIN, // [ 61 TOKEN_ARRAY_END, // ] 62 TOKEN_NEXT_ELEMENT, // , 63 TOKEN_MEMBER_ASSIGN, // : 64 TOKEN_STRING, // "xxx" 65 TOKEN_NUMBER, // [+/-]000.000[e[+/-]000] 66 TOKEN_BOOLEAN, // true -or- false 67 TOKEN_NULL // null 68 }; 69 70 Type nType; 71 std::string sValue; 72 73 // for malformed file debugging 74 Reader::Location locBegin; 75 Reader::Location locEnd; 76 }; 77 78 class InputStream; 79 class TokenStream; 80 typedef std::vector<Token> Tokens; 81 82 // scanning istream into token sequence 83 void Scan(Tokens& tokens, InputStream& inputStream); 84 85 void EatWhiteSpace(InputStream& inputStream); 86 void MatchString(std::string& sValue, InputStream& inputStream); 87 void MatchNumber(std::string& sNumber, InputStream& inputStream); 88 void MatchExpectedString(std::string const& sExpected, InputStream& inputStream); 89 90 // parsing token sequence into element structure 91 UnknownElement Parse(TokenStream& tokenStream); 92 UnknownElement ParseObject(TokenStream& tokenStream); 93 UnknownElement ParseArray(TokenStream& tokenStream); 94 UnknownElement ParseString(TokenStream& tokenStream); 95 UnknownElement ParseNumber(TokenStream& tokenStream); 96 UnknownElement ParseBoolean(TokenStream& tokenStream); 97 UnknownElement ParseNull(TokenStream& tokenStream); 98 99 std::string const& MatchExpectedToken(Token::Type nExpected, TokenStream& tokenStream); 100 }; 101 102 } 103