Merge pull request #183 from open-source-parsers/allow-single-quote

Allow single quote
This commit is contained in:
Christopher Dunn 2015-02-24 18:24:42 -06:00
commit 7d1f656859
3 changed files with 67 additions and 14 deletions

View File

@ -310,6 +310,8 @@ public:
- true if dropped null placeholders are allowed. (See StreamWriterBuilder.) - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
- `"allowNumericKeys": false or true` - `"allowNumericKeys": false or true`
- true if numeric object keys are allowed. - true if numeric object keys are allowed.
- `"allowSingleQuotes": false or true`
- true if '' are allowed for strings (both keys and values)
- `"stackLimit": integer` - `"stackLimit": integer`
- Exceeding stackLimit (recursive depth of `readValue()`) will - Exceeding stackLimit (recursive depth of `readValue()`) will
cause an exception. cause an exception.

View File

@ -909,12 +909,12 @@ bool Reader::good() const {
class OurFeatures { class OurFeatures {
public: public:
static OurFeatures all(); static OurFeatures all();
static OurFeatures strictMode();
OurFeatures(); OurFeatures();
bool allowComments_; bool allowComments_;
bool strictRoot_; bool strictRoot_;
bool allowDroppedNullPlaceholders_; bool allowDroppedNullPlaceholders_;
bool allowNumericKeys_; bool allowNumericKeys_;
bool allowSingleQuotes_;
bool failIfExtra_; bool failIfExtra_;
int stackLimit_; int stackLimit_;
}; // OurFeatures }; // OurFeatures
@ -923,20 +923,15 @@ public:
// //////////////////////////////// // ////////////////////////////////
OurFeatures::OurFeatures() OurFeatures::OurFeatures()
: allowComments_(true), strictRoot_(false), : allowComments_(true), strictRoot_(false)
allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} , allowDroppedNullPlaceholders_(false), allowNumericKeys_(false)
, allowSingleQuotes_(false)
, failIfExtra_(false)
{
}
OurFeatures OurFeatures::all() { return OurFeatures(); } OurFeatures OurFeatures::all() { return OurFeatures(); }
OurFeatures OurFeatures::strictMode() {
OurFeatures features;
features.allowComments_ = false;
features.strictRoot_ = true;
features.allowDroppedNullPlaceholders_ = false;
features.allowNumericKeys_ = false;
return features;
}
// Implementation of class Reader // Implementation of class Reader
// //////////////////////////////// // ////////////////////////////////
@ -1006,6 +1001,7 @@ private:
bool readCStyleComment(); bool readCStyleComment();
bool readCppStyleComment(); bool readCppStyleComment();
bool readString(); bool readString();
bool readStringSingleQuote();
void readNumber(); void readNumber();
bool readValue(); bool readValue();
bool readObject(Token& token); bool readObject(Token& token);
@ -1220,6 +1216,12 @@ bool OurReader::readToken(Token& token) {
token.type_ = tokenString; token.type_ = tokenString;
ok = readString(); ok = readString();
break; break;
case '\'':
if (features_.allowSingleQuotes_) {
token.type_ = tokenString;
ok = readStringSingleQuote();
break;
} // else continue
case '/': case '/':
token.type_ = tokenComment; token.type_ = tokenComment;
ok = readComment(); ok = readComment();
@ -1371,7 +1373,6 @@ void OurReader::readNumber() {
c = (current_ = p) < end_ ? *p++ : 0; c = (current_ = p) < end_ ? *p++ : 0;
} }
} }
bool OurReader::readString() { bool OurReader::readString() {
Char c = 0; Char c = 0;
while (current_ != end_) { while (current_ != end_) {
@ -1384,6 +1385,19 @@ bool OurReader::readString() {
return c == '"'; return c == '"';
} }
bool OurReader::readStringSingleQuote() {
Char c = 0;
while (current_ != end_) {
c = getNextChar();
if (c == '\\')
getNextChar();
else if (c == '\'')
break;
}
return c == '\'';
}
bool OurReader::readObject(Token& tokenStart) { bool OurReader::readObject(Token& tokenStart) {
Token tokenName; Token tokenName;
std::string name; std::string name;
@ -1878,6 +1892,7 @@ CharReader* CharReaderBuilder::newCharReader() const
features.strictRoot_ = settings_["strictRoot"].asBool(); features.strictRoot_ = settings_["strictRoot"].asBool();
features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool();
features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
features.stackLimit_ = settings_["stackLimit"].asInt(); features.stackLimit_ = settings_["stackLimit"].asInt();
features.failIfExtra_ = settings_["failIfExtra"].asBool(); features.failIfExtra_ = settings_["failIfExtra"].asBool();
return new OurCharReader(collectComments, features); return new OurCharReader(collectComments, features);
@ -1890,6 +1905,7 @@ static void getValidReaderKeys(std::set<std::string>* valid_keys)
valid_keys->insert("strictRoot"); valid_keys->insert("strictRoot");
valid_keys->insert("allowDroppedNullPlaceholders"); valid_keys->insert("allowDroppedNullPlaceholders");
valid_keys->insert("allowNumericKeys"); valid_keys->insert("allowNumericKeys");
valid_keys->insert("allowSingleQuotes");
valid_keys->insert("stackLimit"); valid_keys->insert("stackLimit");
valid_keys->insert("failIfExtra"); valid_keys->insert("failIfExtra");
} }
@ -1919,6 +1935,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
(*settings)["strictRoot"] = true; (*settings)["strictRoot"] = true;
(*settings)["allowDroppedNullPlaceholders"] = false; (*settings)["allowDroppedNullPlaceholders"] = false;
(*settings)["allowNumericKeys"] = false; (*settings)["allowNumericKeys"] = false;
(*settings)["allowSingleQuotes"] = false;
(*settings)["failIfExtra"] = true; (*settings)["failIfExtra"] = true;
//! [CharReaderBuilderStrictMode] //! [CharReaderBuilderStrictMode]
} }
@ -1931,6 +1948,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
(*settings)["strictRoot"] = false; (*settings)["strictRoot"] = false;
(*settings)["allowDroppedNullPlaceholders"] = false; (*settings)["allowDroppedNullPlaceholders"] = false;
(*settings)["allowNumericKeys"] = false; (*settings)["allowNumericKeys"] = false;
(*settings)["allowSingleQuotes"] = false;
(*settings)["stackLimit"] = 1000; (*settings)["stackLimit"] = 1000;
(*settings)["failIfExtra"] = false; (*settings)["failIfExtra"] = false;
//! [CharReaderBuilderDefaults] //! [CharReaderBuilderDefaults]

View File

@ -1861,7 +1861,6 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) {
JSONTEST_ASSERT_EQUAL(true, root.asBool()); JSONTEST_ASSERT_EQUAL(true, root.asBool());
delete reader; delete reader;
} }
struct CharReaderAllowDropNullTest : JsonTest::TestCase {}; struct CharReaderAllowDropNullTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
@ -2014,6 +2013,38 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) {
delete reader; delete reader;
} }
struct CharReaderAllowSingleQuotesTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) {
Json::CharReaderBuilder b;
b.settings_["allowSingleQuotes"] = true;
Json::Value root;
std::string errs;
Json::CharReader* reader(b.newCharReader());
{
char const doc[] = "{'a':true,\"b\":true}";
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size());
JSONTEST_ASSERT_EQUAL(true, root.get("a", false));
JSONTEST_ASSERT_EQUAL(true, root.get("b", false));
}
{
char const doc[] = "{'a': 'x', \"b\":'y'}";
bool ok = reader->parse(
doc, doc + std::strlen(doc),
&root, &errs);
JSONTEST_ASSERT(ok);
JSONTEST_ASSERT_STRING_EQUAL("", errs);
JSONTEST_ASSERT_EQUAL(2u, root.size());
JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString());
JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString());
}
}
struct IteratorTest : JsonTest::TestCase {}; struct IteratorTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(IteratorTest, distance) { JSONTEST_FIXTURE(IteratorTest, distance) {
@ -2079,6 +2110,8 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowDropNullTest, issue178); JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowDropNullTest, issue178);
JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowSingleQuotesTest, issue182);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance); JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance);
return runner.runCommandLine(argc, argv); return runner.runCommandLine(argc, argv);