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 | 
