Skip to content

Commit 26e089b

Browse files
StilesCrisisStilesCrisis
authored andcommitted
Merge remote-tracking branch 'miloyip/master'
2 parents 933eb83 + 97e2f7f commit 26e089b

File tree

9 files changed

+374
-104
lines changed

9 files changed

+374
-104
lines changed

example/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ set(EXAMPLES
1818
serialize
1919
simpledom
2020
simplereader
21+
simplepullreader
2122
simplewriter
2223
tutorial)
2324

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include "rapidjson/reader.h"
2+
#include <iostream>
3+
#include <sstream>
4+
5+
using namespace rapidjson;
6+
using namespace std;
7+
8+
// If you can require C++11, you could use std::to_string here
9+
template <typename T> std::string stringify(T x) {
10+
std::stringstream ss;
11+
ss << x;
12+
return ss.str();
13+
}
14+
15+
struct MyHandler {
16+
const char* type;
17+
std::string data;
18+
19+
bool Null() { type = "Null"; data.clear(); return true; }
20+
bool Bool(bool b) { type = "Bool:"; data = b? "true": "false"; return true; }
21+
bool Int(int i) { type = "Int:"; data = stringify(i); return true; }
22+
bool Uint(unsigned u) { type = "Uint:"; data = stringify(u); return true; }
23+
bool Int64(int64_t i) { type = "Int64:"; data = stringify(i); return true; }
24+
bool Uint64(uint64_t u) { type = "Uint64:"; data = stringify(u); return true; }
25+
bool Double(double d) { type = "Double:"; data = stringify(d); return true; }
26+
bool RawNumber(const char* str, SizeType length, bool) { type = "Number:"; data = std::string(str, length); return true; }
27+
bool String(const char* str, SizeType length, bool) { type = "String:"; data = std::string(str, length); return true; }
28+
bool StartObject() { type = "StartObject"; data.clear(); return true; }
29+
bool Key(const char* str, SizeType length, bool) { type = "Key:"; data = std::string(str, length); return true; }
30+
bool EndObject(SizeType memberCount) { type = "EndObject:"; data = stringify(memberCount); return true; }
31+
bool StartArray() { type = "StartArray"; data.clear(); return true; }
32+
bool EndArray(SizeType elementCount) { type = "EndArray:"; data = stringify(elementCount); return true; }
33+
};
34+
35+
int main() {
36+
const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ";
37+
38+
MyHandler handler;
39+
Reader reader;
40+
StringStream ss(json);
41+
reader.IterativeParseInit();
42+
while (!reader.IterativeParseComplete()) {
43+
reader.IterativeParseNext<kParseDefaultFlags>(ss, handler);
44+
cout << handler.type << handler.data << endl;
45+
}
46+
47+
return 0;
48+
}

include/rapidjson/pointer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ class GenericPointer {
240240
template <typename T>
241241
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
242242
Append(T* name, Allocator* allocator = 0) const {
243-
return Append(name, StrLen(name), allocator);
243+
return Append(name, internal::StrLen(name), allocator);
244244
}
245245

246246
#if RAPIDJSON_HAS_STDSTRING

include/rapidjson/reader.h

Lines changed: 171 additions & 74 deletions
Large diffs are not rendered by default.

include/rapidjson/schema.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ class Schema {
880880
#define RAPIDJSON_STRING_(name, ...) \
881881
static const ValueType& Get##name##String() {\
882882
static const Ch s[] = { __VA_ARGS__, '\0' };\
883-
static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\
883+
static const ValueType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1));\
884884
return v;\
885885
}
886886

rapidjson.autopkg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,7 @@ Changed
7171
targets {
7272
// We're trying to be standard about these sorts of thing. (Will help with config.h later :D)
7373
//Defines += HAS_EQCORE;
74+
// Fix creating the package with Raggles' fork of CoApp
75+
Includes += "$(MSBuildThisFileDirectory)../..${d_include}";
7476
};
7577
}

test/perftest/rapidjsontest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,35 @@ TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativeInsitu_DummyHandler)) {
152152
}
153153
}
154154

