mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
This change refactors the codebase to use the "east const convention", and adds a clang-format rule to follow this convention.
254 lines
6.7 KiB
C++
254 lines
6.7 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of rippled: https://github.com/ripple/rippled
|
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef RIPPLE_JSON_JSON_READER_H_INCLUDED
|
|
#define RIPPLE_JSON_JSON_READER_H_INCLUDED
|
|
|
|
#define CPPTL_JSON_READER_H_INCLUDED
|
|
|
|
#include <xrpl/json/json_forwards.h>
|
|
#include <xrpl/json/json_value.h>
|
|
|
|
#include <boost/asio/buffer.hpp>
|
|
|
|
#include <stack>
|
|
|
|
namespace Json {
|
|
|
|
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
|
|
* Value.
|
|
*
|
|
*/
|
|
class Reader
|
|
{
|
|
public:
|
|
using Char = char;
|
|
using Location = Char const*;
|
|
|
|
/** \brief Constructs a Reader allowing all features
|
|
* for parsing.
|
|
*/
|
|
Reader() = default;
|
|
|
|
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
|
|
* document. \param document UTF-8 encoded string containing the document to
|
|
* read. \param root [out] Contains the root value of the document if it was
|
|
* successfully parsed.
|
|
* \return \c true if the document was successfully parsed, \c false if an
|
|
* error occurred.
|
|
*/
|
|
bool
|
|
parse(std::string const& document, Value& root);
|
|
|
|
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
|
|
* document. \param document UTF-8 encoded string containing the document to
|
|
* read. \param root [out] Contains the root value of the document if it was
|
|
* successfully parsed.
|
|
* \return \c true if the document was successfully parsed, \c false if an
|
|
* error occurred.
|
|
*/
|
|
bool
|
|
parse(char const* beginDoc, char const* endDoc, Value& root);
|
|
|
|
/// \brief Parse from input stream.
|
|
/// \see Json::operator>>(std::istream&, Json::Value&).
|
|
bool
|
|
parse(std::istream& is, Value& root);
|
|
|
|
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> buffer
|
|
* sequence. \param root [out] Contains the root value of the document if it
|
|
* was successfully parsed. \param UTF-8 encoded buffer sequence. \return \c
|
|
* true if the buffer was successfully parsed, \c false if an error
|
|
* occurred.
|
|
*/
|
|
template <class BufferSequence>
|
|
bool
|
|
parse(Value& root, BufferSequence const& bs);
|
|
|
|
/** \brief Returns a user friendly string that list errors in the parsed
|
|
* document. \return Formatted error message with the list of errors with
|
|
* their location in the parsed document. An empty string is returned if no
|
|
* error occurred during parsing.
|
|
*/
|
|
std::string
|
|
getFormatedErrorMessages() const;
|
|
|
|
static constexpr unsigned nest_limit{25};
|
|
|
|
private:
|
|
enum TokenType {
|
|
tokenEndOfStream = 0,
|
|
tokenObjectBegin,
|
|
tokenObjectEnd,
|
|
tokenArrayBegin,
|
|
tokenArrayEnd,
|
|
tokenString,
|
|
tokenInteger,
|
|
tokenDouble,
|
|
tokenTrue,
|
|
tokenFalse,
|
|
tokenNull,
|
|
tokenArraySeparator,
|
|
tokenMemberSeparator,
|
|
tokenComment,
|
|
tokenError
|
|
};
|
|
|
|
class Token
|
|
{
|
|
public:
|
|
explicit Token() = default;
|
|
|
|
TokenType type_;
|
|
Location start_;
|
|
Location end_;
|
|
};
|
|
|
|
class ErrorInfo
|
|
{
|
|
public:
|
|
explicit ErrorInfo() = default;
|
|
|
|
Token token_;
|
|
std::string message_;
|
|
Location extra_;
|
|
};
|
|
|
|
using Errors = std::deque<ErrorInfo>;
|
|
|
|
bool
|
|
expectToken(TokenType type, Token& token, char const* message);
|
|
bool
|
|
readToken(Token& token);
|
|
void
|
|
skipSpaces();
|
|
bool
|
|
match(Location pattern, int patternLength);
|
|
bool
|
|
readComment();
|
|
bool
|
|
readCStyleComment();
|
|
bool
|
|
readCppStyleComment();
|
|
bool
|
|
readString();
|
|
Reader::TokenType
|
|
readNumber();
|
|
bool
|
|
readValue(unsigned depth);
|
|
bool
|
|
readObject(Token& token, unsigned depth);
|
|
bool
|
|
readArray(Token& token, unsigned depth);
|
|
bool
|
|
decodeNumber(Token& token);
|
|
bool
|
|
decodeString(Token& token);
|
|
bool
|
|
decodeString(Token& token, std::string& decoded);
|
|
bool
|
|
decodeDouble(Token& token);
|
|
bool
|
|
decodeUnicodeCodePoint(
|
|
Token& token,
|
|
Location& current,
|
|
Location end,
|
|
unsigned int& unicode);
|
|
bool
|
|
decodeUnicodeEscapeSequence(
|
|
Token& token,
|
|
Location& current,
|
|
Location end,
|
|
unsigned int& unicode);
|
|
bool
|
|
addError(std::string const& message, Token& token, Location extra = 0);
|
|
bool
|
|
recoverFromError(TokenType skipUntilToken);
|
|
bool
|
|
addErrorAndRecover(
|
|
std::string const& message,
|
|
Token& token,
|
|
TokenType skipUntilToken);
|
|
void
|
|
skipUntilSpace();
|
|
Value&
|
|
currentValue();
|
|
Char
|
|
getNextChar();
|
|
void
|
|
getLocationLineAndColumn(Location location, int& line, int& column) const;
|
|
std::string
|
|
getLocationLineAndColumn(Location location) const;
|
|
void
|
|
skipCommentTokens(Token& token);
|
|
|
|
using Nodes = std::stack<Value*>;
|
|
Nodes nodes_;
|
|
Errors errors_;
|
|
std::string document_;
|
|
Location begin_;
|
|
Location end_;
|
|
Location current_;
|
|
Location lastValueEnd_;
|
|
Value* lastValue_;
|
|
};
|
|
|
|
template <class BufferSequence>
|
|
bool
|
|
Reader::parse(Value& root, BufferSequence const& bs)
|
|
{
|
|
using namespace boost::asio;
|
|
std::string s;
|
|
s.reserve(buffer_size(bs));
|
|
for (auto const& b : bs)
|
|
s.append(buffer_cast<char const*>(b), buffer_size(b));
|
|
return parse(s, root);
|
|
}
|
|
|
|
/** \brief Read from 'sin' into 'root'.
|
|
|
|
Always keep comments from the input JSON.
|
|
|
|
This can be used to read a file into a particular sub-object.
|
|
For example:
|
|
\code
|
|
Json::Value root;
|
|
cin >> root["dir"]["file"];
|
|
cout << root;
|
|
\endcode
|
|
Result:
|
|
\verbatim
|
|
{
|
|
"dir": {
|
|
"file": {
|
|
// The input stream JSON would be nested here.
|
|
}
|
|
}
|
|
}
|
|
\endverbatim
|
|
\throw std::exception on parse error.
|
|
\see Json::operator<<()
|
|
*/
|
|
std::istream&
|
|
operator>>(std::istream&, Value&);
|
|
|
|
} // namespace Json
|
|
|
|
#endif // CPPTL_JSON_READER_H_INCLUDED
|