summaryrefslogtreecommitdiffstats
path: root/include/json/reader.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/json/reader.h')
-rw-r--r--include/json/reader.h177
1 files changed, 156 insertions, 21 deletions
diff --git a/include/json/reader.h b/include/json/reader.h
index 98814d5..82859fd 100644
--- a/include/json/reader.h
+++ b/include/json/reader.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2010 Baptiste Lepilleur
+// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -14,6 +14,7 @@
#include <iosfwd>
#include <stack>
#include <string>
+#include <istream>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
@@ -22,13 +23,16 @@
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma pack(push, 8)
+
namespace Json {
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
*Value.
*
+ * \deprecated Use CharReader and CharReaderBuilder.
*/
-class JSON_API Reader {
+class JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") JSON_API Reader {
public:
typedef char Char;
typedef const Char* Location;
@@ -40,9 +44,9 @@ public:
*
*/
struct StructuredError {
- size_t offset_start;
- size_t offset_limit;
- std::string message;
+ ptrdiff_t offset_start;
+ ptrdiff_t offset_limit;
+ JSONCPP_STRING message;
};
/** \brief Constructs a Reader allowing all features
@@ -78,7 +82,7 @@ public:
document to read.
* \param endDoc Pointer on the end of the UTF-8 encoded string of the
document to read.
- \ Must be >= beginDoc.
+ * Must be >= beginDoc.
* \param root [out] Contains the root value of the document if it was
* successfully parsed.
* \param collectComments \c true to collect comment and allow writing them
@@ -97,7 +101,7 @@ public:
/// \brief Parse from input stream.
/// \see Json::operator>>(std::istream&, Json::Value&).
- bool parse(std::istream& is, Value& root, bool collectComments = true);
+ bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
/** \brief Returns a user friendly string that list errors in the parsed
* document.
@@ -108,8 +112,8 @@ public:
* during parsing.
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/
- JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
- std::string getFormatedErrorMessages() const;
+ JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
+ JSONCPP_STRING getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed
* document.
@@ -119,7 +123,7 @@ public:
* occurred
* during parsing.
*/
- std::string getFormattedErrorMessages() const;
+ JSONCPP_STRING getFormattedErrorMessages() const;
/** \brief Returns a vector of structured erros encounted while parsing.
* \return A (possibly empty) vector of StructuredError objects. Currently
@@ -136,7 +140,7 @@ public:
* \return \c true if the error was successfully added, \c false if the
* Value offset exceeds the document size.
*/
- bool pushError(const Value& value, const std::string& message);
+ bool pushError(const Value& value, const JSONCPP_STRING& message);
/** \brief Add a semantic error message with extra context.
* \param value JSON Value location associated with the error
@@ -145,7 +149,7 @@ public:
* \return \c true if the error was successfully added, \c false if either
* Value offset exceeds the document size.
*/
- bool pushError(const Value& value, const std::string& message, const Value& extra);
+ bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
/** \brief Return whether there are any errors.
* \return \c true if there are no errors to report \c false if
@@ -181,13 +185,12 @@ private:
class ErrorInfo {
public:
Token token_;
- std::string message_;
+ JSONCPP_STRING message_;
Location extra_;
};
typedef std::deque<ErrorInfo> Errors;
- bool expectToken(TokenType type, Token& token, const char* message);
bool readToken(Token& token);
void skipSpaces();
bool match(Location pattern, int patternLength);
@@ -202,7 +205,7 @@ private:
bool decodeNumber(Token& token);
bool decodeNumber(Token& token, Value& decoded);
bool decodeString(Token& token);
- bool decodeString(Token& token, std::string& decoded);
+ bool decodeString(Token& token, JSONCPP_STRING& decoded);
bool decodeDouble(Token& token);
bool decodeDouble(Token& token, Value& decoded);
bool decodeUnicodeCodePoint(Token& token,
@@ -213,9 +216,9 @@ private:
Location& current,
Location end,
unsigned int& unicode);
- bool addError(const std::string& message, Token& token, Location extra = 0);
+ bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
bool recoverFromError(TokenType skipUntilToken);
- bool addErrorAndRecover(const std::string& message,
+ bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
TokenType skipUntilToken);
void skipUntilSpace();
@@ -223,24 +226,154 @@ private:
Char getNextChar();
void
getLocationLineAndColumn(Location location, int& line, int& column) const;
- std::string getLocationLineAndColumn(Location location) const;
+ JSONCPP_STRING getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement);
void skipCommentTokens(Token& token);
+ static bool containsNewLine(Location begin, Location end);
+ static JSONCPP_STRING normalizeEOL(Location begin, Location end);
+
typedef std::stack<Value*> Nodes;
Nodes nodes_;
Errors errors_;
- std::string document_;
+ JSONCPP_STRING document_;
Location begin_;
Location end_;
Location current_;
Location lastValueEnd_;
Value* lastValue_;
- std::string commentsBefore_;
+ JSONCPP_STRING commentsBefore_;
Features features_;
bool collectComments_;
+}; // Reader
+
+/** Interface for reading JSON from a char array.
+ */
+class JSON_API CharReader {
+public:
+ virtual ~CharReader() {}
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
+ document.
+ * The document must be a UTF-8 encoded string containing the document to read.
+ *
+ * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
+ document to read.
+ * \param endDoc Pointer on the end of the UTF-8 encoded string of the
+ document to read.
+ * Must be >= beginDoc.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param errs [out] Formatted error messages (if not NULL)
+ * a user friendly string that lists errors in the parsed
+ * document.
+ * \return \c true if the document was successfully parsed, \c false if an
+ error occurred.
+ */
+ virtual bool parse(
+ char const* beginDoc, char const* endDoc,
+ Value* root, JSONCPP_STRING* errs) = 0;
+
+ class JSON_API Factory {
+ public:
+ virtual ~Factory() {}
+ /** \brief Allocate a CharReader via operator new().
+ * \throw std::exception if something goes wrong (e.g. invalid settings)
+ */
+ virtual CharReader* newCharReader() const = 0;
+ }; // Factory
+}; // CharReader
+
+/** \brief Build a CharReader implementation.
+
+Usage:
+\code
+ using namespace Json;
+ CharReaderBuilder builder;
+ builder["collectComments"] = false;
+ Value value;
+ JSONCPP_STRING errs;
+ bool ok = parseFromStream(builder, std::cin, &value, &errs);
+\endcode
+*/
+class JSON_API CharReaderBuilder : public CharReader::Factory {
+public:
+ // Note: We use a Json::Value so that we can add data-members to this class
+ // without a major version bump.
+ /** Configuration of this builder.
+ These are case-sensitive.
+ Available settings (case-sensitive):
+ - `"collectComments": false or true`
+ - true to collect comment and allow writing them
+ back during serialization, false to discard comments.
+ This parameter is ignored if allowComments is false.
+ - `"allowComments": false or true`
+ - true if comments are allowed.
+ - `"strictRoot": false or true`
+ - true if root must be either an array or an object value
+ - `"allowDroppedNullPlaceholders": false or true`
+ - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
+ - `"allowNumericKeys": false or true`
+ - true if numeric object keys are allowed.
+ - `"allowSingleQuotes": false or true`
+ - true if '' are allowed for strings (both keys and values)
+ - `"stackLimit": integer`
+ - Exceeding stackLimit (recursive depth of `readValue()`) will
+ cause an exception.
+ - This is a security issue (seg-faults caused by deeply nested JSON),
+ so the default is low.
+ - `"failIfExtra": false or true`
+ - If true, `parse()` returns false when extra non-whitespace trails
+ the JSON value in the input string.
+ - `"rejectDupKeys": false or true`
+ - If true, `parse()` returns false when a key is duplicated within an object.
+ - `"allowSpecialFloats": false or true`
+ - If true, special float values (NaNs and infinities) are allowed
+ and their values are lossfree restorable.
+
+ You can examine 'settings_` yourself
+ to see the defaults. You can also write and read them just like any
+ JSON Value.
+ \sa setDefaults()
+ */
+ Json::Value settings_;
+
+ CharReaderBuilder();
+ ~CharReaderBuilder() JSONCPP_OVERRIDE;
+
+ CharReader* newCharReader() const JSONCPP_OVERRIDE;
+
+ /** \return true if 'settings' are legal and consistent;
+ * otherwise, indicate bad settings via 'invalid'.
+ */
+ bool validate(Json::Value* invalid) const;
+
+ /** A simple way to update a specific setting.
+ */
+ Value& operator[](JSONCPP_STRING key);
+
+ /** Called by ctor, but you can use this to reset settings_.
+ * \pre 'settings' != NULL (but Json::null is fine)
+ * \remark Defaults:
+ * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
+ */
+ static void setDefaults(Json::Value* settings);
+ /** Same as old Features::strictMode().
+ * \pre 'settings' != NULL (but Json::null is fine)
+ * \remark Defaults:
+ * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
+ */
+ static void strictMode(Json::Value* settings);
};
+/** Consume entire stream and use its begin/end.
+ * Someday we might have a real StreamReader, but for now this
+ * is convenient.
+ */
+bool JSON_API parseFromStream(
+ CharReader::Factory const&,
+ JSONCPP_ISTREAM&,
+ Value* root, std::string* errs);
+
/** \brief Read from 'sin' into 'root'.
Always keep comments from the input JSON.
@@ -265,10 +398,12 @@ private:
\throw std::exception on parse error.
\see Json::operator<<()
*/
-JSON_API std::istream& operator>>(std::istream&, Value&);
+JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
} // namespace Json
+#pragma pack(pop)
+
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)