MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / transformNamedArguments

Function transformNamedArguments

src/rpc/server.cpp:368–470  ·  view source on GitHub ↗

* Process named arguments into a vector of positional arguments, based on the * passed-in specification for the RPC call's arguments. */

Source from the content-addressed store, hash-verified

366 * passed-in specification for the RPC call's arguments.
367 */
368static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, const std::vector<std::pair<std::string, bool>>& argNames)
369{
370 JSONRPCRequest out = in;
371 out.params = UniValue(UniValue::VARR);
372 // Build a map of parameters, and remove ones that have been processed, so that we can throw a focused error if
373 // there is an unknown one.
374 const std::vector<std::string>& keys = in.params.getKeys();
375 const std::vector<UniValue>& values = in.params.getValues();
376 std::unordered_map<std::string, const UniValue*> argsIn;
377 for (size_t i=0; i<keys.size(); ++i) {
378 auto [_, inserted] = argsIn.emplace(keys[i], &values[i]);
379 if (!inserted) {
380 throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter " + keys[i] + " specified multiple times");
381 }
382 }
383 // Process expected parameters. If any parameters were left unspecified in
384 // the request before a parameter that was specified, null values need to be
385 // inserted at the unspecified parameter positions, and the "hole" variable
386 // below tracks the number of null values that need to be inserted.
387 // The "initial_hole_size" variable stores the size of the initial hole,
388 // i.e. how many initial positional arguments were left unspecified. This is
389 // used after the for-loop to add initial positional arguments from the
390 // "args" parameter, if present.
391 int hole = 0;
392 int initial_hole_size = 0;
393 const std::string* initial_param = nullptr;
394 UniValue options{UniValue::VOBJ};
395 for (const auto& [argNamePattern, named_only]: argNames) {
396 std::vector<std::string> vargNames = SplitString(argNamePattern, '|');
397 auto fr = argsIn.end();
398 for (const std::string & argName : vargNames) {
399 fr = argsIn.find(argName);
400 if (fr != argsIn.end()) {
401 break;
402 }
403 }
404
405 // Handle named-only parameters by pushing them into a temporary options
406 // object, and then pushing the accumulated options as the next
407 // positional argument.
408 if (named_only) {
409 if (fr != argsIn.end()) {
410 if (options.exists(fr->first)) {
411 throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter " + fr->first + " specified multiple times");
412 }
413 options.pushKVEnd(fr->first, *fr->second);
414 argsIn.erase(fr);
415 }
416 continue;
417 }
418
419 if (!options.empty() || fr != argsIn.end()) {
420 for (int i = 0; i < hole; ++i) {
421 // Fill hole between specified parameters with JSON nulls,
422 // but not at the end (for backwards compatibility with calls
423 // that act based on number of specified parameters).
424 out.params.push_back(UniValue());
425 }

Callers 1

ExecuteCommandFunction · 0.85

Calls 15

JSONRPCErrorFunction · 0.85
SplitStringFunction · 0.85
emplaceMethod · 0.80
findMethod · 0.80
pushKVEndMethod · 0.80
isArrayMethod · 0.80
UniValueClass · 0.70
sizeMethod · 0.45
endMethod · 0.45
existsMethod · 0.45
eraseMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected