reader.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #ifndef CPPTL_JSON_READER_H_INCLUDED
  2. # define CPPTL_JSON_READER_H_INCLUDED
  3. # include "features.h"
  4. # include "value.h"
  5. # include <deque>
  6. # include <stack>
  7. # include <string>
  8. # include <iostream>
  9. namespace Json {
  10. /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
  11. *
  12. */
  13. class JSON_API Reader
  14. {
  15. public:
  16. typedef char Char;
  17. typedef const Char *Location;
  18. /** \brief Constructs a Reader allowing all features
  19. * for parsing.
  20. */
  21. Reader();
  22. /** \brief Constructs a Reader allowing the specified feature set
  23. * for parsing.
  24. */
  25. Reader( const Features &features );
  26. /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
  27. * \param document UTF-8 encoded string containing the document to read.
  28. * \param root [out] Contains the root value of the document if it was
  29. * successfully parsed.
  30. * \param collectComments \c true to collect comment and allow writing them back during
  31. * serialization, \c false to discard comments.
  32. * This parameter is ignored if Features::allowComments_
  33. * is \c false.
  34. * \return \c true if the document was successfully parsed, \c false if an error occurred.
  35. */
  36. bool parse( const std::string &document,
  37. Value &root,
  38. bool collectComments = true );
  39. /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
  40. * \param document UTF-8 encoded string containing the document to read.
  41. * \param root [out] Contains the root value of the document if it was
  42. * successfully parsed.
  43. * \param collectComments \c true to collect comment and allow writing them back during
  44. * serialization, \c false to discard comments.
  45. * This parameter is ignored if Features::allowComments_
  46. * is \c false.
  47. * \return \c true if the document was successfully parsed, \c false if an error occurred.
  48. */
  49. bool parse( const char *beginDoc, const char *endDoc,
  50. Value &root,
  51. bool collectComments = true );
  52. /// \brief Parse from input stream.
  53. /// \see Json::operator>>(std::istream&, Json::Value&).
  54. bool parse( std::istream &is,
  55. Value &root,
  56. bool collectComments = true );
  57. /** \brief Returns a user friendly string that list errors in the parsed document.
  58. * \return Formatted error message with the list of errors with their location in
  59. * the parsed document. An empty string is returned if no error occurred
  60. * during parsing.
  61. */
  62. std::string getFormatedErrorMessages() const;
  63. private:
  64. enum TokenType
  65. {
  66. tokenEndOfStream = 0,
  67. tokenObjectBegin,
  68. tokenObjectEnd,
  69. tokenArrayBegin,
  70. tokenArrayEnd,
  71. tokenString,
  72. tokenNumber,
  73. tokenTrue,
  74. tokenFalse,
  75. tokenNull,
  76. tokenArraySeparator,
  77. tokenMemberSeparator,
  78. tokenComment,
  79. tokenError
  80. };
  81. class Token
  82. {
  83. public:
  84. TokenType type_;
  85. Location start_;
  86. Location end_;
  87. };
  88. class ErrorInfo
  89. {
  90. public:
  91. Token token_;
  92. std::string message_;
  93. Location extra_;
  94. };
  95. typedef std::deque<ErrorInfo> Errors;
  96. bool expectToken( TokenType type, Token &token, const char *message );
  97. bool readToken( Token &token );
  98. void skipSpaces();
  99. bool match( Location pattern,
  100. int patternLength );
  101. bool readComment();
  102. bool readCStyleComment();
  103. bool readCppStyleComment();
  104. bool readString();
  105. void readNumber();
  106. bool readValue();
  107. bool readObject( Token &token );
  108. bool readArray( Token &token );
  109. bool decodeNumber( Token &token );
  110. bool decodeString( Token &token );
  111. bool decodeString( Token &token, std::string &decoded );
  112. bool decodeDouble( Token &token );
  113. bool decodeUnicodeCodePoint( Token &token,
  114. Location &current,
  115. Location end,
  116. unsigned int &unicode );
  117. bool decodeUnicodeEscapeSequence( Token &token,
  118. Location &current,
  119. Location end,
  120. unsigned int &unicode );
  121. bool addError( const std::string &message,
  122. Token &token,
  123. Location extra = 0 );
  124. bool recoverFromError( TokenType skipUntilToken );
  125. bool addErrorAndRecover( const std::string &message,
  126. Token &token,
  127. TokenType skipUntilToken );
  128. void skipUntilSpace();
  129. Value &currentValue();
  130. Char getNextChar();
  131. void getLocationLineAndColumn( Location location,
  132. int &line,
  133. int &column ) const;
  134. std::string getLocationLineAndColumn( Location location ) const;
  135. void addComment( Location begin,
  136. Location end,
  137. CommentPlacement placement );
  138. void skipCommentTokens( Token &token );
  139. typedef std::stack<Value *> Nodes;
  140. Nodes nodes_;
  141. Errors errors_;
  142. std::string document_;
  143. Location begin_;
  144. Location end_;
  145. Location current_;
  146. Location lastValueEnd_;
  147. Value *lastValue_;
  148. std::string commentsBefore_;
  149. Features features_;
  150. bool collectComments_;
  151. };
  152. /** \brief Read from 'sin' into 'root'.
  153. Always keep comments from the input JSON.
  154. This can be used to read a file into a particular sub-object.
  155. For example:
  156. \code
  157. Json::Value root;
  158. cin >> root["dir"]["file"];
  159. cout << root;
  160. \endcode
  161. Result:
  162. \verbatim
  163. {
  164. "dir": {
  165. "file": {
  166. // The input stream JSON would be nested here.
  167. }
  168. }
  169. }
  170. \endverbatim
  171. \throw std::exception on parse error.
  172. \see Json::operator<<()
  173. */
  174. std::istream& operator>>( std::istream&, Value& );
  175. } // namespace Json
  176. #endif // CPPTL_JSON_READER_H_INCLUDED