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,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& s) | @@ -1405,7 +1407,7 @@ JSON::parse(std::string const& 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 |