reader.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
  2. // Distributed under MIT license, or public domain if desired and
  3. // recognized in your jurisdiction.
  4. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
  5. #ifndef CPPTL_JSON_READER_H_INCLUDED
  6. #define CPPTL_JSON_READER_H_INCLUDED
  7. #if !defined(JSON_IS_AMALGAMATION)
  8. #include "features.h"
  9. #include "value.h"
  10. #endif // if !defined(JSON_IS_AMALGAMATION)
  11. #include <deque>
  12. #include <iosfwd>
  13. #include <stack>
  14. #include <string>
  15. #include <istream>
  16. // Disable warning C4251: <data member>: <type> needs to have dll-interface to
  17. // be used by...
  18. #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  19. #pragma warning(push)
  20. #pragma warning(disable : 4251)
  21. #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  22. #pragma pack(push, 8)
  23. namespace Json {
  24. /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
  25. *Value.
  26. *
  27. * \deprecated Use CharReader and CharReaderBuilder.
  28. */
  29. class JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") JSON_API Reader {
  30. public:
  31. typedef char Char;
  32. typedef const Char* Location;
  33. /** \brief An error tagged with where in the JSON text it was encountered.
  34. *
  35. * The offsets give the [start, limit) range of bytes within the text. Note
  36. * that this is bytes, not codepoints.
  37. *
  38. */
  39. struct StructuredError {
  40. ptrdiff_t offset_start;
  41. ptrdiff_t offset_limit;
  42. JSONCPP_STRING message;
  43. };
  44. /** \brief Constructs a Reader allowing all features
  45. * for parsing.
  46. */
  47. Reader();
  48. /** \brief Constructs a Reader allowing the specified feature set
  49. * for parsing.
  50. */
  51. Reader(const Features& features);
  52. /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
  53. * document.
  54. * \param document UTF-8 encoded string containing the document to read.
  55. * \param root [out] Contains the root value of the document if it was
  56. * successfully parsed.
  57. * \param collectComments \c true to collect comment and allow writing them
  58. * back during
  59. * serialization, \c false to discard comments.
  60. * This parameter is ignored if
  61. * Features::allowComments_
  62. * is \c false.
  63. * \return \c true if the document was successfully parsed, \c false if an
  64. * error occurred.
  65. */
  66. bool
  67. parse(const std::string& document, Value& root, bool collectComments = true);
  68. /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
  69. document.
  70. * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
  71. document to read.
  72. * \param endDoc Pointer on the end of the UTF-8 encoded string of the
  73. document to read.
  74. * Must be >= beginDoc.
  75. * \param root [out] Contains the root value of the document if it was
  76. * successfully parsed.
  77. * \param collectComments \c true to collect comment and allow writing them
  78. back during
  79. * serialization, \c false to discard comments.
  80. * This parameter is ignored if
  81. Features::allowComments_
  82. * is \c false.
  83. * \return \c true if the document was successfully parsed, \c false if an
  84. error occurred.
  85. */
  86. bool parse(const char* beginDoc,
  87. const char* endDoc,
  88. Value& root,
  89. bool collectComments = true);
  90. /// \brief Parse from input stream.
  91. /// \see Json::operator>>(std::istream&, Json::Value&).
  92. bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
  93. /** \brief Returns a user friendly string that list errors in the parsed
  94. * document.
  95. * \return Formatted error message with the list of errors with their location
  96. * in
  97. * the parsed document. An empty string is returned if no error
  98. * occurred
  99. * during parsing.
  100. * \deprecated Use getFormattedErrorMessages() instead (typo fix).
  101. */
  102. JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
  103. JSONCPP_STRING getFormatedErrorMessages() const;
  104. /** \brief Returns a user friendly string that list errors in the parsed
  105. * document.
  106. * \return Formatted error message with the list of errors with their location
  107. * in
  108. * the parsed document. An empty string is returned if no error
  109. * occurred
  110. * during parsing.
  111. */
  112. JSONCPP_STRING getFormattedErrorMessages() const;
  113. /** \brief Returns a vector of structured erros encounted while parsing.
  114. * \return A (possibly empty) vector of StructuredError objects. Currently
  115. * only one error can be returned, but the caller should tolerate
  116. * multiple
  117. * errors. This can occur if the parser recovers from a non-fatal
  118. * parse error and then encounters additional errors.
  119. */
  120. std::vector<StructuredError> getStructuredErrors() const;
  121. /** \brief Add a semantic error message.
  122. * \param value JSON Value location associated with the error
  123. * \param message The error message.
  124. * \return \c true if the error was successfully added, \c false if the
  125. * Value offset exceeds the document size.
  126. */
  127. bool pushError(const Value& value, const JSONCPP_STRING& message);
  128. /** \brief Add a semantic error message with extra context.
  129. * \param value JSON Value location associated with the error
  130. * \param message The error message.
  131. * \param extra Additional JSON Value location to contextualize the error
  132. * \return \c true if the error was successfully added, \c false if either
  133. * Value offset exceeds the document size.
  134. */
  135. bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
  136. /** \brief Return whether there are any errors.
  137. * \return \c true if there are no errors to report \c false if
  138. * errors have occurred.
  139. */
  140. bool good() const;
  141. private:
  142. enum TokenType {
  143. tokenEndOfStream = 0,
  144. tokenObjectBegin,
  145. tokenObjectEnd,
  146. tokenArrayBegin,
  147. tokenArrayEnd,
  148. tokenString,
  149. tokenNumber,
  150. tokenTrue,
  151. tokenFalse,
  152. tokenNull,
  153. tokenArraySeparator,
  154. tokenMemberSeparator,
  155. tokenComment,
  156. tokenError
  157. };
  158. class Token {
  159. public:
  160. TokenType type_;
  161. Location start_;
  162. Location end_;
  163. };
  164. class ErrorInfo {
  165. public:
  166. Token token_;
  167. JSONCPP_STRING message_;
  168. Location extra_;
  169. };
  170. typedef std::deque<ErrorInfo> Errors;
  171. bool readToken(Token& token);
  172. void skipSpaces();
  173. bool match(Location pattern, int patternLength);
  174. bool readComment();
  175. bool readCStyleComment();
  176. bool readCppStyleComment();
  177. bool readString();
  178. void readNumber();
  179. bool readValue();
  180. bool readObject(Token& token);
  181. bool readArray(Token& token);
  182. bool decodeNumber(Token& token);
  183. bool decodeNumber(Token& token, Value& decoded);
  184. bool decodeString(Token& token);
  185. bool decodeString(Token& token, JSONCPP_STRING& decoded);
  186. bool decodeDouble(Token& token);
  187. bool decodeDouble(Token& token, Value& decoded);
  188. bool decodeUnicodeCodePoint(Token& token,
  189. Location& current,
  190. Location end,
  191. unsigned int& unicode);
  192. bool decodeUnicodeEscapeSequence(Token& token,
  193. Location& current,
  194. Location end,
  195. unsigned int& unicode);
  196. bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
  197. bool recoverFromError(TokenType skipUntilToken);
  198. bool addErrorAndRecover(const JSONCPP_STRING& message,
  199. Token& token,
  200. TokenType skipUntilToken);
  201. void skipUntilSpace();
  202. Value& currentValue();
  203. Char getNextChar();
  204. void
  205. getLocationLineAndColumn(Location location, int& line, int& column) const;
  206. JSONCPP_STRING getLocationLineAndColumn(Location location) const;
  207. void addComment(Location begin, Location end, CommentPlacement placement);
  208. void skipCommentTokens(Token& token);
  209. static bool containsNewLine(Location begin, Location end);
  210. static JSONCPP_STRING normalizeEOL(Location begin, Location end);
  211. typedef std::stack<Value*> Nodes;
  212. Nodes nodes_;
  213. Errors errors_;
  214. JSONCPP_STRING document_;
  215. Location begin_;
  216. Location end_;
  217. Location current_;
  218. Location lastValueEnd_;
  219. Value* lastValue_;
  220. JSONCPP_STRING commentsBefore_;
  221. Features features_;
  222. bool collectComments_;
  223. }; // Reader
  224. /** Interface for reading JSON from a char array.
  225. */
  226. class JSON_API CharReader {
  227. public:
  228. virtual ~CharReader() {}
  229. /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
  230. document.
  231. * The document must be a UTF-8 encoded string containing the document to read.
  232. *
  233. * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
  234. document to read.
  235. * \param endDoc Pointer on the end of the UTF-8 encoded string of the
  236. document to read.
  237. * Must be >= beginDoc.
  238. * \param root [out] Contains the root value of the document if it was
  239. * successfully parsed.
  240. * \param errs [out] Formatted error messages (if not NULL)
  241. * a user friendly string that lists errors in the parsed
  242. * document.
  243. * \return \c true if the document was successfully parsed, \c false if an
  244. error occurred.
  245. */
  246. virtual bool parse(
  247. char const* beginDoc, char const* endDoc,
  248. Value* root, JSONCPP_STRING* errs) = 0;
  249. class JSON_API Factory {
  250. public:
  251. virtual ~Factory() {}
  252. /** \brief Allocate a CharReader via operator new().
  253. * \throw std::exception if something goes wrong (e.g. invalid settings)
  254. */
  255. virtual CharReader* newCharReader() const = 0;
  256. }; // Factory
  257. }; // CharReader
  258. /** \brief Build a CharReader implementation.
  259. Usage:
  260. \code
  261. using namespace Json;
  262. CharReaderBuilder builder;
  263. builder["collectComments"] = false;
  264. Value value;
  265. JSONCPP_STRING errs;
  266. bool ok = parseFromStream(builder, std::cin, &value, &errs);
  267. \endcode
  268. */
  269. class JSON_API CharReaderBuilder : public CharReader::Factory {
  270. public:
  271. // Note: We use a Json::Value so that we can add data-members to this class
  272. // without a major version bump.
  273. /** Configuration of this builder.
  274. These are case-sensitive.
  275. Available settings (case-sensitive):
  276. - `"collectComments": false or true`
  277. - true to collect comment and allow writing them
  278. back during serialization, false to discard comments.
  279. This parameter is ignored if allowComments is false.
  280. - `"allowComments": false or true`
  281. - true if comments are allowed.
  282. - `"strictRoot": false or true`
  283. - true if root must be either an array or an object value
  284. - `"allowDroppedNullPlaceholders": false or true`
  285. - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
  286. - `"allowNumericKeys": false or true`
  287. - true if numeric object keys are allowed.
  288. - `"allowSingleQuotes": false or true`
  289. - true if '' are allowed for strings (both keys and values)
  290. - `"stackLimit": integer`
  291. - Exceeding stackLimit (recursive depth of `readValue()`) will
  292. cause an exception.
  293. - This is a security issue (seg-faults caused by deeply nested JSON),
  294. so the default is low.
  295. - `"failIfExtra": false or true`
  296. - If true, `parse()` returns false when extra non-whitespace trails
  297. the JSON value in the input string.
  298. - `"rejectDupKeys": false or true`
  299. - If true, `parse()` returns false when a key is duplicated within an object.
  300. - `"allowSpecialFloats": false or true`
  301. - If true, special float values (NaNs and infinities) are allowed
  302. and their values are lossfree restorable.
  303. You can examine 'settings_` yourself
  304. to see the defaults. You can also write and read them just like any
  305. JSON Value.
  306. \sa setDefaults()
  307. */
  308. Json::Value settings_;
  309. CharReaderBuilder();
  310. ~CharReaderBuilder() JSONCPP_OVERRIDE;
  311. CharReader* newCharReader() const JSONCPP_OVERRIDE;
  312. /** \return true if 'settings' are legal and consistent;
  313. * otherwise, indicate bad settings via 'invalid'.
  314. */
  315. bool validate(Json::Value* invalid) const;
  316. /** A simple way to update a specific setting.
  317. */
  318. Value& operator[](JSONCPP_STRING key);
  319. /** Called by ctor, but you can use this to reset settings_.
  320. * \pre 'settings' != NULL (but Json::null is fine)
  321. * \remark Defaults:
  322. * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
  323. */
  324. static void setDefaults(Json::Value* settings);
  325. /** Same as old Features::strictMode().
  326. * \pre 'settings' != NULL (but Json::null is fine)
  327. * \remark Defaults:
  328. * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
  329. */
  330. static void strictMode(Json::Value* settings);
  331. };
  332. /** Consume entire stream and use its begin/end.
  333. * Someday we might have a real StreamReader, but for now this
  334. * is convenient.
  335. */
  336. bool JSON_API parseFromStream(
  337. CharReader::Factory const&,
  338. JSONCPP_ISTREAM&,
  339. Value* root, std::string* errs);
  340. /** \brief Read from 'sin' into 'root'.
  341. Always keep comments from the input JSON.
  342. This can be used to read a file into a particular sub-object.
  343. For example:
  344. \code
  345. Json::Value root;
  346. cin >> root["dir"]["file"];
  347. cout << root;
  348. \endcode
  349. Result:
  350. \verbatim
  351. {
  352. "dir": {
  353. "file": {
  354. // The input stream JSON would be nested here.
  355. }
  356. }
  357. }
  358. \endverbatim
  359. \throw std::exception on parse error.
  360. \see Json::operator<<()
  361. */
  362. JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
  363. } // namespace Json
  364. #pragma pack(pop)
  365. #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  366. #pragma warning(pop)
  367. #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
  368. #endif // CPPTL_JSON_READER_H_INCLUDED