Commit b6f048546f7ffdd228bd9360c647b3064dfa1bf3

Authored by m-holger
1 parent f6c90195

Eliminate the use of shared pointers in JSONParser

include/qpdf/JSON.hh
@@ -54,6 +54,7 @@ class JSON @@ -54,6 +54,7 @@ class JSON
54 { 54 {
55 public: 55 public:
56 static int constexpr LATEST = 2; 56 static int constexpr LATEST = 2;
  57 + JSON() = default;
57 58
58 QPDF_DLL 59 QPDF_DLL
59 std::string unparse() const; 60 std::string unparse() const;
libqpdf/JSON.cc
@@ -602,7 +602,7 @@ namespace @@ -602,7 +602,7 @@ namespace
602 { 602 {
603 } 603 }
604 604
605 - std::shared_ptr<JSON> parse(); 605 + JSON parse();
606 606
607 private: 607 private:
608 enum parser_state_e { 608 enum parser_state_e {
@@ -642,14 +642,14 @@ namespace @@ -642,14 +642,14 @@ namespace
642 642
643 struct StackFrame 643 struct StackFrame
644 { 644 {
645 - StackFrame(parser_state_e state, std::shared_ptr<JSON>& item) : 645 + StackFrame(parser_state_e state, JSON& item) :
646 state(state), 646 state(state),
647 item(item) 647 item(item)
648 { 648 {
649 } 649 }
650 650
651 parser_state_e state; 651 parser_state_e state;
652 - std::shared_ptr<JSON> item; 652 + JSON item;
653 }; 653 };
654 654
655 void getToken(); 655 void getToken();
@@ -860,6 +860,7 @@ JSONParser::getToken() @@ -860,6 +860,7 @@ JSONParser::getToken()
860 } else { 860 } else {
861 break; 861 break;
862 } 862 }
  863 +
863 } else { 864 } else {
864 QTC::TC("libtests", "JSON parse null character"); 865 QTC::TC("libtests", "JSON parse null character");
865 throw std::runtime_error( 866 throw std::runtime_error(
@@ -1169,18 +1170,19 @@ JSONParser::handleToken() @@ -1169,18 +1170,19 @@ JSONParser::handleToken()
1169 ": material follows end of object: " + token); 1170 ": material follows end of object: " + token);
1170 } 1171 }
1171 1172
1172 - std::shared_ptr<JSON> item;  
1173 - auto tos = stack.empty() ? nullptr : stack.back().item; 1173 + const static JSON null_item = JSON::makeNull();
  1174 + JSON item;
  1175 + auto tos = stack.empty() ? null_item : stack.back().item;
