diff options
author | Dave Houlton <euclid@lindenlab.com> | 2020-07-21 11:04:56 -0600 |
---|---|---|
committer | Dave Houlton <euclid@lindenlab.com> | 2020-07-21 11:04:56 -0600 |
commit | 19d063952c4706d4344f207775aa5dfdff8802fd (patch) | |
tree | 596d38d591177ccc2ffef695b6f79437c5efce97 /indra/llcommon/llsdutil.cpp | |
parent | 6362aa300766484909cdfc8884edf3e6744fc727 (diff) | |
parent | 72423372d6cd7f763a5567ad75752fa4e7131d60 (diff) |
Merge master 6.4.6 into DRTVWR-510
Includes the conversion to VS2017 build tools.
Diffstat (limited to 'indra/llcommon/llsdutil.cpp')
-rw-r--r-- | indra/llcommon/llsdutil.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 1f8384f415..3f3edb661f 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -856,6 +856,74 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) } } +/***************************************************************************** +* llsd::drill() +*****************************************************************************/ +namespace llsd +{ + +LLSD& drill(LLSD& blob, const LLSD& rawPath) +{ + // Treat rawPath uniformly as an array. If it's not already an array, + // store it as the only entry in one. (But let's say Undefined means an + // empty array.) + LLSD path; + if (rawPath.isArray() || rawPath.isUndefined()) + { + path = rawPath; + } + else + { + path.append(rawPath); + } + + // Need to indicate a current destination -- but that current destination + // must change as we step through the path array. Where normally we'd use + // an LLSD& to capture a subscripted LLSD lvalue, this time we must + // instead use a pointer -- since it must be reassigned. + // Start by pointing to the input blob exactly as is. + LLSD* located{&blob}; + + // Extract the element of interest by walking path. Use an explicit index + // so that, in case of a bogus type in path, we can identify the specific + // path entry that's bad. + for (LLSD::Integer i = 0; i < path.size(); ++i) + { + const LLSD& key{path[i]}; + if (key.isString()) + { + // a string path element is a map key + located = &((*located)[key.asString()]); + } + else if (key.isInteger()) + { + // an integer path element is an array index + located = &((*located)[key.asInteger()]); + } + else + { + // What do we do with Real or Array or Map or ...? + // As it's a coder error -- not a user error -- rub the coder's + // face in it so it gets fixed. + LL_ERRS("llsdutil") << "drill(" << blob << ", " << rawPath + << "): path[" << i << "] bad type " + << sTypes.lookup(key.type()) << LL_ENDL; + } + } + + // dereference the pointer to return a reference to the element we found + return *located; +} + +LLSD drill(const LLSD& blob, const LLSD& path) +{ + // non-const drill() does exactly what we want. Temporarily cast away + // const-ness and use that. + return drill(const_cast<LLSD&>(blob), path); +} + +} // namespace llsd + // Construct a deep partial clone of of an LLSD object. primitive types share // references, however maps, arrays and binary objects are duplicated. An optional // filter may be include to exclude/include keys in a map. |