Skip to content

Commit 203a1c1

Browse files
committed
merge bitcoin#26612: pass named argument value as string_view
1 parent 41eb3b0 commit 203a1c1

File tree

4 files changed

+31
-19
lines changed

4 files changed

+31
-19
lines changed

src/rpc/client.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
66

77
#include <rpc/client.h>
8+
#include <tinyformat.h>
89
#include <util/system.h>
910

1011
#include <set>
12+
#include <string>
13+
#include <string_view>
1114

1215
class CRPCConvertParam
1316
{
@@ -262,15 +265,15 @@ class CRPCConvertTable
262265
CRPCConvertTable();
263266

264267
/** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
265-
UniValue ArgToUniValue(const std::string& arg_value, const std::string& method, int param_idx)
268+
UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, int param_idx)
266269
{
267-
return members.count(std::make_pair(method, param_idx)) > 0 ? ParseNonRFCJSONValue(arg_value) : arg_value;
270+
return members.count({method, param_idx}) > 0 ? ParseNonRFCJSONValue(arg_value) : arg_value;
268271
}
269272

270273
/** Return arg_value as UniValue, and first parse it if it is a non-string parameter */
271-
UniValue ArgToUniValue(const std::string& arg_value, const std::string& method, const std::string& param_name)
274+
UniValue ArgToUniValue(std::string_view arg_value, const std::string& method, const std::string& param_name)
272275
{
273-
return membersByName.count(std::make_pair(method, param_name)) > 0 ? ParseNonRFCJSONValue(arg_value) : arg_value;
276+
return membersByName.count({method, param_name}) > 0 ? ParseNonRFCJSONValue(arg_value) : arg_value;
274277
}
275278
};
276279

@@ -287,22 +290,20 @@ static CRPCConvertTable rpcCvtTable;
287290
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
288291
* as well as objects and arrays.
289292
*/
290-
UniValue ParseNonRFCJSONValue(const std::string& strVal)
293+
UniValue ParseNonRFCJSONValue(std::string_view raw)
291294
{
292-
UniValue jVal;
293-
if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
294-
!jVal.isArray() || jVal.size()!=1)
295-
throw std::runtime_error(std::string("Error parsing JSON: ") + strVal);
296-
return jVal[0];
295+
UniValue parsed;
296+
if (!parsed.read(raw)) throw std::runtime_error(tfm::format("Error parsing JSON: %s", raw));
297+
return parsed;
297298
}
298299

299300
UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
300301
{
301302
UniValue params(UniValue::VARR);
302303

303304
for (unsigned int idx = 0; idx < strParams.size(); idx++) {
304-
const std::string& strVal = strParams[idx];
305-
params.push_back(rpcCvtTable.ArgToUniValue(strVal, strMethod, idx));
305+
std::string_view value{strParams[idx]};
306+
params.push_back(rpcCvtTable.ArgToUniValue(value, strMethod, idx));
306307
}
307308

308309
return params;
@@ -313,15 +314,15 @@ UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<s
313314
UniValue params(UniValue::VOBJ);
314315
UniValue positional_args{UniValue::VARR};
315316

316-
for (const std::string &s: strParams) {
317+
for (std::string_view s: strParams) {
317318
size_t pos = s.find('=');
318319
if (pos == std::string::npos) {
319320
positional_args.push_back(rpcCvtTable.ArgToUniValue(s, strMethod, positional_args.size()));
320321
continue;
321322
}
322323

323-
std::string name = s.substr(0, pos);
324-
std::string value = s.substr(pos+1);
324+
std::string name{s.substr(0, pos)};
325+
std::string_view value{s.substr(pos+1)};
325326

326327
// Intentionally overwrite earlier named values with later ones as a
327328
// convenience for scripts and command line users that want to merge

src/rpc/client.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#ifndef BITCOIN_RPC_CLIENT_H
77
#define BITCOIN_RPC_CLIENT_H
88

9+
#include <string>
10+
#include <string_view>
11+
912
#include <univalue.h>
1013

1114
/** Convert positional arguments to command-specific RPC representation */
@@ -17,6 +20,6 @@ UniValue RPCConvertNamedValues(const std::string& strMethod, const std::vector<s
1720
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
1821
* as well as objects and arrays.
1922
*/
20-
UniValue ParseNonRFCJSONValue(const std::string& strVal);
23+
UniValue ParseNonRFCJSONValue(std::string_view raw);
2124

2225
#endif // BITCOIN_RPC_CLIENT_H

src/test/rpc_tests.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ BOOST_AUTO_TEST_CASE(json_parse_errors)
296296
{
297297
// Valid
298298
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0").get_real(), 1.0);
299+
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("true").get_bool(), true);
300+
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("[false]")[0].get_bool(), false);
301+
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("{\"a\": true}")["a"].get_bool(), true);
302+
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("{\"1\": \"true\"}")["1"].get_str(), "true");
299303
// Valid, with leading or trailing whitespace
300304
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue(" 1.0").get_real(), 1.0);
301305
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0 ").get_real(), 1.0);
@@ -308,6 +312,11 @@ BOOST_AUTO_TEST_CASE(json_parse_errors)
308312
// Invalid, trailing garbage
309313
BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0sds"), std::runtime_error);
310314
BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0]"), std::runtime_error);
315+
// Invalid, keys have to be names
316+
BOOST_CHECK_THROW(ParseNonRFCJSONValue("{1: \"true\"}"), std::runtime_error);
317+
BOOST_CHECK_THROW(ParseNonRFCJSONValue("{true: 1}"), std::runtime_error);
318+
BOOST_CHECK_THROW(ParseNonRFCJSONValue("{[1]: 1}"), std::runtime_error);
319+
BOOST_CHECK_THROW(ParseNonRFCJSONValue("{{\"a\": \"a\"}: 1}"), std::runtime_error);
311320
// BTC addresses should fail parsing
312321
BOOST_CHECK_THROW(ParseNonRFCJSONValue("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), std::runtime_error);
313322
BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error);

src/univalue/include/univalue.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <map>
1313
#include <stdexcept>
1414
#include <string>
15+
#include <string_view>
1516
#include <type_traits>
1617
#include <vector>
1718

@@ -91,9 +92,7 @@ class UniValue {
9192

9293
bool read(const char *raw, size_t len);
9394
bool read(const char *raw) { return read(raw, strlen(raw)); }
94-
bool read(const std::string& rawStr) {
95-
return read(rawStr.data(), rawStr.size());
96-
}
95+
bool read(std::string_view raw) { return read(raw.data(), raw.size()); }
9796

9897
private:
9998
UniValue::VType typ;

0 commit comments

Comments
 (0)