1174 auto ls = lex_state; 1176 auto ls = lex_state;
1175 lex_state = ls_top; 1177 lex_state = ls_top;
1176 1178
1177 switch (ls) { 1179 switch (ls) {
1178 case ls_begin_dict: 1180 case ls_begin_dict:
1179 - item = std::make_shared<JSON>(JSON::makeDictionary()); 1181 + item = JSON::makeDictionary();
1180 break; 1182 break;
1181 1183
1182 case ls_begin_array: 1184 case ls_begin_array:
1183 - item = std::make_shared<JSON>(JSON::makeArray()); 1185 + item = JSON::makeArray();
1184 break; 1186 break;
1185 1187
1186 case ls_colon: 1188 case ls_colon:
@@ -1220,9 +1222,9 @@ JSONParser::handleToken() @@ -1220,9 +1222,9 @@ JSONParser::handleToken()
1220 ": unexpected array end delimiter"); 1222 ": unexpected array end delimiter");
1221 } 1223 }
1222 parser_state = stack.back().state; 1224 parser_state = stack.back().state;
1223 - tos->setEnd(offset); 1225 + tos.setEnd(offset);
1224 if (reactor) { 1226 if (reactor) {
1225 - reactor->containerEnd(*tos); 1227 + reactor->containerEnd(tos);
1226 } 1228 }
1227 if (parser_state != ps_done) { 1229 if (parser_state != ps_done) {
1228 stack.pop_back(); 1230 stack.pop_back();
@@ -1238,9 +1240,9 @@ JSONParser::handleToken() @@ -1238,9 +1240,9 @@ JSONParser::handleToken()
1238 ": unexpected dictionary end delimiter"); 1240 ": unexpected dictionary end delimiter");
1239 } 1241 }
1240 parser_state = stack.back().state; 1242 parser_state = stack.back().state;
1241 - tos->setEnd(offset); 1243 + tos.setEnd(offset);
1242 if (reactor) { 1244 if (reactor) {
1243 - reactor->containerEnd(*tos); 1245 + reactor->containerEnd(tos);
1244 } 1246 }
1245 if (parser_state != ps_done) { 1247 if (parser_state != ps_done) {
1246 stack.pop_back(); 1248 stack.pop_back();
@@ -1248,16 +1250,16 @@ JSONParser::handleToken() @@ -1248,16 +1250,16 @@ JSONParser::handleToken()
1248 return; 1250 return;
1249 1251
1250 case ls_number: 1252 case ls_number:
1251 - item = std::make_shared<JSON>(JSON::makeNumber(token)); 1253 + item = JSON::makeNumber(token);
1252 break; 1254 break;
1253 1255
1254 case ls_alpha: 1256 case ls_alpha:
1255 if (token == "true") { 1257 if (token == "true") {
1256 - item = std::make_shared<JSON>(JSON::makeBool(true)); 1258 + item = JSON::makeBool(true);
1257 } else if (token == "false") { 1259 } else if (token == "false") {
1258 - item = std::make_shared<JSON>(JSON::makeBool(false)); 1260 + item = JSON::makeBool(false);
1259 } else if (token == "null") { 1261 } else if (token == "null") {
1260 - item = std::make_shared<JSON>(JSON::makeNull()); 1262 + item = JSON::makeNull();
1261 } else { 1263 } else {
1262 QTC::TC("libtests", "JSON parse invalid keyword"); 1264 QTC::TC("libtests", "JSON parse invalid keyword");
1263 throw std::runtime_error( 1265 throw std::runtime_error(
@@ -1274,7 +1276,7 @@ JSONParser::handleToken() @@ -1274,7 +1276,7 @@ JSONParser::handleToken()
1274 parser_state = ps_dict_after_key; 1276 parser_state = ps_dict_after_key;
1275 return; 1277 return;
1276 } else { 1278 } else {
1277 - item = std::make_shared<JSON>(JSON::makeString(token)); 1279 + item = JSON::makeString(token);
1278 } 1280 }
1279 break; 1281 break;
1280 1282
@@ -1284,8 +1286,8 @@ JSONParser::handleToken() @@ -1284,8 +1286,8 @@ JSONParser::handleToken()
1284 break; 1286 break;
1285 } 1287 }
1286 1288
1287 - item->setStart(token_start);  
1288 - item->setEnd(offset); 1289 + item.setStart(token_start);
  1290 + item.setEnd(offset);
1289 1291
1290 switch (parser_state) { 1292 switch (parser_state) {
1291 case ps_dict_begin: 1293 case ps_dict_begin:
@@ -1297,28 +1299,28 @@ JSONParser::handleToken() @@ -1297,28 +1299,28 @@ JSONParser::handleToken()
1297 break; 1299 break;
1298 1300
1299 case ps_dict_after_colon: 1301 case ps_dict_after_colon:
1300 - if (tos->checkDictionaryKeySeen(dict_key)) { 1302 + if (tos.checkDictionaryKeySeen(dict_key)) {
1301 QTC::TC("libtests", "JSON parse duplicate key"); 1303 QTC::TC("libtests", "JSON parse duplicate key");
1302 throw std::runtime_error( 1304 throw std::runtime_error(
1303 "JSON: offset " + std::to_string(dict_key_offset) + 1305 "JSON: offset " + std::to_string(dict_key_offset) +
1304 ": duplicated dictionary key"); 1306 ": duplicated dictionary key");
1305 } 1307 }
1306 - if (!reactor || !reactor->dictionaryItem(dict_key, *item)) {  
1307 - tos->addDictionaryMember(dict_key, *item); 1308 + if (!reactor || !reactor->dictionaryItem(dict_key, item)) {
  1309 + tos.addDictionaryMember(dict_key, item);
1308 } 1310 }
1309 parser_state = ps_dict_after_item; 1311 parser_state = ps_dict_after_item;
1310 break; 1312 break;
1311 1313
1312 case ps_array_begin: 1314 case ps_array_begin:
1313 case ps_array_after_comma: 1315 case ps_array_after_comma:
1314 - if (!reactor || !reactor->arrayItem(*item)) {  
1315 - tos->addArrayElement(*item); 1316 + if (!reactor || !reactor->arrayItem(item)) {
  1317 + tos.addArrayElement(item);
1316 } 1318 }
1317 parser_state = ps_array_after_item; 1319 parser_state = ps_array_after_item;
1318 break; 1320 break;
1319 1321
1320 case ps_top: 1322 case ps_top:
1321 - if (!(item->isDictionary() || item->isArray())) { 1323 + if (!(item.isDictionary() || item.isArray())) {
1322 stack.push_back({ps_done, item}); 1324 stack.push_back({ps_done, item});
1323 parser_state = ps_done; 1325 parser_state = ps_done;
1324 return; 1326 return;
@@ -1349,18 +1351,18 @@ JSONParser::handleToken() @@ -1349,18 +1351,18 @@ JSONParser::handleToken()
1349 "JSONParser::handleToken: unexpected parser state"); 1351 "JSONParser::handleToken: unexpected parser state");
1350 } 1352 }
1351 1353
1352 - if (item->isDictionary() || item->isArray()) { 1354 + if (item.isDictionary() || item.isArray()) {
1353 stack.push_back({parser_state, item}); 1355 stack.push_back({parser_state, item});
1354 // Calling container start method is postponed until after 1356 // Calling container start method is postponed until after
1355 // adding the containers to their parent containers, if any. 1357 // adding the containers to their parent containers, if any.
1356 // This makes it much easier to keep track of the current 1358 // This makes it much easier to keep track of the current
1357 // nesting level. 1359 // nesting level.
1358 - if (item->isDictionary()) { 1360 + if (item.isDictionary()) {
1359 if (reactor) { 1361 if (reactor) {
1360 reactor->dictionaryStart(); 1362 reactor->dictionaryStart();
1361 } 1363 }
1362 parser_state = ps_dict_begin; 1364 parser_state = ps_dict_begin;
1363 - } else if (item->isArray()) { 1365 + } else if (item.isArray()) {
1364 if (reactor) { 1366 if (reactor) {
1365 reactor->arrayStart(); 1367 reactor->arrayStart();
1366 } 1368 }
@@ -1375,7 +1377,7 @@ JSONParser::handleToken() @@ -1375,7 +1377,7 @@ JSONParser::handleToken()
1375 } 1377 }
1376 } 1378 }
1377 1379
1378 -std::shared_ptr<JSON> 1380 +JSON
1379 JSONParser::parse() 1381 JSONParser::parse()
1380 { 1382 {
1381 while (!done) { 1383 while (!done) {
@@ -1387,7 +1389,7 @@ JSONParser::parse() @@ -1387,7 +1389,7 @@ JSONParser::parse()
1387 throw std::runtime_error("JSON: premature end of input"); 1389 throw std::runtime_error("JSON: premature end of input");
1388 } 1390 }
1389 auto const& tos = stack.back().item; 1391 auto const& tos = stack.back().item;
1390 - if (reactor && tos.get() && !(tos->isArray() || tos->isDictionary())) { 1392 + if (reactor && !(tos.isArray() || tos.isDictionary())) {
1391 reactor->topLevelScalar(); 1393 reactor->topLevelScalar();
1392 } 1394 }
1393 return tos; 1395 return tos;
@@ -1397,7 +1399,7 @@ JSON @@ -1397,7 +1399,7 @@ JSON
1397 JSON::parse(InputSource& is, Reactor* reactor) 1399 JSON::parse(InputSource& is, Reactor* reactor)
1398 { 1400 {
1399 JSONParser jp(is, reactor); 1401 JSONParser jp(is, reactor);
1400 - return *jp.parse(); 1402 + return jp.parse();
1401 } 1403 }
1402 1404
1403 JSON 1405 JSON
@@ -1405,7 +1407,7 @@ JSON::parse(std::string const&amp; s) @@ -1405,7 +1407,7 @@ JSON::parse(std::string const&amp; s)
1405 { 1407 {
1406 BufferInputSource bis("json input", s); 1408 BufferInputSource bis("json input", s);
1407 JSONParser jp(bis, nullptr); 1409 JSONParser jp(bis, nullptr);
1408 - return *jp.parse(); 1410 + return jp.parse();
1409 } 1411 }
1410 1412
1411 void 1413 void