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