diff options
Diffstat (limited to 'indra/llcommon/llsdutil.cpp')
-rw-r--r-- | indra/llcommon/llsdutil.cpp | 736 |
1 files changed, 368 insertions, 368 deletions
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index e98fc0285a..efce458117 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llsdutil.cpp * @author Phoenix * @date 2006-05-24 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,12 +32,12 @@ #include <sstream> #if LL_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include <winsock2.h> // for htonl +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> // for htonl #elif LL_LINUX -# include <netinet/in.h> +# include <netinet/in.h> #elif LL_DARWIN -# include <arpa/inet.h> +# include <arpa/inet.h> #endif #include "llsdserialize.h" @@ -51,152 +51,152 @@ // U32 LLSD ll_sd_from_U32(const U32 val) { - std::vector<U8> v; - U32 net_order = htonl(val); + std::vector<U8> v; + U32 net_order = htonl(val); - v.resize(4); - memcpy(&(v[0]), &net_order, 4); /* Flawfinder: ignore */ + v.resize(4); + memcpy(&(v[0]), &net_order, 4); /* Flawfinder: ignore */ - return LLSD(v); + return LLSD(v); } U32 ll_U32_from_sd(const LLSD& sd) { - U32 ret; - std::vector<U8> v = sd.asBinary(); - if (v.size() < 4) - { - return 0; - } - memcpy(&ret, &(v[0]), 4); /* Flawfinder: ignore */ - ret = ntohl(ret); - return ret; + U32 ret; + std::vector<U8> v = sd.asBinary(); + if (v.size() < 4) + { + return 0; + } + memcpy(&ret, &(v[0]), 4); /* Flawfinder: ignore */ + ret = ntohl(ret); + return ret; } //U64 LLSD ll_sd_from_U64(const U64 val) { - std::vector<U8> v; - U32 high, low; + std::vector<U8> v; + U32 high, low; - high = (U32)(val >> 32); - low = (U32)val; - high = htonl(high); - low = htonl(low); + high = (U32)(val >> 32); + low = (U32)val; + high = htonl(high); + low = htonl(low); - v.resize(8); - memcpy(&(v[0]), &high, 4); /* Flawfinder: ignore */ - memcpy(&(v[4]), &low, 4); /* Flawfinder: ignore */ + v.resize(8); + memcpy(&(v[0]), &high, 4); /* Flawfinder: ignore */ + memcpy(&(v[4]), &low, 4); /* Flawfinder: ignore */ - return LLSD(v); + return LLSD(v); } U64 ll_U64_from_sd(const LLSD& sd) { - U32 high, low; - std::vector<U8> v = sd.asBinary(); + U32 high, low; + std::vector<U8> v = sd.asBinary(); - if (v.size() < 8) - { - return 0; - } + if (v.size() < 8) + { + return 0; + } - memcpy(&high, &(v[0]), 4); /* Flawfinder: ignore */ - memcpy(&low, &(v[4]), 4); /* Flawfinder: ignore */ - high = ntohl(high); - low = ntohl(low); + memcpy(&high, &(v[0]), 4); /* Flawfinder: ignore */ + memcpy(&low, &(v[4]), 4); /* Flawfinder: ignore */ + high = ntohl(high); + low = ntohl(low); - return ((U64)high) << 32 | low; + return ((U64)high) << 32 | low; } // IP Address (stored in net order in a U32, so don't need swizzling) LLSD ll_sd_from_ipaddr(const U32 val) { - std::vector<U8> v; + std::vector<U8> v; - v.resize(4); - memcpy(&(v[0]), &val, 4); /* Flawfinder: ignore */ + v.resize(4); + memcpy(&(v[0]), &val, 4); /* Flawfinder: ignore */ - return LLSD(v); + return LLSD(v); } U32 ll_ipaddr_from_sd(const LLSD& sd) { - U32 ret; - std::vector<U8> v = sd.asBinary(); - if (v.size() < 4) - { - return 0; - } - memcpy(&ret, &(v[0]), 4); /* Flawfinder: ignore */ - return ret; + U32 ret; + std::vector<U8> v = sd.asBinary(); + if (v.size() < 4) + { + return 0; + } + memcpy(&ret, &(v[0]), 4); /* Flawfinder: ignore */ + return ret; } // Converts an LLSD binary to an LLSD string LLSD ll_string_from_binary(const LLSD& sd) { - std::vector<U8> value = sd.asBinary(); - std::string str; - str.resize(value.size()); - memcpy(&str[0], &value[0], value.size()); - return str; + std::vector<U8> value = sd.asBinary(); + std::string str; + str.resize(value.size()); + memcpy(&str[0], &value[0], value.size()); + return str; } // Converts an LLSD string to an LLSD binary LLSD ll_binary_from_string(const LLSD& sd) { - std::vector<U8> binary_value; + std::vector<U8> binary_value; - std::string string_value = sd.asString(); - for (const U8 c : string_value) - { - binary_value.push_back(c); - } + std::string string_value = sd.asString(); + for (const U8 c : string_value) + { + binary_value.push_back(c); + } - binary_value.push_back('\0'); + binary_value.push_back('\0'); - return binary_value; + return binary_value; } char* ll_print_sd(const LLSD& sd) { - const U32 bufferSize = 10 * 1024; - static char buffer[bufferSize]; - std::ostringstream stream; - //stream.rdbuf()->pubsetbuf(buffer, bufferSize); - stream << LLSDOStreamer<LLSDXMLFormatter>(sd); - stream << std::ends; - strncpy(buffer, stream.str().c_str(), bufferSize); - buffer[bufferSize - 1] = '\0'; - return buffer; + const U32 bufferSize = 10 * 1024; + static char buffer[bufferSize]; + std::ostringstream stream; + //stream.rdbuf()->pubsetbuf(buffer, bufferSize); + stream << LLSDOStreamer<LLSDXMLFormatter>(sd); + stream << std::ends; + strncpy(buffer, stream.str().c_str(), bufferSize); + buffer[bufferSize - 1] = '\0'; + return buffer; } char* ll_pretty_print_sd_ptr(const LLSD* sd) { - if (sd) - { - return ll_pretty_print_sd(*sd); - } - return NULL; + if (sd) + { + return ll_pretty_print_sd(*sd); + } + return NULL; } char* ll_pretty_print_sd(const LLSD& sd) { - const U32 bufferSize = 100 * 1024; - static char buffer[bufferSize]; - std::ostringstream stream; - //stream.rdbuf()->pubsetbuf(buffer, bufferSize); - stream << LLSDOStreamer<LLSDXMLFormatter>(sd, LLSDFormatter::OPTIONS_PRETTY); - stream << std::ends; - strncpy(buffer, stream.str().c_str(), bufferSize); - buffer[bufferSize - 1] = '\0'; - return buffer; + const U32 bufferSize = 100 * 1024; + static char buffer[bufferSize]; + std::ostringstream stream; + //stream.rdbuf()->pubsetbuf(buffer, bufferSize); + stream << LLSDOStreamer<LLSDXMLFormatter>(sd, LLSDFormatter::OPTIONS_PRETTY); + stream << std::ends; + strncpy(buffer, stream.str().c_str(), bufferSize); + buffer[bufferSize - 1] = '\0'; + return buffer; } std::string ll_stream_notation_sd(const LLSD& sd) { - std::ostringstream stream; - stream << LLSDOStreamer<LLSDNotationFormatter>(sd); + std::ostringstream stream; + stream << LLSDOStreamer<LLSDNotationFormatter>(sd); return stream.str(); } @@ -210,121 +210,121 @@ std::string ll_stream_notation_sd(const LLSD& sd) //of the same value. Ordering of arrays matters //Otherwise, returns true BOOL compare_llsd_with_template( - const LLSD& llsd_to_test, - const LLSD& template_llsd, - LLSD& resultant_llsd) + const LLSD& llsd_to_test, + const LLSD& template_llsd, + LLSD& resultant_llsd) { LL_PROFILE_ZONE_SCOPED - if ( - llsd_to_test.isUndefined() && - template_llsd.isDefined() ) - { - resultant_llsd = template_llsd; - return TRUE; - } - else if ( llsd_to_test.type() != template_llsd.type() ) - { - resultant_llsd = LLSD(); - return FALSE; - } - - if ( llsd_to_test.isArray() ) - { - //they are both arrays - //we loop over all the items in the template - //verifying that the to_test has a subset (in the same order) - //any shortcoming in the testing_llsd are just taken - //to be the rest of the template - LLSD data; - LLSD::array_const_iterator test_iter; - LLSD::array_const_iterator template_iter; - - resultant_llsd = LLSD::emptyArray(); - test_iter = llsd_to_test.beginArray(); - - for ( - template_iter = template_llsd.beginArray(); - (template_iter != template_llsd.endArray() && - test_iter != llsd_to_test.endArray()); - ++template_iter) - { - if ( !compare_llsd_with_template( - *test_iter, - *template_iter, - data) ) - { - resultant_llsd = LLSD(); - return FALSE; - } - else - { - resultant_llsd.append(data); - } - - ++test_iter; - } - - //so either the test or the template ended - //we do another loop now to the end of the template - //grabbing the default values - for (; - template_iter != template_llsd.endArray(); - ++template_iter) - { - resultant_llsd.append(*template_iter); - } - } - else if ( llsd_to_test.isMap() ) - { - //now we loop over the keys of the two maps - //any excess is taken from the template - //excess is ignored in the test - LLSD value; - LLSD::map_const_iterator template_iter; - - resultant_llsd = LLSD::emptyMap(); - for ( - template_iter = template_llsd.beginMap(); - template_iter != template_llsd.endMap(); - ++template_iter) - { - if ( llsd_to_test.has(template_iter->first) ) - { - //the test LLSD has the same key - if ( !compare_llsd_with_template( - llsd_to_test[template_iter->first], - template_iter->second, - value) ) - { - resultant_llsd = LLSD(); - return FALSE; - } - else - { - resultant_llsd[template_iter->first] = value; - } - } - else - { - //test llsd doesn't have it...take the - //template as default value - resultant_llsd[template_iter->first] = - template_iter->second; - } - } - } - else - { - //of same type...take the test llsd's value - resultant_llsd = llsd_to_test; - } - - - return TRUE; + if ( + llsd_to_test.isUndefined() && + template_llsd.isDefined() ) + { + resultant_llsd = template_llsd; + return TRUE; + } + else if ( llsd_to_test.type() != template_llsd.type() ) + { + resultant_llsd = LLSD(); + return FALSE; + } + + if ( llsd_to_test.isArray() ) + { + //they are both arrays + //we loop over all the items in the template + //verifying that the to_test has a subset (in the same order) + //any shortcoming in the testing_llsd are just taken + //to be the rest of the template + LLSD data; + LLSD::array_const_iterator test_iter; + LLSD::array_const_iterator template_iter; + + resultant_llsd = LLSD::emptyArray(); + test_iter = llsd_to_test.beginArray(); + + for ( + template_iter = template_llsd.beginArray(); + (template_iter != template_llsd.endArray() && + test_iter != llsd_to_test.endArray()); + ++template_iter) + { + if ( !compare_llsd_with_template( + *test_iter, + *template_iter, + data) ) + { + resultant_llsd = LLSD(); + return FALSE; + } + else + { + resultant_llsd.append(data); + } + + ++test_iter; + } + + //so either the test or the template ended + //we do another loop now to the end of the template + //grabbing the default values + for (; + template_iter != template_llsd.endArray(); + ++template_iter) + { + resultant_llsd.append(*template_iter); + } + } + else if ( llsd_to_test.isMap() ) + { + //now we loop over the keys of the two maps + //any excess is taken from the template + //excess is ignored in the test + LLSD value; + LLSD::map_const_iterator template_iter; + + resultant_llsd = LLSD::emptyMap(); + for ( + template_iter = template_llsd.beginMap(); + template_iter != template_llsd.endMap(); + ++template_iter) + { + if ( llsd_to_test.has(template_iter->first) ) + { + //the test LLSD has the same key + if ( !compare_llsd_with_template( + llsd_to_test[template_iter->first], + template_iter->second, + value) ) + { + resultant_llsd = LLSD(); + return FALSE; + } + else + { + resultant_llsd[template_iter->first] = value; + } + } + else + { + //test llsd doesn't have it...take the + //template as default value + resultant_llsd[template_iter->first] = + template_iter->second; + } + } + } + else + { + //of same type...take the test llsd's value + resultant_llsd = llsd_to_test; + } + + + return TRUE; } -// filter_llsd_with_template() is a direct clone (copy-n-paste) of +// filter_llsd_with_template() is a direct clone (copy-n-paste) of // compare_llsd_with_template with the following differences: // (1) bool vs BOOL return types // (2) A map with the key value "*" is a special value and maps any key in the @@ -333,171 +333,171 @@ BOOL compare_llsd_with_template( // for *all* the elements of the test array. If the template array is of // different size, compare_llsd_with_template() semantics apply. bool filter_llsd_with_template( - const LLSD & llsd_to_test, - const LLSD & template_llsd, - LLSD & resultant_llsd) + const LLSD & llsd_to_test, + const LLSD & template_llsd, + LLSD & resultant_llsd) { LL_PROFILE_ZONE_SCOPED - if (llsd_to_test.isUndefined() && template_llsd.isDefined()) - { - resultant_llsd = template_llsd; - return true; - } - else if (llsd_to_test.type() != template_llsd.type()) - { - resultant_llsd = LLSD(); - return false; - } - - if (llsd_to_test.isArray()) - { - //they are both arrays - //we loop over all the items in the template - //verifying that the to_test has a subset (in the same order) - //any shortcoming in the testing_llsd are just taken - //to be the rest of the template - LLSD data; - LLSD::array_const_iterator test_iter; - LLSD::array_const_iterator template_iter; - - resultant_llsd = LLSD::emptyArray(); - test_iter = llsd_to_test.beginArray(); - - if (1 == template_llsd.size()) - { - // If the template has a single item, treat it as - // the template for *all* items in the test LLSD. - template_iter = template_llsd.beginArray(); - - for (; test_iter != llsd_to_test.endArray(); ++test_iter) - { - if (! filter_llsd_with_template(*test_iter, *template_iter, data)) - { - resultant_llsd = LLSD(); - return false; - } - else - { - resultant_llsd.append(data); - } - } - } - else - { - // Traditional compare_llsd_with_template matching - - for (template_iter = template_llsd.beginArray(); - template_iter != template_llsd.endArray() && - test_iter != llsd_to_test.endArray(); - ++template_iter, ++test_iter) - { - if (! filter_llsd_with_template(*test_iter, *template_iter, data)) - { - resultant_llsd = LLSD(); - return false; - } - else - { - resultant_llsd.append(data); - } - } - - //so either the test or the template ended - //we do another loop now to the end of the template - //grabbing the default values - for (; - template_iter != template_llsd.endArray(); - ++template_iter) - { - resultant_llsd.append(*template_iter); - } - } - } - else if (llsd_to_test.isMap()) - { - resultant_llsd = LLSD::emptyMap(); - - //now we loop over the keys of the two maps - //any excess is taken from the template - //excess is ignored in the test - - // Special tag for wildcarded LLSD map key templates - const LLSD::String wildcard_tag("*"); - - const bool template_has_wildcard = template_llsd.has(wildcard_tag); - LLSD wildcard_value; - LLSD value; - - const LLSD::map_const_iterator template_iter_end(template_llsd.endMap()); - for (LLSD::map_const_iterator template_iter(template_llsd.beginMap()); - template_iter_end != template_iter; - ++template_iter) - { - if (wildcard_tag == template_iter->first) - { - wildcard_value = template_iter->second; - } - else if (llsd_to_test.has(template_iter->first)) - { - //the test LLSD has the same key - if (! filter_llsd_with_template(llsd_to_test[template_iter->first], - template_iter->second, - value)) - { - resultant_llsd = LLSD(); - return false; - } - else - { - resultant_llsd[template_iter->first] = value; - } - } - else if (! template_has_wildcard) - { - // test llsd doesn't have it...take the - // template as default value - resultant_llsd[template_iter->first] = template_iter->second; - } - } - if (template_has_wildcard) - { - LLSD sub_value; - LLSD::map_const_iterator test_iter; - - for (test_iter = llsd_to_test.beginMap(); - test_iter != llsd_to_test.endMap(); - ++test_iter) - { - if (resultant_llsd.has(test_iter->first)) - { - // Final value has test key, assume more specific - // template matched and we shouldn't modify it again. - continue; - } - else if (! filter_llsd_with_template(test_iter->second, - wildcard_value, - sub_value)) - { - // Test value doesn't match wildcarded template - resultant_llsd = LLSD(); - return false; - } - else - { - // Test value matches template, add the actuals. - resultant_llsd[test_iter->first] = sub_value; - } - } - } - } - else - { - //of same type...take the test llsd's value - resultant_llsd = llsd_to_test; - } - - return true; + if (llsd_to_test.isUndefined() && template_llsd.isDefined()) + { + resultant_llsd = template_llsd; + return true; + } + else if (llsd_to_test.type() != template_llsd.type()) + { + resultant_llsd = LLSD(); + return false; + } + + if (llsd_to_test.isArray()) + { + //they are both arrays + //we loop over all the items in the template + //verifying that the to_test has a subset (in the same order) + //any shortcoming in the testing_llsd are just taken + //to be the rest of the template + LLSD data; + LLSD::array_const_iterator test_iter; + LLSD::array_const_iterator template_iter; + + resultant_llsd = LLSD::emptyArray(); + test_iter = llsd_to_test.beginArray(); + + if (1 == template_llsd.size()) + { + // If the template has a single item, treat it as + // the template for *all* items in the test LLSD. + template_iter = template_llsd.beginArray(); + + for (; test_iter != llsd_to_test.endArray(); ++test_iter) + { + if (! filter_llsd_with_template(*test_iter, *template_iter, data)) + { + resultant_llsd = LLSD(); + return false; + } + else + { + resultant_llsd.append(data); + } + } + } + else + { + // Traditional compare_llsd_with_template matching + + for (template_iter = template_llsd.beginArray(); + template_iter != template_llsd.endArray() && + test_iter != llsd_to_test.endArray(); + ++template_iter, ++test_iter) + { + if (! filter_llsd_with_template(*test_iter, *template_iter, data)) + { + resultant_llsd = LLSD(); + return false; + } + else + { + resultant_llsd.append(data); + } + } + + //so either the test or the template ended + //we do another loop now to the end of the template + //grabbing the default values + for (; + template_iter != template_llsd.endArray(); + ++template_iter) + { + resultant_llsd.append(*template_iter); + } + } + } + else if (llsd_to_test.isMap()) + { + resultant_llsd = LLSD::emptyMap(); + + //now we loop over the keys of the two maps + //any excess is taken from the template + //excess is ignored in the test + + // Special tag for wildcarded LLSD map key templates + const LLSD::String wildcard_tag("*"); + + const bool template_has_wildcard = template_llsd.has(wildcard_tag); + LLSD wildcard_value; + LLSD value; + + const LLSD::map_const_iterator template_iter_end(template_llsd.endMap()); + for (LLSD::map_const_iterator template_iter(template_llsd.beginMap()); + template_iter_end != template_iter; + ++template_iter) + { + if (wildcard_tag == template_iter->first) + { + wildcard_value = template_iter->second; + } + else if (llsd_to_test.has(template_iter->first)) + { + //the test LLSD has the same key + if (! filter_llsd_with_template(llsd_to_test[template_iter->first], + template_iter->second, + value)) + { + resultant_llsd = LLSD(); + return false; + } + else + { + resultant_llsd[template_iter->first] = value; + } + } + else if (! template_has_wildcard) + { + // test llsd doesn't have it...take the + // template as default value + resultant_llsd[template_iter->first] = template_iter->second; + } + } + if (template_has_wildcard) + { + LLSD sub_value; + LLSD::map_const_iterator test_iter; + + for (test_iter = llsd_to_test.beginMap(); + test_iter != llsd_to_test.endMap(); + ++test_iter) + { + if (resultant_llsd.has(test_iter->first)) + { + // Final value has test key, assume more specific + // template matched and we shouldn't modify it again. + continue; + } + else if (! filter_llsd_with_template(test_iter->second, + wildcard_value, + sub_value)) + { + // Test value doesn't match wildcarded template + resultant_llsd = LLSD(); + return false; + } + else + { + // Test value matches template, add the actuals. + resultant_llsd[test_iter->first] = sub_value; + } + } + } + } + else + { + //of same type...take the test llsd's value + resultant_llsd = llsd_to_test; + } + + return true; } /***************************************************************************** @@ -944,9 +944,9 @@ LLSD drill(const LLSD& blob, const LLSD& path) } // namespace llsd -// Construct a deep partial clone of of an LLSD object. primitive types share +// 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. +// filter may be include to exclude/include keys in a map. LLSD llsd_clone(LLSD value, LLSD filter) { LL_PROFILE_ZONE_SCOPED |