summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-08-17 16:15:53 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-08-17 16:15:53 +0000
commit6a4897db5abbc842f50400f39c10b310f600c7d4 (patch)
tree3411e9bace30cc0ce0569df134cf3c37721a8ee7 /indra
parent6b31bc72294d72d14e9761c9c05815081517e23b (diff)
Significant optimization to LLUIString.
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llstring.h110
-rw-r--r--indra/llui/lluistring.cpp6
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile.xml12
3 files changed, 108 insertions, 20 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();
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index 7ce0fd7a88..20ff71378e 100644
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
@@ -37,6 +37,8 @@
const LLStringUtil::format_map_t LLUIString::sNullArgs;
+LLFastTimer::DeclareTimer FTM_UI_STRING("UI String");
+
LLUIString::LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args)
: mOrig(instring),
@@ -59,6 +61,8 @@ void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
void LLUIString::setArgs(const LLSD& sd)
{
+ LLFastTimer timer(FTM_UI_STRING);
+
if (!sd.isMap()) return;
for(LLSD::map_const_iterator sd_it = sd.beginMap();
sd_it != sd.endMap();
@@ -112,6 +116,8 @@ void LLUIString::clear()
void LLUIString::format()
{
+ LLFastTimer timer(FTM_UI_STRING);
+
// optimize for empty strings (don't attempt string replacement)
if (mOrig.empty())
{
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 23c8223e7b..25ed38f5cc 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -104,15 +104,15 @@
top_delta="0"
value="Second Life:"
width="140" />
- <text
+ <text_editor
follows="left|top|right"
height="90"
layout="topleft"
name="sl_description_edit"
- width="130"
+ width="180"
word_wrap="true">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
- </text>
+ </text_editor>
</panel>
<panel
follows="left|top"
@@ -142,15 +142,15 @@
top_delta="0"
value="Real World:"
width="140" />
- <text
+ <text_editor
follows="left|top|right"
height="90"
layout="topleft"
name="fl_description_edit"
- width="130"
+ width="180"
word_wrap="true">
Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
- </text>
+ </text_editor>
</panel>
<link
follows="left|top|right"