1f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Copyright 2007-2011 Baptiste Lepilleur 2f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Distributed under MIT license, or public domain if desired and 3f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// recognized in your jurisdiction. 4f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 6f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#if !defined(JSON_IS_AMALGAMATION) 72eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#include <json/assertions.h> 82eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#include <json/reader.h> 92eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#include <json/value.h> 102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#include "json_tool.h" 11f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#endif // if !defined(JSON_IS_AMALGAMATION) 125021d59dfbed53039ac6f20e198dc3684245b495Greg Hartman#include <iostream> 135021d59dfbed53039ac6f20e198dc3684245b495Greg Hartman#include <fstream> 14f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#include <utility> 15f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#include <cstdio> 16f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#include <cassert> 17f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#include <cstring> 182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#include <istream> 19f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below 212eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#define snprintf _snprintf 222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#endif 232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger// Disable warning about strdup being deprecated. 262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#pragma warning(disable : 4996) 27f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III#endif 28f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 29f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins IIInamespace Json { 30f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 31f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Implementation of class Features 32f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// //////////////////////////////// 33f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 34f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins IIIFeatures::Features() 352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger : allowComments_(true), strictRoot_(false), 362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} 37f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerFeatures Features::all() { return Features(); } 39f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerFeatures Features::strictMode() { 412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Features features; 422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger features.allowComments_ = false; 432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger features.strictRoot_ = true; 442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger features.allowDroppedNullPlaceholders_ = false; 452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger features.allowNumericKeys_ = false; 462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return features; 47f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 48f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 49f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Implementation of class Reader 50f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// //////////////////////////////// 51f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstatic inline bool in(Reader::Char c, 532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c1, 542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c2, 552eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c3, 562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c4) { 572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return c == c1 || c == c2 || c == c3 || c == c4; 58f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 59f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstatic inline bool in(Reader::Char c, 612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c1, 622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c2, 632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c3, 642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c4, 652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::Char c5) { 662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return c == c1 || c == c2 || c == c3 || c == c4 || c == c5; 67f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 68f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstatic bool containsNewLine(Reader::Location begin, Reader::Location end) { 702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger for (; begin < end; ++begin) 712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (*begin == '\n' || *begin == '\r') 722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 74f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 75f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 76f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Class Reader 77f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// ////////////////////////////////////////////////////////////////// 78f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 79f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins IIIReader::Reader() 802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), 812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastValue_(), commentsBefore_(), features_(Features::all()), 822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger collectComments_() {} 83f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerReader::Reader(const Features& features) 852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), 862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastValue_(), commentsBefore_(), features_(features), collectComments_() { 87f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 88f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 89f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins IIIbool 902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerReader::parse(const std::string& document, Value& root, bool collectComments) { 912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger document_ = document; 922eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger const char* begin = document_.c_str(); 932eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger const char* end = begin + document_.length(); 942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return parse(begin, end, root, collectComments); 952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 972eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::parse(std::istream& sin, Value& root, bool collectComments) { 982eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // std::istream_iterator<char> begin(sin); 992eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // std::istream_iterator<char> end; 1002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Those would allow streamed input from a file, if parse() were a 1012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // template function. 1022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 1032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Since std::string is reference-counted, this at least does not 1042eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // create an extra copy. 1052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger std::string doc; 1062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger std::getline(sin, doc, (char)EOF); 1072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return parse(doc, root, collectComments); 1082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 1092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 1102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::parse(const char* beginDoc, 1112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger const char* endDoc, 1122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value& root, 1132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool collectComments) { 1142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!features_.allowComments_) { 1152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger collectComments = false; 1162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 1172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 1182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger begin_ = beginDoc; 1192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger end_ = endDoc; 1202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger collectComments_ = collectComments; 1212eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger current_ = begin_; 1222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastValueEnd_ = 0; 1232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastValue_ = 0; 1242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger commentsBefore_ = ""; 1252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger errors_.clear(); 1262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (!nodes_.empty()) 1272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger nodes_.pop(); 1282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger nodes_.push(&root); 1292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 1302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool successful = readValue(); 1312eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token token; 1322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger skipCommentTokens(token); 1332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (collectComments_ && !commentsBefore_.empty()) 1342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger root.setComment(commentsBefore_, commentAfter); 1352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (features_.strictRoot_) { 1362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!root.isArray() && !root.isObject()) { 1372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Set error location to start of doc, ideally should be first token found 1382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // in doc 1392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenError; 1402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.start_ = beginDoc; 1412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.end_ = endDoc; 1422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger addError( 1432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "A valid JSON document must be either an array or an object value.", 1442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token); 1452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 1462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 1472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 1482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return successful; 1492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 1502eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 1512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readValue() { 1522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token token; 1532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger skipCommentTokens(token); 1542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool successful = true; 1552eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 1562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (collectComments_ && !commentsBefore_.empty()) { 1572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Remove newline characters at the end of the comments 1582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger size_t lastNonNewline = commentsBefore_.find_last_not_of("\r\n"); 1592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (lastNonNewline != std::string::npos) { 1602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger commentsBefore_.erase(lastNonNewline + 1); 1612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else { 1622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger commentsBefore_.clear(); 1632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 164f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 1652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setComment(commentsBefore_, commentBefore); 1662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger commentsBefore_ = ""; 1672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 1682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 1692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger switch (token.type_) { 1702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenObjectBegin: 1712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger successful = readObject(token); 1722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(current_ - begin_); 1732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 1742eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenArrayBegin: 1752eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger successful = readArray(token); 1762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(current_ - begin_); 1772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 1782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenNumber: 1792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger successful = decodeNumber(token); 1802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 1812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenString: 1822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger successful = decodeString(token); 1832eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 1842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenTrue: 1852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = true; 1862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(token.start_ - begin_); 1872eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(token.end_ - begin_); 1882eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 1892eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenFalse: 1902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = false; 1912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(token.start_ - begin_); 1922eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(token.end_ - begin_); 1932eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 1942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenNull: 1952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = Value(); 1962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(token.start_ - begin_); 1972eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(token.end_ - begin_); 1982eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 1992eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case tokenArraySeparator: 2002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (features_.allowDroppedNullPlaceholders_) { 2012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // "Un-read" the current token and mark the current value as a null 2022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // token. 2032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger current_--; 204f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III currentValue() = Value(); 2052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(current_ - begin_ - 1); 2062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(current_ - begin_); 2072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 2092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Else, fall through... 2102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger default: 2112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(token.start_ - begin_); 2122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(token.end_ - begin_); 2132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError("Syntax error: value, object or array expected.", token); 2142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 2152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 2162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (collectComments_) { 2172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastValueEnd_ = current_; 2182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastValue_ = ¤tValue(); 2192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 2202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 2212eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return successful; 2222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 2232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 2242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergervoid Reader::skipCommentTokens(Token& token) { 2252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (features_.allowComments_) { 2262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger do { 2272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger readToken(token); 2282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } while (token.type_ == tokenComment); 2292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else { 2302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger readToken(token); 2312eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 2322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 2332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 2342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::expectToken(TokenType type, Token& token, const char* message) { 2352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger readToken(token); 2362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (token.type_ != type) 2372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError(message, token); 2382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 2392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 2402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 2412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readToken(Token& token) { 2422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger skipSpaces(); 2432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.start_ = current_; 2442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = getNextChar(); 2452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool ok = true; 2462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger switch (c) { 2472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '{': 2482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenObjectBegin; 2492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2502eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '}': 2512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenObjectEnd; 2522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '[': 2542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenArrayBegin; 2552eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case ']': 2572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenArrayEnd; 2582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '"': 2602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenString; 2612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = readString(); 2622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '/': 2642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenComment; 2652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = readComment(); 2662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '0': 2682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '1': 2692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '2': 2702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '3': 2712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '4': 2722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '5': 2732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '6': 2742eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '7': 2752eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '8': 2762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '9': 2772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '-': 2782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenNumber; 2792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger readNumber(); 2802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 't': 2822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenTrue; 2832eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = match("rue", 3); 2842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 'f': 2862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenFalse; 2872eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = match("alse", 4); 2882eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2892eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 'n': 2902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenNull; 2912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = match("ull", 3); 2922eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2932eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case ',': 2942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenArraySeparator; 2952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case ':': 2972eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenMemberSeparator; 2982eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 2992eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 0: 3002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenEndOfStream; 3012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 3022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger default: 3032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = false; 3042eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 3052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 3062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!ok) 3072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenError; 3082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.end_ = current_; 3092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 3102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 3112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 3122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergervoid Reader::skipSpaces() { 3132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current_ != end_) { 3142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = *current_; 3152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c == ' ' || c == '\t' || c == '\r' || c == '\n') 3162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++current_; 3172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else 318f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III break; 3192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 3202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 321f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 3222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::match(Location pattern, int patternLength) { 3232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (end_ - current_ < patternLength) 3242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 3252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int index = patternLength; 3262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (index--) 3272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (current_[index] != pattern[index]) 3282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 3292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger current_ += patternLength; 3302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 3312eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 3322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 3332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readComment() { 3342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location commentBegin = current_ - 1; 3352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = getNextChar(); 3362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool successful = false; 3372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c == '*') 3382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger successful = readCStyleComment(); 3392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else if (c == '/') 3402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger successful = readCppStyleComment(); 3412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!successful) 3422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 3432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 3442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (collectComments_) { 3452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger CommentPlacement placement = commentBefore; 3462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { 3472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c != '*' || !containsNewLine(commentBegin, current_)) 3482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger placement = commentAfterOnSameLine; 3492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 350f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 3512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger addComment(commentBegin, current_, placement); 3522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 3532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 354f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 355f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 3562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergervoid 3572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerReader::addComment(Location begin, Location end, CommentPlacement placement) { 3582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger assert(collectComments_); 3592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (placement == commentAfterOnSameLine) { 3602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger assert(lastValue_ != 0); 3612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastValue_->setComment(std::string(begin, end), placement); 3622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else { 3632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger commentsBefore_ += std::string(begin, end); 3642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 3652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 366f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 3672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readCStyleComment() { 3682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current_ != end_) { 3692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = getNextChar(); 3702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c == '*' && *current_ == '/') 371f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III break; 3722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 3732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return getNextChar() == '/'; 374f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 375f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 3762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readCppStyleComment() { 3772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current_ != end_) { 3782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = getNextChar(); 3792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c == '\r' || c == '\n') 3802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 3812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 3822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 383f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 384f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 3852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergervoid Reader::readNumber() { 3862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current_ != end_) { 3872eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!(*current_ >= '0' && *current_ <= '9') && 3882eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger !in(*current_, '.', 'e', 'E', '+', '-')) 3892eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 3902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++current_; 3912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 392f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 393f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 3942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readString() { 3952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = 0; 3962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current_ != end_) { 3972eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger c = getNextChar(); 3982eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c == '\\') 3992eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger getNextChar(); 4002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else if (c == '"') 4012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 4022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return c == '"'; 4042eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 4052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 4062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readObject(Token& tokenStart) { 4072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token tokenName; 4082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger std::string name; 4092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = Value(objectValue); 4102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(tokenStart.start_ - begin_); 4112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (readToken(tokenName)) { 4122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool initialTokenOk = true; 4132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (tokenName.type_ == tokenComment && initialTokenOk) 4142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger initialTokenOk = readToken(tokenName); 4152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!initialTokenOk) 4162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 4172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object 4182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 4192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger name = ""; 4202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (tokenName.type_ == tokenString) { 4212eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!decodeString(tokenName, name)) 4222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return recoverFromError(tokenObjectEnd); 4232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { 4242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value numberName; 4252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!decodeNumber(tokenName, numberName)) 4262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return recoverFromError(tokenObjectEnd); 4272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger name = numberName.asString(); 4282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else { 4292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 4302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 431f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 4322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token colon; 4332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { 4342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addErrorAndRecover( 4352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "Missing ':' after object member name", colon, tokenObjectEnd); 4362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value& value = currentValue()[name]; 4382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger nodes_.push(&value); 4392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool ok = readValue(); 4402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger nodes_.pop(); 4412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!ok) // error already set 4422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return recoverFromError(tokenObjectEnd); 4432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 4442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token comma; 4452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!readToken(comma) || 4462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && 4472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger comma.type_ != tokenComment)) { 4482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addErrorAndRecover( 4492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); 4502eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool finalizeTokenOk = true; 4522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (comma.type_ == tokenComment && finalizeTokenOk) 4532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger finalizeTokenOk = readToken(comma); 4542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (comma.type_ == tokenObjectEnd) 455f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III return true; 4562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addErrorAndRecover( 4582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "Missing '}' or object member name", tokenName, tokenObjectEnd); 4592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 4602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 4612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::readArray(Token& tokenStart) { 4622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = Value(arrayValue); 4632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(tokenStart.start_ - begin_); 4642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger skipSpaces(); 4652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (*current_ == ']') // empty array 4662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger { 4672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token endArray; 4682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger readToken(endArray); 4692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 4702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int index = 0; 4722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger for (;;) { 4732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value& value = currentValue()[index++]; 4742eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger nodes_.push(&value); 4752eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool ok = readValue(); 4762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger nodes_.pop(); 4772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!ok) // error already set 4782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return recoverFromError(tokenArrayEnd); 4792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 4802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token token; 4812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Accept Comment after last item in the array. 4822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = readToken(token); 4832eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (token.type_ == tokenComment && ok) { 4842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ok = readToken(token); 4852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool badTokenType = 4872eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); 4882eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!ok || badTokenType) { 4892eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addErrorAndRecover( 4902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "Missing ',' or ']' in array declaration", token, tokenArrayEnd); 4912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4922eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (token.type_ == tokenArrayEnd) 4932eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 4942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 4952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 4962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 4972eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 4982eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeNumber(Token& token) { 4992eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value decoded; 5002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!decodeNumber(token, decoded)) 5012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 5022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = decoded; 5032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(token.start_ - begin_); 5042eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(token.end_ - begin_); 5052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 5062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 5072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 5082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeNumber(Token& token, Value& decoded) { 5092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool isDouble = false; 5102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger for (Location inspect = token.start_; inspect != token.end_; ++inspect) { 5112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger isDouble = isDouble || in(*inspect, '.', 'e', 'E', '+') || 5122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger (*inspect == '-' && inspect != token.start_); 5132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 5142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (isDouble) 5152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return decodeDouble(token, decoded); 5162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Attempts to parse the number as an integer. If the number is 5172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // larger than the maximum supported value of an integer then 5182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // we decode the number as a double. 5192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location current = token.start_; 5202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool isNegative = *current == '-'; 5212eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (isNegative) 5222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++current; 5232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value::LargestUInt maxIntegerValue = 5242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger isNegative ? Value::LargestUInt(-Value::minLargestInt) 5252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger : Value::maxLargestUInt; 5262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value::LargestUInt threshold = maxIntegerValue / 10; 5272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value::LargestUInt value = 0; 5282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current < token.end_) { 5292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = *current++; 5302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c < '0' || c > '9') 5312eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError("'" + std::string(token.start_, token.end_) + 5322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "' is not a number.", 5332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token); 5342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value::UInt digit(c - '0'); 5352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (value >= threshold) { 5362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // We've hit or exceeded the max value divided by 10 (rounded down). If 5372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // a) we've only just touched the limit, b) this is the last digit, and 5382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // c) it's small enough to fit in that rounding delta, we're okay. 5392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Otherwise treat this number as a double to avoid overflow. 5402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (value > threshold || current != token.end_ || 5412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger digit > maxIntegerValue % 10) { 5422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return decodeDouble(token, decoded); 543f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III } 5442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 5452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger value = value * 10 + digit; 5462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 5472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (isNegative) 5482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded = -Value::LargestInt(value); 5492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else if (value <= Value::LargestUInt(Value::maxInt)) 5502eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded = Value::LargestInt(value); 5512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else 5522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded = value; 5532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 5542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 5552eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 5562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeDouble(Token& token) { 5572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Value decoded; 5582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!decodeDouble(token, decoded)) 5592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 5602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = decoded; 5612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(token.start_ - begin_); 5622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(token.end_ - begin_); 5632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 5642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 5652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 5662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeDouble(Token& token, Value& decoded) { 5672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger double value = 0; 5682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger const int bufferSize = 32; 5692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int count; 5702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int length = int(token.end_ - token.start_); 5712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 5722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Sanity check to avoid buffer overflow exploits. 5732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (length < 0) { 5742eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError("Unable to parse token length", token); 5752eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 5762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 5772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // Avoid using a string constant for the format control string given to 5782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // sscanf, as this can cause hard to debug crashes on OS X. See here for more 5792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // info: 5802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // 5812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html 5822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger char format[] = "%lf"; 5832eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 5842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (length <= bufferSize) { 5852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char buffer[bufferSize + 1]; 5862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger memcpy(buffer, token.start_, length); 5872eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger buffer[length] = 0; 5882eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger count = sscanf(buffer, format, &value); 5892eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else { 5902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger std::string buffer(token.start_, token.end_); 5912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger count = sscanf(buffer.c_str(), format, &value); 5922eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 5932eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 5942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (count != 1) 5952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError("'" + std::string(token.start_, token.end_) + 5962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "' is not a number.", 5972eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token); 5982eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded = value; 5992eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 6002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 6012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 6022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeString(Token& token) { 6032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger std::string decoded; 6042eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!decodeString(token, decoded)) 6052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 6062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue() = decoded; 6072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetStart(token.start_ - begin_); 6082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger currentValue().setOffsetLimit(token.end_ - begin_); 6092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 6102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 6112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 6122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeString(Token& token, std::string& decoded) { 6132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded.reserve(token.end_ - token.start_ - 2); 6142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location current = token.start_ + 1; // skip '"' 6152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location end = token.end_ - 1; // do not include '"' 6162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current != end) { 6172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = *current++; 6182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c == '"') 6192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else if (c == '\\') { 6212eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (current == end) 6222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError("Empty escape sequence in string", token, current); 6232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char escape = *current++; 6242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger switch (escape) { 6252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '"': 6262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '"'; 6272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '/': 6292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '/'; 6302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6312eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case '\\': 6322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '\\'; 6332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 'b': 6352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '\b'; 6362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 'f': 6382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '\f'; 6392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 'n': 6412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '\n'; 6422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 'r': 6442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '\r'; 6452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 't': 6472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += '\t'; 6482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 6492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger case 'u': { 6502eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unsigned int unicode; 6512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!decodeUnicodeCodePoint(token, current, end, unicode)) 6522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 6532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += codePointToUTF8(unicode); 6542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } break; 6552eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger default: 6562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError("Bad escape sequence in string", token, current); 657f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III } 6582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else { 6592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger decoded += c; 6602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 6612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 6622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 6632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 6642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 6652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeUnicodeCodePoint(Token& token, 6662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location& current, 6672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location end, 6682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unsigned int& unicode) { 6692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 6702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) 6712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 6722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (unicode >= 0xD800 && unicode <= 0xDBFF) { 6732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // surrogate pairs 6742eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (end - current < 6) 6752eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError( 6762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "additional six characters expected to parse unicode surrogate pair.", 6772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token, 6782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger current); 6792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unsigned int surrogatePair; 6802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (*(current++) == '\\' && *(current++) == 'u') { 6812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { 6822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); 6832eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else 6842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 6852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else 6862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError("expecting another \\u token to begin the second half of " 6872eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "a unicode surrogate pair", 6882eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token, 6892eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger current); 6902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 6912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 6922eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 6932eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 6942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::decodeUnicodeEscapeSequence(Token& token, 6952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location& current, 6962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location end, 6972eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unsigned int& unicode) { 6982eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (end - current < 4) 6992eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError( 7002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "Bad unicode escape sequence in string: four digits expected.", 7012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token, 7022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger current); 7032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unicode = 0; 7042eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger for (int index = 0; index < 4; ++index) { 7052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = *current++; 7062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unicode *= 16; 7072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c >= '0' && c <= '9') 7082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unicode += c - '0'; 7092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else if (c >= 'a' && c <= 'f') 7102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unicode += c - 'a' + 10; 7112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else if (c >= 'A' && c <= 'F') 7122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger unicode += c - 'A' + 10; 7132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger else 7142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return addError( 7152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "Bad unicode escape sequence in string: hexadecimal digit expected.", 7162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token, 7172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger current); 7182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 7192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 720f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 721f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 722f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins IIIbool 7232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerReader::addError(const std::string& message, Token& token, Location extra) { 7242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ErrorInfo info; 7252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.token_ = token; 7262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.message_ = message; 7272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.extra_ = extra; 7282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger errors_.push_back(info); 7292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 7302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 7312eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 7322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::recoverFromError(TokenType skipUntilToken) { 7332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int errorCount = int(errors_.size()); 7342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token skip; 7352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger for (;;) { 7362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!readToken(skip)) 7372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger errors_.resize(errorCount); // discard errors caused by recovery 7382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) 7392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger break; 7402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 7412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger errors_.resize(errorCount); 7422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 7432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 7442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 7452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::addErrorAndRecover(const std::string& message, 7462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token& token, 7472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger TokenType skipUntilToken) { 7482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger addError(message, token); 7492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return recoverFromError(skipUntilToken); 7502eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 7512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 7522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerValue& Reader::currentValue() { return *(nodes_.top()); } 7532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 7542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek SollenbergerReader::Char Reader::getNextChar() { 7552eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (current_ == end_) 7562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return 0; 7572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return *current_++; 7582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 7592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 7602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergervoid Reader::getLocationLineAndColumn(Location location, 7612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int& line, 7622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int& column) const { 7632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location current = begin_; 7642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Location lastLineStart = current; 7652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger line = 0; 7662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger while (current < location && current != end_) { 7672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Char c = *current++; 7682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (c == '\r') { 7692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (*current == '\n') 7702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++current; 7712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastLineStart = current; 7722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++line; 7732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } else if (c == '\n') { 7742eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger lastLineStart = current; 7752eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++line; 7762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 7772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 7782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger // column & line start at 1 7792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger column = int(location - lastLineStart) + 1; 7802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++line; 7812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 7822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 7832eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstd::string Reader::getLocationLineAndColumn(Location location) const { 7842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger int line, column; 7852eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger getLocationLineAndColumn(location, line, column); 7862eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger char buffer[18 + 16 + 16 + 1]; 7872eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) 7882eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#if defined(WINCE) 7892eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); 7902eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#else 7912eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column); 7922eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#endif 7932eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#else 7942eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); 7952eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger#endif 7962eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return buffer; 797f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 798f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 799f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III// Deprecated. Preserved for backward compatibility 8002eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstd::string Reader::getFormatedErrorMessages() const { 8012eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return getFormattedErrorMessages(); 8022eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 8032eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 8042eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstd::string Reader::getFormattedErrorMessages() const { 8052eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger std::string formattedMessage; 8062eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger for (Errors::const_iterator itError = errors_.begin(); 8072eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger itError != errors_.end(); 8082eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++itError) { 8092eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger const ErrorInfo& error = *itError; 8102eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger formattedMessage += 8112eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; 8122eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger formattedMessage += " " + error.message_ + "\n"; 8132eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (error.extra_) 8142eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger formattedMessage += 8152eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; 8162eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 8172eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return formattedMessage; 8182eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 8192eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 8202eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstd::vector<Reader::StructuredError> Reader::getStructuredErrors() const { 8212eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger std::vector<Reader::StructuredError> allErrors; 8222eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger for (Errors::const_iterator itError = errors_.begin(); 8232eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger itError != errors_.end(); 8242eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ++itError) { 8252eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger const ErrorInfo& error = *itError; 8262eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Reader::StructuredError structured; 8272eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger structured.offset_start = error.token_.start_ - begin_; 8282eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger structured.offset_limit = error.token_.end_ - begin_; 8292eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger structured.message = error.message_; 8302eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger allErrors.push_back(structured); 8312eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 8322eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return allErrors; 8332eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 8342eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 8352eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::pushError(const Value& value, const std::string& message) { 8362eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger size_t length = end_ - begin_; 8372eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if(value.getOffsetStart() > length 8382eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger || value.getOffsetLimit() > length) 8392eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 8402eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token token; 8412eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenError; 8422eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.start_ = begin_ + value.getOffsetStart(); 8432eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.end_ = end_ + value.getOffsetLimit(); 8442eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ErrorInfo info; 8452eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.token_ = token; 8462eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.message_ = message; 8472eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.extra_ = 0; 8482eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger errors_.push_back(info); 8492eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 8502eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 8512eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 8522eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::pushError(const Value& value, const std::string& message, const Value& extra) { 8532eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger size_t length = end_ - begin_; 8542eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if(value.getOffsetStart() > length 8552eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger || value.getOffsetLimit() > length 8562eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger || extra.getOffsetLimit() > length) 8572eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return false; 8582eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Token token; 8592eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.type_ = tokenError; 8602eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.start_ = begin_ + value.getOffsetStart(); 8612eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger token.end_ = begin_ + value.getOffsetLimit(); 8622eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger ErrorInfo info; 8632eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.token_ = token; 8642eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.message_ = message; 8652eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger info.extra_ = begin_ + extra.getOffsetStart(); 8662eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger errors_.push_back(info); 8672eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return true; 8682eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 8692eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 8702eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerbool Reader::good() const { 8712eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return !errors_.size(); 8722eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger} 8732eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 8742eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenbergerstd::istream& operator>>(std::istream& sin, Value& root) { 8752eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger Json::Reader reader; 8762eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger bool ok = reader.parse(sin, root, true); 8772eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger if (!ok) { 8782eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger fprintf(stderr, 8792eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger "Error from reader: %s", 8802eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger reader.getFormattedErrorMessages().c_str()); 8812eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger 8822eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger JSON_FAIL_MESSAGE("reader error"); 8832eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger } 8842eb3b4d7ea1a3cbb0f8775de3b6d92c0a6152f9fDerek Sollenberger return sin; 885f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} 886f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III 887f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2eLeon Scroggins III} // namespace Json 888