diff options
Diffstat (limited to 'indra/llcommon/llstring.h')
-rw-r--r-- | indra/llcommon/llstring.h | 110 |
1 files changed, 96 insertions, 14 deletions
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 91b706a5be..65e005abfb 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -232,9 +232,10 @@ public: typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t; static void getTokens (std::basic_string<T> input, std::vector<std::basic_string<T> >& tokens); static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals); - static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, const LLSD& substitutions); + static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch); + static S32 format(std::basic_string<T>& s, const format_map_t& substitutions); static S32 format(std::basic_string<T>& s, const LLSD& substitutions); - static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map); + static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions); static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions); static void setLocale (std::string inLocale) {sLocale = inLocale;}; static std::string getLocale (void) {return sLocale;}; @@ -618,18 +619,76 @@ void LLStringUtilBase<T>::getTokens (std::basic_string<T> input, std::vector<std // static template<class T> -S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map) +S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& substitutions) { - LLSD llsdMap; + S32 res = 0; + + std::basic_ostringstream<T> output; + // match strings like [NAME,number,3] + const boost::regex key("\\[((\\s)*([0-9_A-Za-z]+)((\\s)*,(\\s)*[0-9_A-Za-z\\s]*){0,2}(\\s)*)]"); - for (format_map_t::const_iterator iter = fmt_map.begin(); - iter != fmt_map.end(); - ++iter) + + typename std::basic_string<T>::const_iterator start = s.begin(); + typename std::basic_string<T>::const_iterator end = s.end(); + boost::smatch match; + + + while (boost::regex_search(start, end, match, key, boost::match_default)) { - llsdMap[iter->first] = iter->second; - } + bool found_replacement = false; + std::vector<std::basic_string<T> > tokens; + std::basic_string<T> replacement; + + getTokens (std::basic_string<T>(match[1].first, match[1].second), tokens); + + if (tokens.size() == 1) + { + found_replacement = simpleReplacement (replacement, tokens[0], substitutions); + } + else if (tokens[1] == "number") + { + std::basic_string<T> param = "0"; + + if (tokens.size() > 2) param = tokens[2]; + found_replacement = simpleReplacement (replacement, tokens[0], substitutions); + if (found_replacement) formatNumber (replacement, param); + } + else if (tokens[1] == "datetime") + { + std::basic_string<T> param; + if (tokens.size() > 2) param = tokens[2]; + + format_map_t::const_iterator iter = substitutions.find("datetime"); + if (iter != substitutions.end()) + { + S32 secFromEpoch = 0; + BOOL r = LLStringUtil::convertToS32(iter->second, secFromEpoch); + if (r) + { + found_replacement = formatDatetime(replacement, tokens[0], param, secFromEpoch); + } + } + } - return format (s, llsdMap); + if (found_replacement) + { + output << std::basic_string<T>(start, match[0].first) << replacement; + res++; + } + else + { + // we had no replacement, so leave the string we searched for so that it gets noticed by QA + // "hello [NAME_NOT_FOUND]" is output + output << std::basic_string<T>(start, match[0].second); + } + + // update search position + start = match[0].second; + } + // send the remainder of the string (with no further matches for bracketed names) + output << std::basic_string<T>(start, end); + s = output.str(); + return res; } //static @@ -704,7 +763,32 @@ S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const LLSD& substitutio // static template<class T> -bool LLStringUtilBase<T>::simpleReplacement(std::basic_string<T> &replacement, std::basic_string<T> token, const LLSD &substitutions) +bool LLStringUtilBase<T>::simpleReplacement(std::basic_string<T> &replacement, std::basic_string<T> token, const format_map_t& substitutions) +{ + // see if we have a replacement for the bracketed string (without the brackets) + // test first using has() because if we just look up with operator[] we get back an + // empty string even if the value is missing. We want to distinguish between + // missing replacements and deliberately empty replacement strings. + format_map_t::const_iterator iter = substitutions.find(token); + if (iter != substitutions.end()) + { + replacement = iter->second; + return true; + } + // if not, see if there's one WITH brackets + iter = substitutions.find(std::basic_string<T>("[" + token + "]")); + if (iter != substitutions.end()) + { + replacement = iter->second; + return true; + } + + return false; +} + +// static +template<class T> +bool LLStringUtilBase<T>::simpleReplacement(std::basic_string<T> &replacement, std::basic_string<T> token, const LLSD& substitutions) { // see if we have a replacement for the bracketed string (without the brackets) // test first using has() because if we just look up with operator[] we get back an @@ -764,10 +848,8 @@ void LLStringUtilBase<T>::formatNumber(std::basic_string<T>& numStr, std::basic_ // static template<class T> bool LLStringUtilBase<T>::formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, - std::basic_string<T> param, const LLSD& substitutions) + std::basic_string<T> param, S32 secFromEpoch) { - S32 secFromEpoch = (long) substitutions["datetime"].asInteger(); - if (param == "local") // local { secFromEpoch -= LLStringOps::getLocalTimeOffset(); |