Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
reader.h
00001 // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors 00002 // Distributed under MIT license, or public domain if desired and 00003 // recognized in your jurisdiction. 00004 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 00005 00006 #ifndef CPPTL_JSON_READER_H_INCLUDED 00007 #define CPPTL_JSON_READER_H_INCLUDED 00008 00009 #if !defined(JSON_IS_AMALGAMATION) 00010 #include "features.h" 00011 #include "value.h" 00012 #endif // if !defined(JSON_IS_AMALGAMATION) 00013 #include <deque> 00014 #include <iosfwd> 00015 #include <stack> 00016 #include <string> 00017 #include <istream> 00018 00019 // Disable warning C4251: <data member>: <type> needs to have dll-interface to 00020 // be used by... 00021 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 00022 #pragma warning(push) 00023 #pragma warning(disable : 4251) 00024 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 00025 00026 #pragma pack(push, 8) 00027 00028 namespace Json { 00029 00030 /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a 00031 *Value. 00032 * 00033 * \deprecated Use CharReader and CharReaderBuilder. 00034 */ 00035 class JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") JSON_API Reader { 00036 public: 00037 typedef char Char; 00038 typedef const Char* Location; 00039 00040 /** \brief An error tagged with where in the JSON text it was encountered. 00041 * 00042 * The offsets give the [start, limit) range of bytes within the text. Note 00043 * that this is bytes, not codepoints. 00044 * 00045 */ 00046 struct StructuredError { 00047 ptrdiff_t offset_start; 00048 ptrdiff_t offset_limit; 00049 JSONCPP_STRING message; 00050 }; 00051 00052 /** \brief Constructs a Reader allowing all features 00053 * for parsing. 00054 */ 00055 Reader(); 00056 00057 /** \brief Constructs a Reader allowing the specified feature set 00058 * for parsing. 00059 */ 00060 Reader(const Features& features); 00061 00062 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> 00063 * document. 00064 * \param document UTF-8 encoded string containing the document to read. 00065 * \param root [out] Contains the root value of the document if it was 00066 * successfully parsed. 00067 * \param collectComments \c true to collect comment and allow writing them 00068 * back during 00069 * serialization, \c false to discard comments. 00070 * This parameter is ignored if 00071 * Features::allowComments_ 00072 * is \c false. 00073 * \return \c true if the document was successfully parsed, \c false if an 00074 * error occurred. 00075 */ 00076 bool 00077 parse(const std::string& document, Value& root, bool collectComments = true); 00078 00079 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> 00080 document. 00081 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 00082 document to read. 00083 * \param endDoc Pointer on the end of the UTF-8 encoded string of the 00084 document to read. 00085 * Must be >= beginDoc. 00086 * \param root [out] Contains the root value of the document if it was 00087 * successfully parsed. 00088 * \param collectComments \c true to collect comment and allow writing them 00089 back during 00090 * serialization, \c false to discard comments. 00091 * This parameter is ignored if 00092 Features::allowComments_ 00093 * is \c false. 00094 * \return \c true if the document was successfully parsed, \c false if an 00095 error occurred. 00096 */ 00097 bool parse(const char* beginDoc, 00098 const char* endDoc, 00099 Value& root, 00100 bool collectComments = true); 00101 00102 /// \brief Parse from input stream. 00103 /// \see Json::operator>>(std::istream&, Json::Value&). 00104 bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true); 00105 00106 /** \brief Returns a user friendly string that list errors in the parsed 00107 * document. 00108 * \return Formatted error message with the list of errors with their location 00109 * in 00110 * the parsed document. An empty string is returned if no error 00111 * occurred 00112 * during parsing. 00113 * \deprecated Use getFormattedErrorMessages() instead (typo fix). 00114 */ 00115 JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") 00116 JSONCPP_STRING getFormatedErrorMessages() const; 00117 00118 /** \brief Returns a user friendly string that list errors in the parsed 00119 * document. 00120 * \return Formatted error message with the list of errors with their location 00121 * in 00122 * the parsed document. An empty string is returned if no error 00123 * occurred 00124 * during parsing. 00125 */ 00126 JSONCPP_STRING getFormattedErrorMessages() const; 00127 00128 /** \brief Returns a vector of structured erros encounted while parsing. 00129 * \return A (possibly empty) vector of StructuredError objects. Currently 00130 * only one error can be returned, but the caller should tolerate 00131 * multiple 00132 * errors. This can occur if the parser recovers from a non-fatal 00133 * parse error and then encounters additional errors. 00134 */ 00135 std::vector<StructuredError> getStructuredErrors() const; 00136 00137 /** \brief Add a semantic error message. 00138 * \param value JSON Value location associated with the error 00139 * \param message The error message. 00140 * \return \c true if the error was successfully added, \c false if the 00141 * Value offset exceeds the document size. 00142 */ 00143 bool pushError(const Value& value, const JSONCPP_STRING& message); 00144 00145 /** \brief Add a semantic error message with extra context. 00146 * \param value JSON Value location associated with the error 00147 * \param message The error message. 00148 * \param extra Additional JSON Value location to contextualize the error 00149 * \return \c true if the error was successfully added, \c false if either 00150 * Value offset exceeds the document size. 00151 */ 00152 bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); 00153 00154 /** \brief Return whether there are any errors. 00155 * \return \c true if there are no errors to report \c false if 00156 * errors have occurred. 00157 */ 00158 bool good() const; 00159 00160 private: 00161 enum TokenType { 00162 tokenEndOfStream = 0, 00163 tokenObjectBegin, 00164 tokenObjectEnd, 00165 tokenArrayBegin, 00166 tokenArrayEnd, 00167 tokenString, 00168 tokenNumber, 00169 tokenTrue, 00170 tokenFalse, 00171 tokenNull, 00172 tokenArraySeparator, 00173 tokenMemberSeparator, 00174 tokenComment, 00175 tokenError 00176 }; 00177 00178 class Token { 00179 public: 00180 TokenType type_; 00181 Location start_; 00182 Location end_; 00183 }; 00184 00185 class ErrorInfo { 00186 public: 00187 Token token_; 00188 JSONCPP_STRING message_; 00189 Location extra_; 00190 }; 00191 00192 typedef std::deque<ErrorInfo> Errors; 00193 00194 bool readToken(Token& token); 00195 void skipSpaces(); 00196 bool match(Location pattern, int patternLength); 00197 bool readComment(); 00198 bool readCStyleComment(); 00199 bool readCppStyleComment(); 00200 bool readString(); 00201 void readNumber(); 00202 bool readValue(); 00203 bool readObject(Token& token); 00204 bool readArray(Token& token); 00205 bool decodeNumber(Token& token); 00206 bool decodeNumber(Token& token, Value& decoded); 00207 bool decodeString(Token& token); 00208 bool decodeString(Token& token, JSONCPP_STRING& decoded); 00209 bool decodeDouble(Token& token); 00210 bool decodeDouble(Token& token, Value& decoded); 00211 bool decodeUnicodeCodePoint(Token& token, 00212 Location& current, 00213 Location end, 00214 unsigned int& unicode); 00215 bool decodeUnicodeEscapeSequence(Token& token, 00216 Location& current, 00217 Location end, 00218 unsigned int& unicode); 00219 bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); 00220 bool recoverFromError(TokenType skipUntilToken); 00221 bool addErrorAndRecover(const JSONCPP_STRING& message, 00222 Token& token, 00223 TokenType skipUntilToken); 00224 void skipUntilSpace(); 00225 Value& currentValue(); 00226 Char getNextChar(); 00227 void 00228 getLocationLineAndColumn(Location location, int& line, int& column) const; 00229 JSONCPP_STRING getLocationLineAndColumn(Location location) const; 00230 void addComment(Location begin, Location end, CommentPlacement placement); 00231 void skipCommentTokens(Token& token); 00232 00233 static bool containsNewLine(Location begin, Location end); 00234 static JSONCPP_STRING normalizeEOL(Location begin, Location end); 00235 00236 typedef std::stack<Value*> Nodes; 00237 Nodes nodes_; 00238 Errors errors_; 00239 JSONCPP_STRING document_; 00240 Location begin_; 00241 Location end_; 00242 Location current_; 00243 Location lastValueEnd_; 00244 Value* lastValue_; 00245 JSONCPP_STRING commentsBefore_; 00246 Features features_; 00247 bool collectComments_; 00248 }; // Reader 00249 00250 /** Interface for reading JSON from a char array. 00251 */ 00252 class JSON_API CharReader { 00253 public: 00254 virtual ~CharReader() {} 00255 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> 00256 document. 00257 * The document must be a UTF-8 encoded string containing the document to read. 00258 * 00259 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the 00260 document to read. 00261 * \param endDoc Pointer on the end of the UTF-8 encoded string of the 00262 document to read. 00263 * Must be >= beginDoc. 00264 * \param root [out] Contains the root value of the document if it was 00265 * successfully parsed. 00266 * \param errs [out] Formatted error messages (if not NULL) 00267 * a user friendly string that lists errors in the parsed 00268 * document. 00269 * \return \c true if the document was successfully parsed, \c false if an 00270 error occurred. 00271 */ 00272 virtual bool parse( 00273 char const* beginDoc, char const* endDoc, 00274 Value* root, JSONCPP_STRING* errs) = 0; 00275 00276 class JSON_API Factory { 00277 public: 00278 virtual ~Factory() {} 00279 /** \brief Allocate a CharReader via operator new(). 00280 * \throw std::exception if something goes wrong (e.g. invalid settings) 00281 */ 00282 virtual CharReader* newCharReader() const = 0; 00283 }; // Factory 00284 }; // CharReader 00285 00286 /** \brief Build a CharReader implementation. 00287 00288 Usage: 00289 \code 00290 using namespace Json; 00291 CharReaderBuilder builder; 00292 builder["collectComments"] = false; 00293 Value value; 00294 JSONCPP_STRING errs; 00295 bool ok = parseFromStream(builder, std::cin, &value, &errs); 00296 \endcode 00297 */ 00298 class JSON_API CharReaderBuilder : public CharReader::Factory { 00299 public: 00300 // Note: We use a Json::Value so that we can add data-members to this class 00301 // without a major version bump. 00302 /** Configuration of this builder. 00303 These are case-sensitive. 00304 Available settings (case-sensitive): 00305 - `"collectComments": false or true` 00306 - true to collect comment and allow writing them 00307 back during serialization, false to discard comments. 00308 This parameter is ignored if allowComments is false. 00309 - `"allowComments": false or true` 00310 - true if comments are allowed. 00311 - `"strictRoot": false or true` 00312 - true if root must be either an array or an object value 00313 - `"allowDroppedNullPlaceholders": false or true` 00314 - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) 00315 - `"allowNumericKeys": false or true` 00316 - true if numeric object keys are allowed. 00317 - `"allowSingleQuotes": false or true` 00318 - true if '' are allowed for strings (both keys and values) 00319 - `"stackLimit": integer` 00320 - Exceeding stackLimit (recursive depth of `readValue()`) will 00321 cause an exception. 00322 - This is a security issue (seg-faults caused by deeply nested JSON), 00323 so the default is low. 00324 - `"failIfExtra": false or true` 00325 - If true, `parse()` returns false when extra non-whitespace trails 00326 the JSON value in the input string. 00327 - `"rejectDupKeys": false or true` 00328 - If true, `parse()` returns false when a key is duplicated within an object. 00329 - `"allowSpecialFloats": false or true` 00330 - If true, special float values (NaNs and infinities) are allowed 00331 and their values are lossfree restorable. 00332 00333 You can examine 'settings_` yourself 00334 to see the defaults. You can also write and read them just like any 00335 JSON Value. 00336 \sa setDefaults() 00337 */ 00338 Json::Value settings_; 00339 00340 CharReaderBuilder(); 00341 ~CharReaderBuilder() JSONCPP_OVERRIDE; 00342 00343 CharReader* newCharReader() const JSONCPP_OVERRIDE; 00344 00345 /** \return true if 'settings' are legal and consistent; 00346 * otherwise, indicate bad settings via 'invalid'. 00347 */ 00348 bool validate(Json::Value* invalid) const; 00349 00350 /** A simple way to update a specific setting. 00351 */ 00352 Value& operator[](JSONCPP_STRING key); 00353 00354 /** Called by ctor, but you can use this to reset settings_. 00355 * \pre 'settings' != NULL (but Json::null is fine) 00356 * \remark Defaults: 00357 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults 00358 */ 00359 static void setDefaults(Json::Value* settings); 00360 /** Same as old Features::strictMode(). 00361 * \pre 'settings' != NULL (but Json::null is fine) 00362 * \remark Defaults: 00363 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode 00364 */ 00365 static void strictMode(Json::Value* settings); 00366 }; 00367 00368 /** Consume entire stream and use its begin/end. 00369 * Someday we might have a real StreamReader, but for now this 00370 * is convenient. 00371 */ 00372 bool JSON_API parseFromStream( 00373 CharReader::Factory const&, 00374 JSONCPP_ISTREAM&, 00375 Value* root, std::string* errs); 00376 00377 /** \brief Read from 'sin' into 'root'. 00378 00379 Always keep comments from the input JSON. 00380 00381 This can be used to read a file into a particular sub-object. 00382 For example: 00383 \code 00384 Json::Value root; 00385 cin >> root["dir"]["file"]; 00386 cout << root; 00387 \endcode 00388 Result: 00389 \verbatim 00390 { 00391 "dir": { 00392 "file": { 00393 // The input stream JSON would be nested here. 00394 } 00395 } 00396 } 00397 \endverbatim 00398 \throw std::exception on parse error. 00399 \see Json::operator<<() 00400 */ 00401 JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&); 00402 00403 } // namespace Json 00404 00405 #pragma pack(pop) 00406 00407 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 00408 #pragma warning(pop) 00409 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) 00410 00411 #endif // CPPTL_JSON_READER_H_INCLUDED
Generated on Tue Jul 12 2022 21:24:54 by
1.7.2