diff options
Diffstat (limited to 'Utilities/cmjsoncpp/src/lib_json/json_reader.cpp')
-rw-r--r-- | Utilities/cmjsoncpp/src/lib_json/json_reader.cpp | 2029 |
1 files changed, 961 insertions, 1068 deletions
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp index 8362fc4..8291cc6 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp @@ -2,88 +2,74 @@ // Copyright (C) 2016 InfoTeCS JSC. All rights reserved. // 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 +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #if !defined(JSON_IS_AMALGAMATION) -# include <json/assertions.h> -# include <json/reader.h> -# include <json/value.h> - -# include "json_tool.h" +#include <json/assertions.h> +#include <json/reader.h> +#include <json/value.h> +#include "json_tool.h" #endif // if !defined(JSON_IS_AMALGAMATION) -#include <istream> -#include <limits> -#include <memory> -#include <set> -#include <sstream> #include <utility> - -#include <assert.h> #include <stdio.h> +#include <assert.h> #include <string.h> +#include <istream> +#include <sstream> +#include <memory> +#include <set> +#include <limits> #if defined(_MSC_VER) -# if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && \ - _MSC_VER >= 1500 // VC++ 9.0 and above -# define snprintf sprintf_s -# elif _MSC_VER >= 1900 // VC++ 14.0 and above -# define snprintf std::snprintf -# else -# define snprintf _snprintf -# endif +#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above +#define snprintf sprintf_s +#elif _MSC_VER >= 1900 // VC++ 14.0 and above +#define snprintf std::snprintf +#else +#define snprintf _snprintf +#endif #elif defined(__ANDROID__) || defined(__QNXNTO__) -# define snprintf snprintf +#define snprintf snprintf #elif __cplusplus >= 201103L -# if !defined(__MINGW32__) && !defined(__CYGWIN__) -# define snprintf std::snprintf -# endif +#if !defined(__MINGW32__) && !defined(__CYGWIN__) +#define snprintf std::snprintf +#endif #endif #if defined(__QNXNTO__) -# define sscanf std::sscanf +#define sscanf std::sscanf #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 // Disable warning about strdup being deprecated. -# pragma warning(disable : 4996) +#pragma warning(disable : 4996) #endif -// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile -// time to change the stack limit +// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit #if !defined(JSONCPP_DEPRECATED_STACK_LIMIT) -# define JSONCPP_DEPRECATED_STACK_LIMIT 1000 +#define JSONCPP_DEPRECATED_STACK_LIMIT 1000 #endif -static size_t const stackLimit_g = - JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() +static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) typedef std::unique_ptr<CharReader> CharReaderPtr; #else -typedef std::auto_ptr<CharReader> CharReaderPtr; +typedef std::auto_ptr<CharReader> CharReaderPtr; #endif // Implementation of class Features // //////////////////////////////// Features::Features() - : allowComments_(true) - , strictRoot_(false) - , allowDroppedNullPlaceholders_(false) - , allowNumericKeys_(false) -{ -} + : allowComments_(true), strictRoot_(false), + allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} -Features Features::all() -{ - return Features(); -} +Features Features::all() { return Features(); } -Features Features::strictMode() -{ +Features Features::strictMode() { Features features; features.allowComments_ = false; features.strictRoot_ = true; @@ -95,8 +81,7 @@ Features Features::strictMode() // Implementation of class Reader // //////////////////////////////// -bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) -{ +bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { for (; begin < end; ++begin) if (*begin == '\n' || *begin == '\r') return true; @@ -107,44 +92,24 @@ bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) // ////////////////////////////////////////////////////////////////// Reader::Reader() - : errors_() - , document_() - , begin_() - , end_() - , current_() - , lastValueEnd_() - , lastValue_() - , commentsBefore_() - , features_(Features::all()) - , collectComments_() -{ -} + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(Features::all()), + collectComments_() {} Reader::Reader(const Features& features) - : errors_() - , document_() - , begin_() - , end_() - , current_() - , lastValueEnd_() - , lastValue_() - , commentsBefore_() - , features_(features) - , collectComments_() -{ + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(features), collectComments_() { } -bool Reader::parse(const std::string& document, Value& root, - bool collectComments) -{ - this->document_.assign(document.begin(), document.end()); - const char* begin = this->document_.c_str(); - const char* end = begin + this->document_.length(); - return this->parse(begin, end, root, collectComments); +bool +Reader::parse(const std::string& document, Value& root, bool collectComments) { + document_.assign(document.begin(), document.end()); + const char* begin = document_.c_str(); + const char* end = begin + document_.length(); + return parse(begin, end, root, collectComments); } -bool Reader::parse(std::istream& sin, Value& root, bool collectComments) -{ +bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { // std::istream_iterator<char> begin(sin); // std::istream_iterator<char> end; // Those would allow streamed input from a file, if parse() were a @@ -154,263 +119,257 @@ bool Reader::parse(std::istream& sin, Value& root, bool collectComments) // create an extra copy. JSONCPP_STRING doc; std::getline(sin, doc, (char)EOF); - return this->parse(doc.data(), doc.data() + doc.size(), root, - collectComments); + return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } -bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root, - bool collectComments) -{ - if (!this->features_.allowComments_) { +bool Reader::parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments) { + if (!features_.allowComments_) { collectComments = false; } - this->begin_ = beginDoc; - this->end_ = endDoc; - this->collectComments_ = collectComments; - this->current_ = this->begin_; - this->lastValueEnd_ = 0; - this->lastValue_ = 0; - this->commentsBefore_.clear(); - this->errors_.clear(); - while (!this->nodes_.empty()) - this->nodes_.pop(); - this->nodes_.push(&root); - - bool successful = this->readValue(); + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = 0; + lastValue_ = 0; + commentsBefore_.clear(); + errors_.clear(); + while (!nodes_.empty()) + nodes_.pop(); + nodes_.push(&root); + + bool successful = readValue(); Token token; - this->skipCommentTokens(token); - if (this->collectComments_ && !this->commentsBefore_.empty()) - root.setComment(this->commentsBefore_, commentAfter); - if (this->features_.strictRoot_) { + skipCommentTokens(token); + if (collectComments_ && !commentsBefore_.empty()) + root.setComment(commentsBefore_, commentAfter); + if (features_.strictRoot_) { if (!root.isArray() && !root.isObject()) { - // Set error location to start of doc, ideally should be first token - // found in doc + // Set error location to start of doc, ideally should be first token found + // in doc token.type_ = tokenError; token.start_ = beginDoc; token.end_ = endDoc; - this->addError( - "A valid JSON document must be either an array or an object value.", - token); + addError( + "A valid JSON document must be either an array or an object value.", + token); return false; } } return successful; } -bool Reader::readValue() -{ +bool Reader::readValue() { // readValue() may call itself only if it calls readObject() or ReadArray(). - // These methods execute nodes_.push() just before and nodes_.pop)() just - // after calling readValue(). parse() executes one nodes_.push(), so > - // instead of >=. - if (this->nodes_.size() > stackLimit_g) - throwRuntimeError("Exceeded stackLimit in readValue()."); + // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue(). + // parse() executes one nodes_.push(), so > instead of >=. + if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - this->skipCommentTokens(token); + skipCommentTokens(token); bool successful = true; - if (this->collectComments_ && !this->commentsBefore_.empty()) { - this->currentValue().setComment(this->commentsBefore_, commentBefore); - this->commentsBefore_.clear(); + if (collectComments_ && !commentsBefore_.empty()) { + currentValue().setComment(commentsBefore_, commentBefore); + commentsBefore_.clear(); } switch (token.type_) { - case tokenObjectBegin: - successful = this->readObject(token); - this->currentValue().setOffsetLimit(this->current_ - this->begin_); - break; - case tokenArrayBegin: - successful = this->readArray(token); - this->currentValue().setOffsetLimit(this->current_ - this->begin_); - break; - case tokenNumber: - successful = this->decodeNumber(token); - break; - case tokenString: - successful = this->decodeString(token); - break; - case tokenTrue: { - Value v(true); - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenFalse: { - Value v(false); - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenNull: { + case tokenObjectBegin: + successful = readObject(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenArrayBegin: + successful = readArray(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenNumber: + successful = decodeNumber(token); + break; + case tokenString: + successful = decodeString(token); + break; + case tokenTrue: + { + Value v(true); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenFalse: + { + Value v(false); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenNull: + { + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; Value v; - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenArraySeparator: - case tokenObjectEnd: - case tokenArrayEnd: - if (this->features_.allowDroppedNullPlaceholders_) { - // "Un-read" the current token and mark the current value as a null - // token. - this->current_--; - Value v; - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(this->current_ - this->begin_ - 1); - this->currentValue().setOffsetLimit(this->current_ - this->begin_); - break; - } // Else, fall through... - default: - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - return this->addError("Syntax error: value, object or array expected.", - token); + currentValue().swapPayload(v); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } // Else, fall through... + default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return addError("Syntax error: value, object or array expected.", token); } - if (this->collectComments_) { - this->lastValueEnd_ = this->current_; - this->lastValue_ = &this->currentValue(); + if (collectComments_) { + lastValueEnd_ = current_; + lastValue_ = ¤tValue(); } return successful; } -void Reader::skipCommentTokens(Token& token) -{ - if (this->features_.allowComments_) { +void Reader::skipCommentTokens(Token& token) { + if (features_.allowComments_) { do { - this->readToken(token); + readToken(token); } while (token.type_ == tokenComment); } else { - this->readToken(token); + readToken(token); } } -bool Reader::readToken(Token& token) -{ - this->skipSpaces(); - token.start_ = this->current_; - Char c = this->getNextChar(); +bool Reader::readToken(Token& token) { + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); bool ok = true; switch (c) { - case '{': - token.type_ = tokenObjectBegin; - break; - case '}': - token.type_ = tokenObjectEnd; - break; - case '[': - token.type_ = tokenArrayBegin; - break; - case ']': - token.type_ = tokenArrayEnd; - break; - case '"': - token.type_ = tokenString; - ok = this->readString(); - break; - case '/': - token.type_ = tokenComment; - ok = this->readComment(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - token.type_ = tokenNumber; - this->readNumber(); - break; - case 't': - token.type_ = tokenTrue; - ok = this->match("rue", 3); - break; - case 'f': - token.type_ = tokenFalse; - ok = this->match("alse", 4); - break; - case 'n': - token.type_ = tokenNull; - ok = this->match("ull", 3); - break; - case ',': - token.type_ = tokenArraySeparator; - break; - case ':': - token.type_ = tokenMemberSeparator; - break; - case 0: - token.type_ = tokenEndOfStream; - break; - default: - ok = false; - break; + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + token.type_ = tokenNumber; + readNumber(); + break; + case 't': + token.type_ = tokenTrue; + ok = match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = match("ull", 3); + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; } if (!ok) token.type_ = tokenError; - token.end_ = this->current_; + token.end_ = current_; return true; } -void Reader::skipSpaces() -{ - while (this->current_ != this->end_) { - Char c = *this->current_; +void Reader::skipSpaces() { + while (current_ != end_) { + Char c = *current_; if (c == ' ' || c == '\t' || c == '\r' || c == '\n') - ++this->current_; + ++current_; else break; } } -bool Reader::match(Location pattern, int patternLength) -{ - if (this->end_ - this->current_ < patternLength) +bool Reader::match(Location pattern, int patternLength) { + if (end_ - current_ < patternLength) return false; int index = patternLength; while (index--) - if (this->current_[index] != pattern[index]) + if (current_[index] != pattern[index]) return false; - this->current_ += patternLength; + current_ += patternLength; return true; } -bool Reader::readComment() -{ - Location commentBegin = this->current_ - 1; - Char c = this->getNextChar(); +bool Reader::readComment() { + Location commentBegin = current_ - 1; + Char c = getNextChar(); bool successful = false; if (c == '*') - successful = this->readCStyleComment(); + successful = readCStyleComment(); else if (c == '/') - successful = this->readCppStyleComment(); + successful = readCppStyleComment(); if (!successful) return false; - if (this->collectComments_) { + if (collectComments_) { CommentPlacement placement = commentBefore; - if (this->lastValueEnd_ && - !containsNewLine(this->lastValueEnd_, commentBegin)) { - if (c != '*' || !containsNewLine(commentBegin, this->current_)) + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, current_)) placement = commentAfterOnSameLine; } - this->addComment(commentBegin, this->current_, placement); + addComment(commentBegin, current_, placement); } return true; } -JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, - Reader::Location end) -{ +JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end) { JSONCPP_STRING normalized; normalized.reserve(static_cast<size_t>(end - begin)); Reader::Location current = begin; @@ -418,8 +377,8 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, char c = *current++; if (c == '\r') { if (current != end && *current == '\n') - // convert dos EOL - ++current; + // convert dos EOL + ++current; // convert Mac EOL normalized += '\n'; } else { @@ -429,39 +388,36 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, return normalized; } -void Reader::addComment(Location begin, Location end, - CommentPlacement placement) -{ - assert(this->collectComments_); +void +Reader::addComment(Location begin, Location end, CommentPlacement placement) { + assert(collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(this->lastValue_ != 0); - this->lastValue_->setComment(normalized, placement); + assert(lastValue_ != 0); + lastValue_->setComment(normalized, placement); } else { - this->commentsBefore_ += normalized; + commentsBefore_ += normalized; } } -bool Reader::readCStyleComment() -{ - while ((this->current_ + 1) < this->end_) { - Char c = this->getNextChar(); - if (c == '*' && *this->current_ == '/') +bool Reader::readCStyleComment() { + while ((current_ + 1) < end_) { + Char c = getNextChar(); + if (c == '*' && *current_ == '/') break; } - return this->getNextChar() == '/'; + return getNextChar() == '/'; } -bool Reader::readCppStyleComment() -{ - while (this->current_ != this->end_) { - Char c = this->getNextChar(); +bool Reader::readCppStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); if (c == '\n') break; if (c == '\r') { // Consume DOS EOL. It will be normalized in addComment. - if (this->current_ != this->end_ && *this->current_ == '\n') - this->getNextChar(); + if (current_ != end_ && *current_ == '\n') + getNextChar(); // Break on Moc OS 9 EOL. break; } @@ -469,132 +425,127 @@ bool Reader::readCppStyleComment() return true; } -void Reader::readNumber() -{ - const char* p = this->current_; +void Reader::readNumber() { + const char *p = current_; char c = '0'; // stopgap for already consumed character // integral part while (c >= '0' && c <= '9') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; // fractional part if (c == '.') { - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; } // exponential part if (c == 'e' || c == 'E') { - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; if (c == '+' || c == '-') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; } } -bool Reader::readString() -{ +bool Reader::readString() { Char c = '\0'; - while (this->current_ != this->end_) { - c = this->getNextChar(); + while (current_ != end_) { + c = getNextChar(); if (c == '\\') - this->getNextChar(); + getNextChar(); else if (c == '"') break; } return c == '"'; } -bool Reader::readObject(Token& tokenStart) -{ +bool Reader::readObject(Token& tokenStart) { Token tokenName; JSONCPP_STRING name; Value init(objectValue); - this->currentValue().swapPayload(init); - this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); - while (this->readToken(tokenName)) { + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + while (readToken(tokenName)) { bool initialTokenOk = true; while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = this->readToken(tokenName); + initialTokenOk = readToken(tokenName); if (!initialTokenOk) break; if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object return true; name.clear(); if (tokenName.type_ == tokenString) { - if (!this->decodeString(tokenName, name)) - return this->recoverFromError(tokenObjectEnd); - } else if (tokenName.type_ == tokenNumber && - this->features_.allowNumericKeys_) { + if (!decodeString(tokenName, name)) + return recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { Value numberName; - if (!this->decodeNumber(tokenName, numberName)) - return this->recoverFromError(tokenObjectEnd); + if (!decodeNumber(tokenName, numberName)) + return recoverFromError(tokenObjectEnd); name = JSONCPP_STRING(numberName.asCString()); } else { break; } Token colon; - if (!this->readToken(colon) || colon.type_ != tokenMemberSeparator) { - return this->addErrorAndRecover("Missing ':' after object member name", - colon, tokenObjectEnd); + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover( + "Missing ':' after object member name", colon, tokenObjectEnd); } - Value& value = this->currentValue()[name]; - this->nodes_.push(&value); - bool ok = this->readValue(); - this->nodes_.pop(); + Value& value = currentValue()[name]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); if (!ok) // error already set - return this->recoverFromError(tokenObjectEnd); + return recoverFromError(tokenObjectEnd); Token comma; - if (!this->readToken(comma) || + if (!readToken(comma) || (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && comma.type_ != tokenComment)) { - return this->addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + return addErrorAndRecover( + "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } bool finalizeTokenOk = true; while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = this->readToken(comma); + finalizeTokenOk = readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } - return this->addErrorAndRecover("Missing '}' or object member name", - tokenName, tokenObjectEnd); + return addErrorAndRecover( + "Missing '}' or object member name", tokenName, tokenObjectEnd); } -bool Reader::readArray(Token& tokenStart) -{ +bool Reader::readArray(Token& tokenStart) { Value init(arrayValue); - this->currentValue().swapPayload(init); - this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); - this->skipSpaces(); - if (this->current_ != this->end_ && *this->current_ == ']') // empty array + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + skipSpaces(); + if (current_ != end_ && *current_ == ']') // empty array { Token endArray; - this->readToken(endArray); + readToken(endArray); return true; } int index = 0; for (;;) { - Value& value = this->currentValue()[index++]; - this->nodes_.push(&value); - bool ok = this->readValue(); - this->nodes_.pop(); + Value& value = currentValue()[index++]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); if (!ok) // error already set - return this->recoverFromError(tokenArrayEnd); + return recoverFromError(tokenArrayEnd); Token token; // Accept Comment after last item in the array. - ok = this->readToken(token); + ok = readToken(token); while (token.type_ == tokenComment && ok) { - ok = this->readToken(token); + ok = readToken(token); } bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { - return this->addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + return addErrorAndRecover( + "Missing ',' or ']' in array declaration", token, tokenArrayEnd); } if (token.type_ == tokenArrayEnd) break; @@ -602,19 +553,17 @@ bool Reader::readArray(Token& tokenStart) return true; } -bool Reader::decodeNumber(Token& token) -{ +bool Reader::decodeNumber(Token& token) { Value decoded; - if (!this->decodeNumber(token, decoded)) + if (!decodeNumber(token, decoded)) return false; - this->currentValue().swapPayload(decoded); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return true; } -bool Reader::decodeNumber(Token& token, Value& decoded) -{ +bool Reader::decodeNumber(Token& token, Value& decoded) { // Attempts to parse the number as an integer. If the number is // larger than the maximum supported value of an integer then // we decode the number as a double. @@ -622,17 +571,16 @@ bool Reader::decodeNumber(Token& token, Value& decoded) bool isNegative = *current == '-'; if (isNegative) ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of - // them. - Value::LargestUInt maxIntegerValue = isNegative - ? Value::LargestUInt(Value::maxLargestInt) + 1 - : Value::maxLargestUInt; + // TODO: Help the compiler do the div and mod at compile time or get rid of them. + Value::LargestUInt maxIntegerValue = + isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1 + : Value::maxLargestUInt; Value::LargestUInt threshold = maxIntegerValue / 10; Value::LargestUInt value = 0; while (current < token.end_) { Char c = *current++; if (c < '0' || c > '9') - return this->decodeDouble(token, decoded); + return decodeDouble(token, decoded); Value::UInt digit(static_cast<Value::UInt>(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If @@ -641,7 +589,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) // Otherwise treat this number as a double to avoid overflow. if (value > threshold || current != token.end_ || digit > maxIntegerValue % 10) { - return this->decodeDouble(token, decoded); + return decodeDouble(token, decoded); } } value = value * 10 + digit; @@ -657,44 +605,40 @@ bool Reader::decodeNumber(Token& token, Value& decoded) return true; } -bool Reader::decodeDouble(Token& token) -{ +bool Reader::decodeDouble(Token& token) { Value decoded; - if (!this->decodeDouble(token, decoded)) + if (!decodeDouble(token, decoded)) return false; - this->currentValue().swapPayload(decoded); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return true; } -bool Reader::decodeDouble(Token& token, Value& decoded) -{ +bool Reader::decodeDouble(Token& token, Value& decoded) { double value = 0; JSONCPP_STRING buffer(token.start_, token.end_); JSONCPP_ISTRINGSTREAM is(buffer); if (!(is >> value)) - return this->addError("'" + JSONCPP_STRING(token.start_, token.end_) + - "' is not a number.", - token); + return addError("'" + JSONCPP_STRING(token.start_, token.end_) + + "' is not a number.", + token); decoded = value; return true; } -bool Reader::decodeString(Token& token) -{ +bool Reader::decodeString(Token& token) { JSONCPP_STRING decoded_string; - if (!this->decodeString(token, decoded_string)) + if (!decodeString(token, decoded_string)) return false; Value decoded(decoded_string); - this->currentValue().swapPayload(decoded); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return true; } -bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) -{ +bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) { decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -704,43 +648,41 @@ bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) break; else if (c == '\\') { if (current == end) - return this->addError("Empty escape sequence in string", token, - current); + return addError("Empty escape sequence in string", token, current); Char escape = *current++; switch (escape) { - case '"': - decoded += '"'; - break; - case '/': - decoded += '/'; - break; - case '\\': - decoded += '\\'; - break; - case 'b': - decoded += '\b'; - break; - case 'f': - decoded += '\f'; - break; - case 'n': - decoded += '\n'; - break; - case 'r': - decoded += '\r'; - break; - case 't': - decoded += '\t'; - break; - case 'u': { - unsigned int unicode; - if (!this->decodeUnicodeCodePoint(token, current, end, unicode)) - return false; - decoded += codePointToUTF8(unicode); - } break; - default: - return this->addError("Bad escape sequence in string", token, - current); + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return addError("Bad escape sequence in string", token, current); } } else { decoded += c; @@ -749,43 +691,44 @@ bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) return true; } -bool Reader::decodeUnicodeCodePoint(Token& token, Location& current, - Location end, unsigned int& unicode) -{ +bool Reader::decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode) { - if (!this->decodeUnicodeEscapeSequence(token, current, end, unicode)) + if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) return false; if (unicode >= 0xD800 && unicode <= 0xDBFF) { // surrogate pairs if (end - current < 6) - return this->addError( - "additional six characters expected to parse unicode surrogate pair.", - token, current); + return addError( + "additional six characters expected to parse unicode surrogate pair.", + token, + current); unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { - if (this->decodeUnicodeEscapeSequence(token, current, end, - surrogatePair)) { - unicode = - 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); } else return false; } else - return this->addError( - "expecting another \\u token to begin the second half of " - "a unicode surrogate pair", - token, current); + return addError("expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, + current); } return true; } -bool Reader::decodeUnicodeEscapeSequence(Token& token, Location& current, +bool Reader::decodeUnicodeEscapeSequence(Token& token, + Location& current, Location end, - unsigned int& ret_unicode) -{ + unsigned int& ret_unicode) { if (end - current < 4) - return this->addError( - "Bad unicode escape sequence in string: four digits expected.", token, - current); + return addError( + "Bad unicode escape sequence in string: four digits expected.", + token, + current); int unicode = 0; for (int index = 0; index < 4; ++index) { Char c = *current++; @@ -797,65 +740,60 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token, Location& current, else if (c >= 'A' && c <= 'F') unicode += c - 'A' + 10; else - return this->addError( - "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, current); + return addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, + current); } ret_unicode = static_cast<unsigned int>(unicode); return true; } -bool Reader::addError(const JSONCPP_STRING& message, Token& token, - Location extra) -{ +bool +Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = extra; - this->errors_.push_back(info); + errors_.push_back(info); return false; } -bool Reader::recoverFromError(TokenType skipUntilToken) -{ - size_t const errorCount = this->errors_.size(); +bool Reader::recoverFromError(TokenType skipUntilToken) { + size_t const errorCount = errors_.size(); Token skip; for (;;) { - if (!this->readToken(skip)) - this->errors_.resize(errorCount); // discard errors caused by recovery + if (!readToken(skip)) + errors_.resize(errorCount); // discard errors caused by recovery if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) break; } - this->errors_.resize(errorCount); + errors_.resize(errorCount); return false; } -bool Reader::addErrorAndRecover(const JSONCPP_STRING& message, Token& token, - TokenType skipUntilToken) -{ - this->addError(message, token); - return this->recoverFromError(skipUntilToken); +bool Reader::addErrorAndRecover(const JSONCPP_STRING& message, + Token& token, + TokenType skipUntilToken) { + addError(message, token); + return recoverFromError(skipUntilToken); } -Value& Reader::currentValue() -{ - return *(this->nodes_.top()); -} +Value& Reader::currentValue() { return *(nodes_.top()); } -Reader::Char Reader::getNextChar() -{ - if (this->current_ == this->end_) +Reader::Char Reader::getNextChar() { + if (current_ == end_) return 0; - return *this->current_++; + return *current_++; } -void Reader::getLocationLineAndColumn(Location location, int& line, - int& column) const -{ - Location current = this->begin_; +void Reader::getLocationLineAndColumn(Location location, + int& line, + int& column) const { + Location current = begin_; Location lastLineStart = current; line = 0; - while (current < location && current != this->end_) { + while (current < location && current != end_) { Char c = *current++; if (c == '\r') { if (*current == '\n') @@ -872,96 +810,91 @@ void Reader::getLocationLineAndColumn(Location location, int& line, ++line; } -JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const -{ +JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const { int line, column; - this->getLocationLineAndColumn(location, line, column); + getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); return buffer; } // Deprecated. Preserved for backward compatibility -JSONCPP_STRING Reader::getFormatedErrorMessages() const -{ - return this->getFormattedErrorMessages(); +JSONCPP_STRING Reader::getFormatedErrorMessages() const { + return getFormattedErrorMessages(); } -JSONCPP_STRING Reader::getFormattedErrorMessages() const -{ +JSONCPP_STRING Reader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; - for (Errors::const_iterator itError = this->errors_.begin(); - itError != this->errors_.end(); ++itError) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { const ErrorInfo& error = *itError; formattedMessage += - "* " + this->getLocationLineAndColumn(error.token_.start_) + "\n"; + "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; if (error.extra_) - formattedMessage += "See " + - this->getLocationLineAndColumn(error.extra_) + " for detail.\n"; + formattedMessage += + "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; } return formattedMessage; } -std::vector<Reader::StructuredError> Reader::getStructuredErrors() const -{ +std::vector<Reader::StructuredError> Reader::getStructuredErrors() const { std::vector<Reader::StructuredError> allErrors; - for (Errors::const_iterator itError = this->errors_.begin(); - itError != this->errors_.end(); ++itError) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { const ErrorInfo& error = *itError; Reader::StructuredError structured; - structured.offset_start = error.token_.start_ - this->begin_; - structured.offset_limit = error.token_.end_ - this->begin_; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; structured.message = error.message_; allErrors.push_back(structured); } return allErrors; } -bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) -{ - ptrdiff_t const length = this->end_ - this->begin_; - if (value.getOffsetStart() > length || value.getOffsetLimit() > length) +bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { + ptrdiff_t const length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = this->begin_ + value.getOffsetStart(); - token.end_ = this->end_ + value.getOffsetLimit(); + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = end_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = 0; - this->errors_.push_back(info); + errors_.push_back(info); return true; } -bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, - const Value& extra) -{ - ptrdiff_t const length = this->end_ - this->begin_; - if (value.getOffsetStart() > length || value.getOffsetLimit() > length || - extra.getOffsetLimit() > length) +bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { + ptrdiff_t const length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length + || extra.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = this->begin_ + value.getOffsetStart(); - token.end_ = this->begin_ + value.getOffsetLimit(); + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = begin_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; - info.extra_ = this->begin_ + extra.getOffsetStart(); - this->errors_.push_back(info); + info.extra_ = begin_ + extra.getOffsetStart(); + errors_.push_back(info); return true; } -bool Reader::good() const -{ - return !this->errors_.size(); +bool Reader::good() const { + return !errors_.size(); } // exact copy of Features -class OurFeatures -{ +class OurFeatures { public: static OurFeatures all(); bool allowComments_; @@ -973,48 +906,43 @@ public: bool rejectDupKeys_; bool allowSpecialFloats_; int stackLimit_; -}; // OurFeatures +}; // OurFeatures // exact copy of Implementation of class Features // //////////////////////////////// -OurFeatures OurFeatures::all() -{ - return OurFeatures(); -} +OurFeatures OurFeatures::all() { return OurFeatures(); } // Implementation of class Reader // //////////////////////////////// // exact copy of Reader, renamed to OurReader -class OurReader -{ +class OurReader { public: typedef char Char; typedef const Char* Location; - struct StructuredError - { + struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; JSONCPP_STRING message; }; OurReader(OurFeatures const& features); - bool parse(const char* beginDoc, const char* endDoc, Value& root, + bool parse(const char* beginDoc, + const char* endDoc, + Value& root, bool collectComments = true); JSONCPP_STRING getFormattedErrorMessages() const; std::vector<StructuredError> getStructuredErrors() const; bool pushError(const Value& value, const JSONCPP_STRING& message); - bool pushError(const Value& value, const JSONCPP_STRING& message, - const Value& extra); + bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); bool good() const; private: - OurReader(OurReader const&); // no impl - void operator=(OurReader const&); // no impl + OurReader(OurReader const&); // no impl + void operator=(OurReader const&); // no impl - enum TokenType - { + enum TokenType { tokenEndOfStream = 0, tokenObjectBegin, tokenObjectEnd, @@ -1034,16 +962,14 @@ private: tokenError }; - class Token - { + class Token { public: TokenType type_; Location start_; Location end_; }; - class ErrorInfo - { + class ErrorInfo { public: Token token_; JSONCPP_STRING message_; @@ -1070,20 +996,24 @@ private: bool decodeString(Token& token, JSONCPP_STRING& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); - bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, + bool decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, unsigned int& unicode); - bool decodeUnicodeEscapeSequence(Token& token, Location& current, - Location end, unsigned int& unicode); - bool addError(const JSONCPP_STRING& message, Token& token, - Location extra = 0); + bool decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, + bool addErrorAndRecover(const JSONCPP_STRING& message, + Token& token, TokenType skipUntilToken); void skipUntilSpace(); Value& currentValue(); Char getNextChar(); - void getLocationLineAndColumn(Location location, int& line, - int& column) const; + void + getLocationLineAndColumn(Location location, int& line, int& column) const; JSONCPP_STRING getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); @@ -1104,13 +1034,11 @@ private: OurFeatures const features_; bool collectComments_; -}; // OurReader +}; // OurReader // complete copy of Read impl, for OurReader -bool OurReader::containsNewLine(OurReader::Location begin, - OurReader::Location end) -{ +bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location end) { for (; begin < end; ++begin) if (*begin == '\n' || *begin == '\r') return true; @@ -1118,322 +1046,315 @@ bool OurReader::containsNewLine(OurReader::Location begin, } OurReader::OurReader(OurFeatures const& features) - : errors_() - , document_() - , begin_() - , end_() - , current_() - , lastValueEnd_() - , lastValue_() - , commentsBefore_() - , features_(features) - , collectComments_() -{ + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), + features_(features), collectComments_() { } -bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, - bool collectComments) -{ - if (!this->features_.allowComments_) { +bool OurReader::parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments) { + if (!features_.allowComments_) { collectComments = false; } - this->begin_ = beginDoc; - this->end_ = endDoc; - this->collectComments_ = collectComments; - this->current_ = this->begin_; - this->lastValueEnd_ = 0; - this->lastValue_ = 0; - this->commentsBefore_.clear(); - this->errors_.clear(); - while (!this->nodes_.empty()) - this->nodes_.pop(); - this->nodes_.push(&root); - - bool successful = this->readValue(); + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = 0; + lastValue_ = 0; + commentsBefore_.clear(); + errors_.clear(); + while (!nodes_.empty()) + nodes_.pop(); + nodes_.push(&root); + + bool successful = readValue(); Token token; - this->skipCommentTokens(token); - if (this->features_.failIfExtra_) { - if ((this->features_.strictRoot_ || token.type_ != tokenError) && - token.type_ != tokenEndOfStream) { - this->addError("Extra non-whitespace after JSON value.", token); + skipCommentTokens(token); + if (features_.failIfExtra_) { + if ((features_.strictRoot_ || token.type_ != tokenError) && token.type_ != tokenEndOfStream) { + addError("Extra non-whitespace after JSON value.", token); return false; } } - if (this->collectComments_ && !this->commentsBefore_.empty()) - root.setComment(this->commentsBefore_, commentAfter); - if (this->features_.strictRoot_) { + if (collectComments_ && !commentsBefore_.empty()) + root.setComment(commentsBefore_, commentAfter); + if (features_.strictRoot_) { if (!root.isArray() && !root.isObject()) { - // Set error location to start of doc, ideally should be first token - // found in doc + // Set error location to start of doc, ideally should be first token found + // in doc token.type_ = tokenError; token.start_ = beginDoc; token.end_ = endDoc; - this->addError( - "A valid JSON document must be either an array or an object value.", - token); + addError( + "A valid JSON document must be either an array or an object value.", + token); return false; } } return successful; } -bool OurReader::readValue() -{ +bool OurReader::readValue() { // To preserve the old behaviour we cast size_t to int. - if (static_cast<int>(this->nodes_.size()) > this->features_.stackLimit_) - throwRuntimeError("Exceeded stackLimit in readValue()."); + if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - this->skipCommentTokens(token); + skipCommentTokens(token); bool successful = true; - if (this->collectComments_ && !this->commentsBefore_.empty()) { - this->currentValue().setComment(this->commentsBefore_, commentBefore); - this->commentsBefore_.clear(); + if (collectComments_ && !commentsBefore_.empty()) { + currentValue().setComment(commentsBefore_, commentBefore); + commentsBefore_.clear(); } switch (token.type_) { - case tokenObjectBegin: - successful = this->readObject(token); - this->currentValue().setOffsetLimit(this->current_ - this->begin_); - break; - case tokenArrayBegin: - successful = this->readArray(token); - this->currentValue().setOffsetLimit(this->current_ - this->begin_); - break; - case tokenNumber: - successful = this->decodeNumber(token); - break; - case tokenString: - successful = this->decodeString(token); - break; - case tokenTrue: { - Value v(true); - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenFalse: { - Value v(false); - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenNull: { + case tokenObjectBegin: + successful = readObject(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenArrayBegin: + successful = readArray(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenNumber: + successful = decodeNumber(token); + break; + case tokenString: + successful = decodeString(token); + break; + case tokenTrue: + { + Value v(true); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenFalse: + { + Value v(false); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenNull: + { + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenNaN: + { + Value v(std::numeric_limits<double>::quiet_NaN()); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenPosInf: + { + Value v(std::numeric_limits<double>::infinity()); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenNegInf: + { + Value v(-std::numeric_limits<double>::infinity()); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; Value v; - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenNaN: { - Value v(std::numeric_limits<double>::quiet_NaN()); - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenPosInf: { - Value v(std::numeric_limits<double>::infinity()); - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenNegInf: { - Value v(-std::numeric_limits<double>::infinity()); - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - } break; - case tokenArraySeparator: - case tokenObjectEnd: - case tokenArrayEnd: - if (this->features_.allowDroppedNullPlaceholders_) { - // "Un-read" the current token and mark the current value as a null - // token. - this->current_--; - Value v; - this->currentValue().swapPayload(v); - this->currentValue().setOffsetStart(this->current_ - this->begin_ - 1); - this->currentValue().setOffsetLimit(this->current_ - this->begin_); - break; - } // else, fall through ... - default: - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); - return this->addError("Syntax error: value, object or array expected.", - token); + currentValue().swapPayload(v); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } // else, fall through ... + default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return addError("Syntax error: value, object or array expected.", token); } - if (this->collectComments_) { - this->lastValueEnd_ = this->current_; - this->lastValue_ = &this->currentValue(); + if (collectComments_) { + lastValueEnd_ = current_; + lastValue_ = ¤tValue(); } return successful; } -void OurReader::skipCommentTokens(Token& token) -{ - if (this->features_.allowComments_) { +void OurReader::skipCommentTokens(Token& token) { + if (features_.allowComments_) { do { - this->readToken(token); + readToken(token); } while (token.type_ == tokenComment); } else { - this->readToken(token); + readToken(token); } } -bool OurReader::readToken(Token& token) -{ - this->skipSpaces(); - token.start_ = this->current_; - Char c = this->getNextChar(); +bool OurReader::readToken(Token& token) { + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); bool ok = true; switch (c) { - case '{': - token.type_ = tokenObjectBegin; - break; - case '}': - token.type_ = tokenObjectEnd; - break; - case '[': - token.type_ = tokenArrayBegin; - break; - case ']': - token.type_ = tokenArrayEnd; - break; - case '"': - token.type_ = tokenString; - ok = this->readString(); - break; - case '\'': - if (this->features_.allowSingleQuotes_) { - token.type_ = tokenString; - ok = this->readStringSingleQuote(); - break; - } // else continue - case '/': - token.type_ = tokenComment; - ok = this->readComment(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '\'': + if (features_.allowSingleQuotes_) { + token.type_ = tokenString; + ok = readStringSingleQuote(); + break; + } // else continue + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + token.type_ = tokenNumber; + readNumber(false); + break; + case '-': + if (readNumber(true)) { token.type_ = tokenNumber; - this->readNumber(false); - break; - case '-': - if (this->readNumber(true)) { - token.type_ = tokenNumber; - } else { - token.type_ = tokenNegInf; - ok = this->features_.allowSpecialFloats_ && this->match("nfinity", 7); - } - break; - case 't': - token.type_ = tokenTrue; - ok = this->match("rue", 3); - break; - case 'f': - token.type_ = tokenFalse; - ok = this->match("alse", 4); - break; - case 'n': - token.type_ = tokenNull; - ok = this->match("ull", 3); - break; - case 'N': - if (this->features_.allowSpecialFloats_) { - token.type_ = tokenNaN; - ok = this->match("aN", 2); - } else { - ok = false; - } - break; - case 'I': - if (this->features_.allowSpecialFloats_) { - token.type_ = tokenPosInf; - ok = this->match("nfinity", 7); - } else { - ok = false; - } - break; - case ',': - token.type_ = tokenArraySeparator; - break; - case ':': - token.type_ = tokenMemberSeparator; - break; - case 0: - token.type_ = tokenEndOfStream; - break; - default: + } else { + token.type_ = tokenNegInf; + ok = features_.allowSpecialFloats_ && match("nfinity", 7); + } + break; + case 't': + token.type_ = tokenTrue; + ok = match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = match("ull", 3); + break; + case 'N': + if (features_.allowSpecialFloats_) { + token.type_ = tokenNaN; + ok = match("aN", 2); + } else { ok = false; - break; + } + break; + case 'I': + if (features_.allowSpecialFloats_) { + token.type_ = tokenPosInf; + ok = match("nfinity", 7); + } else { + ok = false; + } + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; } if (!ok) token.type_ = tokenError; - token.end_ = this->current_; + token.end_ = current_; return true; } -void OurReader::skipSpaces() -{ - while (this->current_ != this->end_) { - Char c = *this->current_; +void OurReader::skipSpaces() { + while (current_ != end_) { + Char c = *current_; if (c == ' ' || c == '\t' || c == '\r' || c == '\n') - ++this->current_; + ++current_; else break; } } -bool OurReader::match(Location pattern, int patternLength) -{ - if (this->end_ - this->current_ < patternLength) +bool OurReader::match(Location pattern, int patternLength) { + if (end_ - current_ < patternLength) return false; int index = patternLength; while (index--) - if (this->current_[index] != pattern[index]) + if (current_[index] != pattern[index]) return false; - this->current_ += patternLength; + current_ += patternLength; return true; } -bool OurReader::readComment() -{ - Location commentBegin = this->current_ - 1; - Char c = this->getNextChar(); +bool OurReader::readComment() { + Location commentBegin = current_ - 1; + Char c = getNextChar(); bool successful = false; if (c == '*') - successful = this->readCStyleComment(); + successful = readCStyleComment(); else if (c == '/') - successful = this->readCppStyleComment(); + successful = readCppStyleComment(); if (!successful) return false; - if (this->collectComments_) { + if (collectComments_) { CommentPlacement placement = commentBefore; - if (this->lastValueEnd_ && - !containsNewLine(this->lastValueEnd_, commentBegin)) { - if (c != '*' || !containsNewLine(commentBegin, this->current_)) + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, current_)) placement = commentAfterOnSameLine; } - this->addComment(commentBegin, this->current_, placement); + addComment(commentBegin, current_, placement); } return true; } -JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, - OurReader::Location end) -{ +JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Location end) { JSONCPP_STRING normalized; normalized.reserve(static_cast<size_t>(end - begin)); OurReader::Location current = begin; @@ -1441,8 +1362,8 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, char c = *current++; if (c == '\r') { if (current != end && *current == '\n') - // convert dos EOL - ++current; + // convert dos EOL + ++current; // convert Mac EOL normalized += '\n'; } else { @@ -1452,39 +1373,36 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, return normalized; } -void OurReader::addComment(Location begin, Location end, - CommentPlacement placement) -{ - assert(this->collectComments_); +void +OurReader::addComment(Location begin, Location end, CommentPlacement placement) { + assert(collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(this->lastValue_ != 0); - this->lastValue_->setComment(normalized, placement); + assert(lastValue_ != 0); + lastValue_->setComment(normalized, placement); } else { - this->commentsBefore_ += normalized; + commentsBefore_ += normalized; } } -bool OurReader::readCStyleComment() -{ - while ((this->current_ + 1) < this->end_) { - Char c = this->getNextChar(); - if (c == '*' && *this->current_ == '/') +bool OurReader::readCStyleComment() { + while ((current_ + 1) < end_) { + Char c = getNextChar(); + if (c == '*' && *current_ == '/') break; } - return this->getNextChar() == '/'; + return getNextChar() == '/'; } -bool OurReader::readCppStyleComment() -{ - while (this->current_ != this->end_) { - Char c = this->getNextChar(); +bool OurReader::readCppStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); if (c == '\n') break; if (c == '\r') { // Consume DOS EOL. It will be normalized in addComment. - if (this->current_ != this->end_ && *this->current_ == '\n') - this->getNextChar(); + if (current_ != end_ && *current_ == '\n') + getNextChar(); // Break on Moc OS 9 EOL. break; } @@ -1492,156 +1410,150 @@ bool OurReader::readCppStyleComment() return true; } -bool OurReader::readNumber(bool checkInf) -{ - const char* p = this->current_; - if (checkInf && p != this->end_ && *p == 'I') { - this->current_ = ++p; +bool OurReader::readNumber(bool checkInf) { + const char *p = current_; + if (checkInf && p != end_ && *p == 'I') { + current_ = ++p; return false; } char c = '0'; // stopgap for already consumed character // integral part while (c >= '0' && c <= '9') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; // fractional part if (c == '.') { - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; } // exponential part if (c == 'e' || c == 'E') { - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; if (c == '+' || c == '-') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (this->current_ = p) < this->end_ ? *p++ : '\0'; + c = (current_ = p) < end_ ? *p++ : '\0'; } return true; } -bool OurReader::readString() -{ +bool OurReader::readString() { Char c = 0; - while (this->current_ != this->end_) { - c = this->getNextChar(); + while (current_ != end_) { + c = getNextChar(); if (c == '\\') - this->getNextChar(); + getNextChar(); else if (c == '"') break; } return c == '"'; } -bool OurReader::readStringSingleQuote() -{ + +bool OurReader::readStringSingleQuote() { Char c = 0; - while (this->current_ != this->end_) { - c = this->getNextChar(); + while (current_ != end_) { + c = getNextChar(); if (c == '\\') - this->getNextChar(); + getNextChar(); else if (c == '\'') break; } return c == '\''; } -bool OurReader::readObject(Token& tokenStart) -{ +bool OurReader::readObject(Token& tokenStart) { Token tokenName; JSONCPP_STRING name; Value init(objectValue); - this->currentValue().swapPayload(init); - this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); - while (this->readToken(tokenName)) { + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + while (readToken(tokenName)) { bool initialTokenOk = true; while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = this->readToken(tokenName); + initialTokenOk = readToken(tokenName); if (!initialTokenOk) break; if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object return true; name.clear(); if (tokenName.type_ == tokenString) { - if (!this->decodeString(tokenName, name)) - return this->recoverFromError(tokenObjectEnd); - } else if (tokenName.type_ == tokenNumber && - this->features_.allowNumericKeys_) { + if (!decodeString(tokenName, name)) + return recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { Value numberName; - if (!this->decodeNumber(tokenName, numberName)) - return this->recoverFromError(tokenObjectEnd); + if (!decodeNumber(tokenName, numberName)) + return recoverFromError(tokenObjectEnd); name = numberName.asString(); } else { break; } Token colon; - if (!this->readToken(colon) || colon.type_ != tokenMemberSeparator) { - return this->addErrorAndRecover("Missing ':' after object member name", - colon, tokenObjectEnd); + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover( + "Missing ':' after object member name", colon, tokenObjectEnd); } - if (name.length() >= (1U << 30)) - throwRuntimeError("keylength >= 2^30"); - if (this->features_.rejectDupKeys_ && - this->currentValue().isMember(name)) { + if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30"); + if (features_.rejectDupKeys_ && currentValue().isMember(name)) { JSONCPP_STRING msg = "Duplicate key: '" + name + "'"; - return this->addErrorAndRecover(msg, tokenName, tokenObjectEnd); + return addErrorAndRecover( + msg, tokenName, tokenObjectEnd); } - Value& value = this->currentValue()[name]; - this->nodes_.push(&value); - bool ok = this->readValue(); - this->nodes_.pop(); + Value& value = currentValue()[name]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); if (!ok) // error already set - return this->recoverFromError(tokenObjectEnd); + return recoverFromError(tokenObjectEnd); Token comma; - if (!this->readToken(comma) || + if (!readToken(comma) || (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && comma.type_ != tokenComment)) { - return this->addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + return addErrorAndRecover( + "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } bool finalizeTokenOk = true; while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = this->readToken(comma); + finalizeTokenOk = readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } - return this->addErrorAndRecover("Missing '}' or object member name", - tokenName, tokenObjectEnd); + return addErrorAndRecover( + "Missing '}' or object member name", tokenName, tokenObjectEnd); } -bool OurReader::readArray(Token& tokenStart) -{ +bool OurReader::readArray(Token& tokenStart) { Value init(arrayValue); - this->currentValue().swapPayload(init); - this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); - this->skipSpaces(); - if (this->current_ != this->end_ && *this->current_ == ']') // empty array + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + skipSpaces(); + if (current_ != end_ && *current_ == ']') // empty array { Token endArray; - this->readToken(endArray); + readToken(endArray); return true; } int index = 0; for (;;) { - Value& value = this->currentValue()[index++]; - this->nodes_.push(&value); - bool ok = this->readValue(); - this->nodes_.pop(); + Value& value = currentValue()[index++]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); if (!ok) // error already set - return this->recoverFromError(tokenArrayEnd); + return recoverFromError(tokenArrayEnd); Token token; // Accept Comment after last item in the array. - ok = this->readToken(token); + ok = readToken(token); while (token.type_ == tokenComment && ok) { - ok = this->readToken(token); + ok = readToken(token); } bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { - return this->addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + return addErrorAndRecover( + "Missing ',' or ']' in array declaration", token, tokenArrayEnd); } if (token.type_ == tokenArrayEnd) break; @@ -1649,19 +1561,17 @@ bool OurReader::readArray(Token& tokenStart) return true; } -bool OurReader::decodeNumber(Token& token) -{ +bool OurReader::decodeNumber(Token& token) { Value decoded; - if (!this->decodeNumber(token, decoded)) + if (!decodeNumber(token, decoded)) return false; - this->currentValue().swapPayload(decoded); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return true; } -bool OurReader::decodeNumber(Token& token, Value& decoded) -{ +bool OurReader::decodeNumber(Token& token, Value& decoded) { // Attempts to parse the number as an integer. If the number is // larger than the maximum supported value of an integer then // we decode the number as a double. @@ -1669,17 +1579,16 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) bool isNegative = *current == '-'; if (isNegative) ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of - // them. - Value::LargestUInt maxIntegerValue = isNegative - ? Value::LargestUInt(Value::minLargestInt) - : Value::maxLargestUInt; + // TODO: Help the compiler do the div and mod at compile time or get rid of them. + Value::LargestUInt maxIntegerValue = + isNegative ? Value::LargestUInt(Value::minLargestInt) + : Value::maxLargestUInt; Value::LargestUInt threshold = maxIntegerValue / 10; Value::LargestUInt value = 0; while (current < token.end_) { Char c = *current++; if (c < '0' || c > '9') - return this->decodeDouble(token, decoded); + return decodeDouble(token, decoded); Value::UInt digit(static_cast<Value::UInt>(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If @@ -1688,7 +1597,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) // Otherwise treat this number as a double to avoid overflow. if (value > threshold || current != token.end_ || digit > maxIntegerValue % 10) { - return this->decodeDouble(token, decoded); + return decodeDouble(token, decoded); } } value = value * 10 + digit; @@ -1702,19 +1611,17 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) return true; } -bool OurReader::decodeDouble(Token& token) -{ +bool OurReader::decodeDouble(Token& token) { Value decoded; - if (!this->decodeDouble(token, decoded)) + if (!decodeDouble(token, decoded)) return false; - this->currentValue().swapPayload(decoded); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return true; } -bool OurReader::decodeDouble(Token& token, Value& decoded) -{ +bool OurReader::decodeDouble(Token& token, Value& decoded) { double value = 0; const int bufferSize = 32; int count; @@ -1722,7 +1629,7 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) // Sanity check to avoid buffer overflow exploits. if (length < 0) { - return this->addError("Unable to parse token length", token); + return addError("Unable to parse token length", token); } size_t const ulength = static_cast<size_t>(length); @@ -1745,27 +1652,25 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) } if (count != 1) - return this->addError("'" + JSONCPP_STRING(token.start_, token.end_) + - "' is not a number.", - token); + return addError("'" + JSONCPP_STRING(token.start_, token.end_) + + "' is not a number.", + token); decoded = value; return true; } -bool OurReader::decodeString(Token& token) -{ +bool OurReader::decodeString(Token& token) { JSONCPP_STRING decoded_string; - if (!this->decodeString(token, decoded_string)) + if (!decodeString(token, decoded_string)) return false; Value decoded(decoded_string); - this->currentValue().swapPayload(decoded); - this->currentValue().setOffsetStart(token.start_ - this->begin_); - this->currentValue().setOffsetLimit(token.end_ - this->begin_); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return true; } -bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) -{ +bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) { decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -1775,43 +1680,41 @@ bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) break; else if (c == '\\') { if (current == end) - return this->addError("Empty escape sequence in string", token, - current); + return addError("Empty escape sequence in string", token, current); Char escape = *current++; switch (escape) { - case '"': - decoded += '"'; - break; - case '/': - decoded += '/'; - break; - case '\\': - decoded += '\\'; - break; - case 'b': - decoded += '\b'; - break; - case 'f': - decoded += '\f'; - break; - case 'n': - decoded += '\n'; - break; - case 'r': - decoded += '\r'; - break; - case 't': - decoded += '\t'; - break; - case 'u': { - unsigned int unicode; - if (!this->decodeUnicodeCodePoint(token, current, end, unicode)) - return false; - decoded += codePointToUTF8(unicode); - } break; - default: - return this->addError("Bad escape sequence in string", token, - current); + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return addError("Bad escape sequence in string", token, current); } } else { decoded += c; @@ -1820,44 +1723,45 @@ bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) return true; } -bool OurReader::decodeUnicodeCodePoint(Token& token, Location& current, - Location end, unsigned int& unicode) -{ +bool OurReader::decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode) { - unicode = 0; // Convince scanbuild this is always initialized before use. - if (!this->decodeUnicodeEscapeSequence(token, current, end, unicode)) + unicode = 0; // Convince clang-analyzer that this is initialized before use. + if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) return false; if (unicode >= 0xD800 && unicode <= 0xDBFF) { // surrogate pairs if (end - current < 6) - return this->addError( - "additional six characters expected to parse unicode surrogate pair.", - token, current); + return addError( + "additional six characters expected to parse unicode surrogate pair.", + token, + current); unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { - if (this->decodeUnicodeEscapeSequence(token, current, end, - surrogatePair)) { - unicode = - 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); } else return false; } else - return this->addError( - "expecting another \\u token to begin the second half of " - "a unicode surrogate pair", - token, current); + return addError("expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, + current); } return true; } -bool OurReader::decodeUnicodeEscapeSequence(Token& token, Location& current, - Location end, - unsigned int& ret_unicode) -{ +bool OurReader::decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& ret_unicode) { if (end - current < 4) - return this->addError( - "Bad unicode escape sequence in string: four digits expected.", token, - current); + return addError( + "Bad unicode escape sequence in string: four digits expected.", + token, + current); int unicode = 0; for (int index = 0; index < 4; ++index) { Char c = *current++; @@ -1869,65 +1773,60 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token, Location& current, else if (c >= 'A' && c <= 'F') unicode += c - 'A' + 10; else - return this->addError( - "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, current); + return addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, + current); } ret_unicode = static_cast<unsigned int>(unicode); return true; } -bool OurReader::addError(const JSONCPP_STRING& message, Token& token, - Location extra) -{ +bool +OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = extra; - this->errors_.push_back(info); + errors_.push_back(info); return false; } -bool OurReader::recoverFromError(TokenType skipUntilToken) -{ - size_t errorCount = this->errors_.size(); +bool OurReader::recoverFromError(TokenType skipUntilToken) { + size_t errorCount = errors_.size(); Token skip; for (;;) { - if (!this->readToken(skip)) - this->errors_.resize(errorCount); // discard errors caused by recovery + if (!readToken(skip)) + errors_.resize(errorCount); // discard errors caused by recovery if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) break; } - this->errors_.resize(errorCount); + errors_.resize(errorCount); return false; } -bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message, Token& token, - TokenType skipUntilToken) -{ - this->addError(message, token); - return this->recoverFromError(skipUntilToken); +bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message, + Token& token, + TokenType skipUntilToken) { + addError(message, token); + return recoverFromError(skipUntilToken); } -Value& OurReader::currentValue() -{ - return *(this->nodes_.top()); -} +Value& OurReader::currentValue() { return *(nodes_.top()); } -OurReader::Char OurReader::getNextChar() -{ - if (this->current_ == this->end_) +OurReader::Char OurReader::getNextChar() { + if (current_ == end_) return 0; - return *this->current_++; + return *current_++; } -void OurReader::getLocationLineAndColumn(Location location, int& line, - int& column) const -{ - Location current = this->begin_; +void OurReader::getLocationLineAndColumn(Location location, + int& line, + int& column) const { + Location current = begin_; Location lastLineStart = current; line = 0; - while (current < location && current != this->end_) { + while (current < location && current != end_) { Char c = *current++; if (c == '\r') { if (*current == '\n') @@ -1944,105 +1843,101 @@ void OurReader::getLocationLineAndColumn(Location location, int& line, ++line; } -JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const -{ +JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { int line, column; - this->getLocationLineAndColumn(location, line, column); + getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); return buffer; } -JSONCPP_STRING OurReader::getFormattedErrorMessages() const -{ +JSONCPP_STRING OurReader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; - for (Errors::const_iterator itError = this->errors_.begin(); - itError != this->errors_.end(); ++itError) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { const ErrorInfo& error = *itError; formattedMessage += - "* " + this->getLocationLineAndColumn(error.token_.start_) + "\n"; + "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; if (error.extra_) - formattedMessage += "See " + - this->getLocationLineAndColumn(error.extra_) + " for detail.\n"; + formattedMessage += + "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; } return formattedMessage; } -std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const -{ +std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const { std::vector<OurReader::StructuredError> allErrors; - for (Errors::const_iterator itError = this->errors_.begin(); - itError != this->errors_.end(); ++itError) { + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { const ErrorInfo& error = *itError; OurReader::StructuredError structured; - structured.offset_start = error.token_.start_ - this->begin_; - structured.offset_limit = error.token_.end_ - this->begin_; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; structured.message = error.message_; allErrors.push_back(structured); } return allErrors; } -bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) -{ - ptrdiff_t length = this->end_ - this->begin_; - if (value.getOffsetStart() > length || value.getOffsetLimit() > length) +bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { + ptrdiff_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = this->begin_ + value.getOffsetStart(); - token.end_ = this->end_ + value.getOffsetLimit(); + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = end_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = 0; - this->errors_.push_back(info); + errors_.push_back(info); return true; } -bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, - const Value& extra) -{ - ptrdiff_t length = this->end_ - this->begin_; - if (value.getOffsetStart() > length || value.getOffsetLimit() > length || - extra.getOffsetLimit() > length) +bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { + ptrdiff_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length + || extra.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = this->begin_ + value.getOffsetStart(); - token.end_ = this->begin_ + value.getOffsetLimit(); + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = begin_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; - info.extra_ = this->begin_ + extra.getOffsetStart(); - this->errors_.push_back(info); + info.extra_ = begin_ + extra.getOffsetStart(); + errors_.push_back(info); return true; } -bool OurReader::good() const -{ - return !this->errors_.size(); +bool OurReader::good() const { + return !errors_.size(); } -class OurCharReader : public CharReader -{ + +class OurCharReader : public CharReader { bool const collectComments_; OurReader reader_; - public: - OurCharReader(bool collectComments, OurFeatures const& features) - : collectComments_(collectComments) - , reader_(features) - { - } - bool parse(char const* beginDoc, char const* endDoc, Value* root, - JSONCPP_STRING* errs) JSONCPP_OVERRIDE - { - bool ok = - this->reader_.parse(beginDoc, endDoc, *root, this->collectComments_); + OurCharReader( + bool collectComments, + OurFeatures const& features) + : collectComments_(collectComments) + , reader_(features) + {} + bool parse( + char const* beginDoc, char const* endDoc, + Value* root, JSONCPP_STRING* errs) JSONCPP_OVERRIDE { + bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); if (errs) { - *errs = this->reader_.getFormattedErrorMessages(); + *errs = reader_.getFormattedErrorMessages(); } return ok; } @@ -2050,26 +1945,23 @@ public: CharReaderBuilder::CharReaderBuilder() { - setDefaults(&this->settings_); + setDefaults(&settings_); } CharReaderBuilder::~CharReaderBuilder() -{ -} +{} CharReader* CharReaderBuilder::newCharReader() const { - bool collectComments = this->settings_["collectComments"].asBool(); + bool collectComments = settings_["collectComments"].asBool(); OurFeatures features = OurFeatures::all(); - features.allowComments_ = this->settings_["allowComments"].asBool(); - features.strictRoot_ = this->settings_["strictRoot"].asBool(); - features.allowDroppedNullPlaceholders_ = - this->settings_["allowDroppedNullPlaceholders"].asBool(); - features.allowNumericKeys_ = this->settings_["allowNumericKeys"].asBool(); - features.allowSingleQuotes_ = this->settings_["allowSingleQuotes"].asBool(); - features.stackLimit_ = this->settings_["stackLimit"].asInt(); - features.failIfExtra_ = this->settings_["failIfExtra"].asBool(); - features.rejectDupKeys_ = this->settings_["rejectDupKeys"].asBool(); - features.allowSpecialFloats_ = - this->settings_["allowSpecialFloats"].asBool(); + features.allowComments_ = settings_["allowComments"].asBool(); + features.strictRoot_ = settings_["strictRoot"].asBool(); + features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); + features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); + features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); + features.stackLimit_ = settings_["stackLimit"].asInt(); + features.failIfExtra_ = settings_["failIfExtra"].asBool(); + features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); + features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); return new OurCharReader(collectComments, features); } static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys) @@ -2089,29 +1981,28 @@ static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys) bool CharReaderBuilder::validate(Json::Value* invalid) const { Json::Value my_invalid; - if (!invalid) - invalid = &my_invalid; // so we do not need to test for NULL + if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; std::set<JSONCPP_STRING> valid_keys; getValidReaderKeys(&valid_keys); - Value::Members keys = this->settings_.getMemberNames(); + Value::Members keys = settings_.getMemberNames(); size_t n = keys.size(); for (size_t i = 0; i < n; ++i) { JSONCPP_STRING const& key = keys[i]; if (valid_keys.find(key) == valid_keys.end()) { - inv[key] = this->settings_[key]; + inv[key] = settings_[key]; } } return 0u == inv.size(); } Value& CharReaderBuilder::operator[](JSONCPP_STRING key) { - return this->settings_[key]; + return settings_[key]; } // static void CharReaderBuilder::strictMode(Json::Value* settings) { - //! [CharReaderBuilderStrictMode] +//! [CharReaderBuilderStrictMode] (*settings)["allowComments"] = false; (*settings)["strictRoot"] = true; (*settings)["allowDroppedNullPlaceholders"] = false; @@ -2121,12 +2012,12 @@ void CharReaderBuilder::strictMode(Json::Value* settings) (*settings)["failIfExtra"] = true; (*settings)["rejectDupKeys"] = true; (*settings)["allowSpecialFloats"] = false; - //! [CharReaderBuilderStrictMode] +//! [CharReaderBuilderStrictMode] } // static void CharReaderBuilder::setDefaults(Json::Value* settings) { - //! [CharReaderBuilderDefaults] +//! [CharReaderBuilderDefaults] (*settings)["collectComments"] = true; (*settings)["allowComments"] = true; (*settings)["strictRoot"] = false; @@ -2137,14 +2028,15 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) (*settings)["failIfExtra"] = false; (*settings)["rejectDupKeys"] = false; (*settings)["allowSpecialFloats"] = false; - //! [CharReaderBuilderDefaults] +//! [CharReaderBuilderDefaults] } ////////////////////////////////// // global functions -bool parseFromStream(CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, - Value* root, JSONCPP_STRING* errs) +bool parseFromStream( + CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, + Value* root, JSONCPP_STRING* errs) { JSONCPP_OSTRINGSTREAM ssin; ssin << sin.rdbuf(); @@ -2156,13 +2048,14 @@ bool parseFromStream(CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, return reader->parse(begin, end, root, errs); } -JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) -{ +JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) { CharReaderBuilder b; JSONCPP_STRING errs; bool ok = parseFromStream(b, sin, &root, &errs); if (!ok) { - fprintf(stderr, "Error from reader: %s", errs.c_str()); + fprintf(stderr, + "Error from reader: %s", + errs.c_str()); throwRuntimeError(errs); } |