Untested support for passing array to map-registered function.
An array-registered function has no param names, so you can only pass an array: a map would be meaningless. Initial implementation of map-registered functions assumed that since you CAN pass a map, you MUST pass a map. But in fact it's meaningful to pass an array as well -- for whatever reason -- and easy to implement, so there you are. Tests to follow.meow-7.2.2
parent
f4f3791a5f
commit
1a1563bb15
|
|
@ -269,9 +269,10 @@ LLSDArgsMapper::LLSDArgsMapper(const std::string& function,
|
|||
|
||||
LLSD LLSDArgsMapper::map(const LLSD& argsmap) const
|
||||
{
|
||||
if (! (argsmap.isUndefined() || argsmap.isMap()))
|
||||
if (! (argsmap.isUndefined() || argsmap.isMap() || argsmap.isArray()))
|
||||
{
|
||||
LL_ERRS("LLSDArgsMapper") << _function << " map() needs a map, not " << argsmap << LL_ENDL;
|
||||
LL_ERRS("LLSDArgsMapper") << _function << " map() needs a map or array, not "
|
||||
<< argsmap << LL_ENDL;
|
||||
}
|
||||
// Initialize the args array. Indexing a non-const LLSD array grows it
|
||||
// to appropriate size, but we don't want to resize this one on each
|
||||
|
|
@ -295,30 +296,57 @@ LLSD LLSDArgsMapper::map(const LLSD& argsmap) const
|
|||
// holes. (Avoid std::vector<bool> which is known to be odd -- can we
|
||||
// iterate?)
|
||||
FilledVector filled(args.size());
|
||||
// Walk the map.
|
||||
for (LLSD::map_const_iterator mi(argsmap.beginMap()), mend(argsmap.endMap());
|
||||
mi != mend; ++mi)
|
||||
|
||||
if (argsmap.isArray())
|
||||
{
|
||||
// mi->first is a parameter-name string, with mi->second its
|
||||
// value. Look up the name's position index in _indexes.
|
||||
IndexMap::const_iterator ixit(_indexes.find(mi->first));
|
||||
if (ixit == _indexes.end())
|
||||
// Fill args from array. If there are too many args in passed array,
|
||||
// ignore the rest.
|
||||
LLSD::Integer size(argsmap.size());
|
||||
if (size > args.size())
|
||||
{
|
||||
// Allow for a map containing more params than were passed in
|
||||
// our names array. Caller typically receives a map containing
|
||||
// the function name, cruft such as reqid, etc. Ignore keys
|
||||
// not defined in _indexes.
|
||||
LL_DEBUGS("LLSDArgsMapper") << _function << " ignoring "
|
||||
<< mi->first << "=" << mi->second << LL_ENDL;
|
||||
continue;
|
||||
// We don't just use std::min() because we want to sneak in this
|
||||
// warning if caller passes too many args.
|
||||
LL_WARNS("LLSDArgsMapper") << _function << " needs " << args.size()
|
||||
<< " params, ignoring last " << (size - args.size())
|
||||
<< " of passed " << size << ": " << argsmap << LL_ENDL;
|
||||
size = args.size();
|
||||
}
|
||||
for (LLSD::Integer i(0); i < size; ++i)
|
||||
{
|
||||
// Copy the actual argument from argsmap
|
||||
args[i] = argsmap[i];
|
||||
// Note that it's been filled
|
||||
filled[i] = 1;
|
||||
}
|
||||
LLSD::Integer pos = ixit->second;
|
||||
// Store the value at that position in the args array.
|
||||
args[pos] = mi->second;
|
||||
// Don't forget to record the fact that we've filled this
|
||||
// position.
|
||||
filled[pos] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// argsmap is in fact a map. Walk the map.
|
||||
for (LLSD::map_const_iterator mi(argsmap.beginMap()), mend(argsmap.endMap());
|
||||
mi != mend; ++mi)
|
||||
{
|
||||
// mi->first is a parameter-name string, with mi->second its
|
||||
// value. Look up the name's position index in _indexes.
|
||||
IndexMap::const_iterator ixit(_indexes.find(mi->first));
|
||||
if (ixit == _indexes.end())
|
||||
{
|
||||
// Allow for a map containing more params than were passed in
|
||||
// our names array. Caller typically receives a map containing
|
||||
// the function name, cruft such as reqid, etc. Ignore keys
|
||||
// not defined in _indexes.
|
||||
LL_DEBUGS("LLSDArgsMapper") << _function << " ignoring "
|
||||
<< mi->first << "=" << mi->second << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
LLSD::Integer pos = ixit->second;
|
||||
// Store the value at that position in the args array.
|
||||
args[pos] = mi->second;
|
||||
// Don't forget to record the fact that we've filled this
|
||||
// position.
|
||||
filled[pos] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill any remaining holes from _defaults.
|
||||
LLSD unfilled(LLSD::emptyArray());
|
||||
for (LLSD::Integer i = 0, iend = args.size(); i < iend; ++i)
|
||||
|
|
|
|||
|
|
@ -682,7 +682,7 @@ namespace tut
|
|||
// (scalar | map | array (too short | too long | just right))
|
||||
// [trap LL_WARNS for too-long case?]
|
||||
// - (Free function | non-static method), arbitrary args, map style with
|
||||
// (scalar | array | map (all | too many | holes (with | without) defaults))
|
||||
// (scalar | (array | map) (all | too many | holes (with | without) defaults))
|
||||
// - const char* param gets ("" | NULL)
|
||||
|
||||
// Query cases:
|
||||
|
|
@ -1108,7 +1108,9 @@ namespace tut
|
|||
|
||||
std::string map_exc("needs a map");
|
||||
call_exc("free0_map", 17, map_exc);
|
||||
call_exc("free0_map", LLSDArray("a")("b"), map_exc);
|
||||
// Passing an array to a map-style function works now! No longer an
|
||||
// error case!
|
||||
// call_exc("free0_map", LLSDArray("a")("b"), map_exc);
|
||||
}
|
||||
|
||||
struct FunctionsTriple
|
||||
|
|
|
|||
Loading…
Reference in New Issue