155+
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativePull_DummyHandler)) {
156+
for (size_t i = 0; i < kTrialCount; i++) {
157+
StringStream s(json_);
158+
BaseReaderHandler<> h;
159+
Reader reader;
160+
reader.IterativeParseInit();
161+
while (!reader.IterativeParseComplete()) {
162+
if (!reader.IterativeParseNext<kParseDefaultFlags>(s, h))
163+
break;
164+
}
165+
EXPECT_FALSE(reader.HasParseError());
166+
}
167+
}
168+
169+
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativePullInsitu_DummyHandler)) {
170+
for (size_t i = 0; i < kTrialCount; i++) {
171+
memcpy(temp_, json_, length_ + 1);
172+
InsituStringStream s(temp_);
173+
BaseReaderHandler<> h;
174+
Reader reader;
175+
reader.IterativeParseInit();
176+
while (!reader.IterativeParseComplete()) {
177+
if (!reader.IterativeParseNext<kParseDefaultFlags|kParseInsituFlag>(s, h))
178+
break;
179+
}
180+
EXPECT_FALSE(reader.HasParseError());
181+
}
182+
}
183+
155184
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_ValidateEncoding)) {
156185
for (size_t i = 0; i < kTrialCount; i++) {
157186
StringStream s(json_);

test/unittest/jsoncheckertest.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,24 @@ static char* ReadFile(const char* filename, size_t& length) {
4848
return json;
4949
}
5050

51+
struct NoOpHandler {
52+
bool Null() { return true; }
53+
bool Bool(bool) { return true; }
54+
bool Int(int) { return true; }
55+
bool Uint(unsigned) { return true; }
56+
bool Int64(int64_t) { return true; }
57+
bool Uint64(uint64_t) { return true; }
58+
bool Double(double) { return true; }
59+
bool RawNumber(const char*, SizeType, bool) { return true; }
60+
bool String(const char*, SizeType, bool) { return true; }
61+
bool StartObject() { return true; }
62+
bool Key(const char*, SizeType, bool) { return true; }
63+
bool EndObject(SizeType) { return true; }
64+
bool StartArray() { return true; }
65+
bool EndArray(SizeType) { return true; }
66+
};
67+
68+
5169
TEST(JsonChecker, Reader) {
5270
char filename[256];
5371

@@ -67,13 +85,26 @@ TEST(JsonChecker, Reader) {
6785
continue;
6886
}
6987

88+
// Test stack-based parsing.
7089
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
7190
document.Parse(json);
7291
EXPECT_TRUE(document.HasParseError()) << filename;
7392

93+
// Test iterative parsing.
7494
document.Parse<kParseIterativeFlag>(json);
7595
EXPECT_TRUE(document.HasParseError()) << filename;
7696

97+
// Test iterative pull-parsing.
98+
Reader reader;
99+
StringStream ss(json);
100+
NoOpHandler h;
101+
reader.IterativeParseInit();
102+
while (!reader.IterativeParseComplete()) {
103+
if (!reader.IterativeParseNext<kParseDefaultFlags>(ss, h))
104+
break;
105+
}
106+
EXPECT_TRUE(reader.HasParseError()) << filename;
107+
77108
free(json);
78109
}
79110

@@ -87,12 +118,25 @@ TEST(JsonChecker, Reader) {
87118
continue;
88119
}
89120

121+
// Test stack-based parsing.
90122
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
91123
document.Parse(json);
92124
EXPECT_FALSE(document.HasParseError()) << filename;
93125

126+
// Test iterative parsing.
94127
document.Parse<kParseIterativeFlag>(json);
95128
EXPECT_FALSE(document.HasParseError()) << filename;
129+
130+
// Test iterative pull-parsing.
131+
Reader reader;
132+
StringStream ss(json);
133+
NoOpHandler h;
134+
reader.IterativeParseInit();
135+
while (!reader.IterativeParseComplete()) {
136+
if (!reader.IterativeParseNext<kParseDefaultFlags>(ss, h))
137+
break;
138+
}
139+
EXPECT_FALSE(reader.HasParseError()) << filename;
96140

97141
free(json);
98142
}

test/unittest/readertest.cpp

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,22 +1157,22 @@ template<typename Encoding = UTF8<> >
11571157
struct IterativeParsingReaderHandler {
11581158
typedef typename Encoding::Ch Ch;
11591159

1160-
const static int LOG_NULL = -1;
1161-
const static int LOG_BOOL = -2;
1162-
const static int LOG_INT = -3;
1163-
const static int LOG_UINT = -4;
1164-
const static int LOG_INT64 = -5;
1165-
const static int LOG_UINT64 = -6;
1166-
const static int LOG_DOUBLE = -7;
1167-
const static int LOG_STRING = -8;
1168-
const static int LOG_STARTOBJECT = -9;
1169-
const static int LOG_KEY = -10;
1170-
const static int LOG_ENDOBJECT = -11;
1171-
const static int LOG_STARTARRAY = -12;
1172-
const static int LOG_ENDARRAY = -13;
1160+
const static uint32_t LOG_NULL = 0x10000000;
1161+
const static uint32_t LOG_BOOL = 0x20000000;
1162+
const static uint32_t LOG_INT = 0x30000000;
1163+
const static uint32_t LOG_UINT = 0x40000000;
1164+
const static uint32_t LOG_INT64 = 0x50000000;
1165+
const static uint32_t LOG_UINT64 = 0x60000000;
1166+
const static uint32_t LOG_DOUBLE = 0x70000000;
1167+
const static uint32_t LOG_STRING = 0x80000000;
1168+
const static uint32_t LOG_STARTOBJECT = 0x90000000;
1169+
const static uint32_t LOG_KEY = 0xA0000000;
1170+
const static uint32_t LOG_ENDOBJECT = 0xB0000000;
1171+
const static uint32_t LOG_STARTARRAY = 0xC0000000;
1172+
const static uint32_t LOG_ENDARRAY = 0xD0000000;
11731173

11741174
const static size_t LogCapacity = 256;
1175-
int Logs[LogCapacity];
1175+
uint32_t Logs[LogCapacity];
11761176
size_t LogCount;
11771177

11781178
IterativeParsingReaderHandler() : LogCount(0) {
@@ -1202,17 +1202,17 @@ struct IterativeParsingReaderHandler {
12021202

12031203
bool EndObject(SizeType c) {
12041204
RAPIDJSON_ASSERT(LogCount < LogCapacity);
1205-
Logs[LogCount++] = LOG_ENDOBJECT;
1206-
Logs[LogCount++] = static_cast<int>(c);
1205+
RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1206+
Logs[LogCount++] = LOG_ENDOBJECT | static_cast<uint32_t>(c);
12071207
return true;
12081208
}
12091209

12101210
bool StartArray() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTARRAY; return true; }
12111211

12121212
bool EndArray(SizeType c) {
12131213
RAPIDJSON_ASSERT(LogCount < LogCapacity);
1214-
Logs[LogCount++] = LOG_ENDARRAY;
1215-
Logs[LogCount++] = static_cast<int>(c);
1214+
RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1215+
Logs[LogCount++] = LOG_ENDARRAY | static_cast<uint32_t>(c);
12161216
return true;
12171217
}
12181218
};
@@ -1228,22 +1228,22 @@ TEST(Reader, IterativeParsing_General) {
12281228
EXPECT_FALSE(r.IsError());
12291229
EXPECT_FALSE(reader.HasParseError());
12301230

1231-
int e[] = {
1231+
uint32_t e[] = {
12321232
handler.LOG_STARTARRAY,
12331233
handler.LOG_INT,
12341234
handler.LOG_STARTOBJECT,
12351235
handler.LOG_KEY,
12361236
handler.LOG_STARTARRAY,
12371237
handler.LOG_INT,
12381238
handler.LOG_INT,
1239-
handler.LOG_ENDARRAY, 2,
1240-
handler.LOG_ENDOBJECT, 1,
1239+
handler.LOG_ENDARRAY | 2,
1240+
handler.LOG_ENDOBJECT | 1,
12411241
handler.LOG_NULL,
12421242
handler.LOG_BOOL,
12431243
handler.LOG_BOOL,
12441244
handler.LOG_STRING,
12451245
handler.LOG_DOUBLE,
1246-
handler.LOG_ENDARRAY, 7
1246+
handler.LOG_ENDARRAY | 7
12471247
};
12481248

12491249
EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
@@ -1265,20 +1265,20 @@ TEST(Reader, IterativeParsing_Count) {
12651265
EXPECT_FALSE(r.IsError());
12661266
EXPECT_FALSE(reader.HasParseError());
12671267

1268-
int e[] = {
1268+
uint32_t e[] = {
12691269
handler.LOG_STARTARRAY,
12701270
handler.LOG_STARTOBJECT,
1271-
handler.LOG_ENDOBJECT, 0,
1271+
handler.LOG_ENDOBJECT | 0,
12721272
handler.LOG_STARTOBJECT,
12731273
handler.LOG_KEY,
12741274
handler.LOG_INT,
1275-
handler.LOG_ENDOBJECT, 1,
1275+
handler.LOG_ENDOBJECT | 1,
12761276
handler.LOG_STARTARRAY,
12771277
handler.LOG_INT,
1278-
handler.LOG_ENDARRAY, 1,
1278+
handler.LOG_ENDARRAY | 1,
12791279
handler.LOG_STARTARRAY,
1280-
handler.LOG_ENDARRAY, 0,
1281-
handler.LOG_ENDARRAY, 4
1280+
handler.LOG_ENDARRAY | 0,
1281+
handler.LOG_ENDARRAY | 4
12821282
};
12831283

12841284
EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
@@ -1289,6 +1289,51 @@ TEST(Reader, IterativeParsing_Count) {
12891289
}
12901290
}
12911291

1292+
TEST(Reader, IterativePullParsing_General) {
1293+
{
1294+
IterativeParsingReaderHandler<> handler;
1295+
uint32_t e[] = {
1296+
handler.LOG_STARTARRAY,
1297+
handler.LOG_INT,
1298+
handler.LOG_STARTOBJECT,
1299+
handler.LOG_KEY,
1300+
handler.LOG_STARTARRAY,
1301+
handler.LOG_INT,
1302+
handler.LOG_INT,
1303+
handler.LOG_ENDARRAY | 2,
1304+
handler.LOG_ENDOBJECT | 1,
1305+
handler.LOG_NULL,
1306+
handler.LOG_BOOL,
1307+
handler.LOG_BOOL,
1308+
handler.LOG_STRING,
1309+
handler.LOG_DOUBLE,
1310+
handler.LOG_ENDARRAY | 7
1311+
};
1312+
1313+
StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1314+
Reader reader;
1315+
1316+
reader.IterativeParseInit();
1317+
while (!reader.IterativeParseComplete()) {
1318+
size_t oldLogCount = handler.LogCount;
1319+
EXPECT_TRUE(oldLogCount < sizeof(e) / sizeof(int)) << "overrun";
1320+
1321+
EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse fail";
1322+
EXPECT_EQ(handler.LogCount, oldLogCount + 1) << "handler should be invoked exactly once each time";
1323+
EXPECT_EQ(e[oldLogCount], handler.Logs[oldLogCount]) << "wrong event returned";
1324+
}
1325+
1326+
EXPECT_FALSE(reader.HasParseError());
1327+
EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount) << "handler invoked wrong number of times";
1328+
1329+
// The handler should not be invoked when the JSON has been fully read, but it should not fail
1330+
size_t oldLogCount = handler.LogCount;
1331+
EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse-next past complete is allowed";
1332+
EXPECT_EQ(handler.LogCount, oldLogCount) << "parse-next past complete should not invoke handler";
1333+
EXPECT_FALSE(reader.HasParseError()) << "parse-next past complete should not generate parse error";
1334+
}
1335+
}
1336+
12921337
// Test iterative parsing on kParseErrorTermination.
12931338
struct HandlerTerminateAtStartObject : public IterativeParsingReaderHandler<> {
12941339
bool StartObject() { return false; }
@@ -1832,6 +1877,10 @@ TEST(Reader, ParseNanAndInfinity) {
18321877
TEST_NAN_INF("Infinity", inf);
18331878
TEST_NAN_INF("-Inf", -inf);
18341879
TEST_NAN_INF("-Infinity", -inf);
1880+
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NInf", 1);
1881+
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NaInf", 2);
1882+
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "INan", 1);
1883+
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "InNan", 2);
18351884
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "nan", 1);
18361885
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "-nan", 1);
18371886
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NAN", 1);

0 commit comments

Comments
 (0)