diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2011-02-06 21:32:25 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2011-02-06 21:32:25 -0500 |
commit | 1a1563bb154102c09a172235081d8db62e4fbec9 (patch) | |
tree | 7207634d5b4c485a52a40815748775517ca8ffb0 /indra | |
parent | f4f3791a5ff1cc76b9d1054c269e69d44cdaf8d6 (diff) |
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.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/lleventdispatcher.cpp | 72 | ||||
-rw-r--r-- | indra/llcommon/tests/lleventdispatcher_test.cpp | 6 |
2 files changed, 54 insertions, 24 deletions
diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp index 52660105c4..5b6d4efbe9 100644 --- a/indra/llcommon/lleventdispatcher.cpp +++ b/indra/llcommon/lleventdispatcher.cpp @@ -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()) + { + // 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; + } + } + else + { + // argsmap is in fact a map. Walk the map. + for (LLSD::map_const_iterator mi(argsmap.beginMap()), mend(argsmap.endMap()); + mi != mend; ++mi) { - // 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; + // 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; } - 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) diff --git a/indra/llcommon/tests/lleventdispatcher_test.cpp b/indra/llcommon/tests/lleventdispatcher_test.cpp index bdd8c16cec..c599672bc5 100644 --- a/indra/llcommon/tests/lleventdispatcher_test.cpp +++ b/indra/llcommon/tests/lleventdispatcher_test.cpp @@ -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 |