diff options
Diffstat (limited to 'indra/llcommon/llstring.cpp')
-rw-r--r-- | indra/llcommon/llstring.cpp | 109 |
1 files changed, 89 insertions, 20 deletions
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 6512bbc392..c57f8b1e96 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -250,7 +250,7 @@ LLWString utf16str_to_wstring(const U16* utf16str, size_t len) while (i < len) { llwchar cur_char; - i += utf16chars_to_wchar(chars16+i, &cur_char); + i += (S32)utf16chars_to_wchar(chars16+i, &cur_char); wout += cur_char; } return wout; @@ -308,10 +308,10 @@ S32 wstring_utf16_length(const LLWString &wstr, const S32 woffset, const S32 wle // Given a wstring and an offset in it, returns the length as wstring (i.e., // number of llwchars) of the longest substring that starts at the offset // and whose equivalent utf-16 string does not exceeds the given utf16_length. -S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, const S32 woffset, const S32 utf16_length, BOOL *unaligned) +S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, const S32 woffset, const S32 utf16_length, bool *unaligned) { const auto end = wstr.length(); - BOOL u = FALSE; + bool u{ false }; S32 n = woffset + utf16_length; S32 i = woffset; while (i < end) @@ -758,7 +758,7 @@ std::string utf8str_showBytesUTF8(const std::string& utf8str) } // Search for any emoji symbol, return true if found -bool wstring_has_emoji(const LLWString& wstr) +bool wstring_has_emoji(LLWStringView wstr) { for (const llwchar& wch : wstr) { @@ -809,7 +809,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in, size_t len_in, unsigned code_page, 0, in, - len_in, + static_cast<int>(len_in), NULL, 0, 0, @@ -824,7 +824,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in, size_t len_in, unsigned code_page, 0, in, - len_in, + static_cast<int>(len_in), pout, len_out, 0, @@ -851,8 +851,8 @@ std::wstring ll_convert_string_to_wide(const char* in, size_t len, unsigned int std::vector<wchar_t> w_out(len + 1); memset(&w_out[0], 0, w_out.size()); - int real_output_str_len = MultiByteToWideChar(code_page, 0, in, len, - &w_out[0], w_out.size() - 1); + int real_output_str_len = MultiByteToWideChar(code_page, 0, in, static_cast<int>(len), + &w_out[0], static_cast<int>(w_out.size() - 1)); //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858. w_out[real_output_str_len] = 0; @@ -938,12 +938,12 @@ std::wstring windows_message<std::wstring>(DWORD error) return out.str(); } -boost::optional<std::wstring> llstring_getoptenv(const std::string& key) +std::optional<std::wstring> llstring_getoptenv(const std::string& key) { auto wkey = ll_convert_string_to_wide(key); // Take a wild guess as to how big the buffer should be. std::vector<wchar_t> buffer(1024); - auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); + auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], static_cast<DWORD>(buffer.size())); // If our initial guess was too short, n will indicate the size (in // wchar_t's) that buffer should have been, including the terminating nul. if (n > (buffer.size() - 1)) @@ -951,13 +951,13 @@ boost::optional<std::wstring> llstring_getoptenv(const std::string& key) // make it big enough buffer.resize(n); // and try again - n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); + n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], static_cast<DWORD>(buffer.size())); } // did that (ultimately) succeed? if (n) { - // great, return populated boost::optional - return boost::optional<std::wstring>(&buffer[0]); + // great, return populated std::optional + return std::make_optional<std::wstring>(&buffer[0]); } // not successful @@ -968,23 +968,23 @@ boost::optional<std::wstring> llstring_getoptenv(const std::string& key) LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: " << windows_message<std::string>(last_error) << LL_ENDL; } - // return empty boost::optional + // return empty std::optional return {}; } #else // ! LL_WINDOWS -boost::optional<std::string> llstring_getoptenv(const std::string& key) +std::optional<std::string> llstring_getoptenv(const std::string& key) { auto found = getenv(key.c_str()); if (found) { - // return populated boost::optional - return boost::optional<std::string>(found); + // return populated std::optional + return std::make_optional<std::string>(found); } else { - // return empty boost::optional + // return empty std::optional return {}; } } @@ -1017,7 +1017,7 @@ bool LLStringOps::isEmoji(llwchar a) // These are indeed "genuine" emojis, we *do want* rendered as such. HB return a >= 0x1f000 && a < 0x20000; #endif -} + } S32 LLStringOps::collate(const llwchar* a, const llwchar* b) { @@ -1208,6 +1208,75 @@ namespace LLStringFn return output; } + using literals_t = std::map<char, std::string>; + static const literals_t xml_elem_literals = + { + { '<', "<" }, + { '>', ">" }, + { '&', "&" } + }; + static const literals_t xml_attr_literals = + { + { '"', """ }, + { '\'', "'" } + }; + + static void literals_encode(std::string& text, const literals_t& literals) + { + for (const std::pair<char, std::string> it : literals) + { + std::string::size_type pos = 0; + while ((pos = text.find(it.first, pos)) != std::string::npos) + { + text.replace(pos, 1, it.second); + pos += it.second.size(); + } + } + } + + static void literals_decode(std::string& text, const literals_t& literals) + { + for (const std::pair<char, std::string> it : literals) + { + std::string::size_type pos = 0; + while ((pos = text.find(it.second, pos)) != std::string::npos) + { + text[pos++] = it.first; + text.erase(pos, it.second.size() - 1); + } + } + } + + /** + * @brief Replace all characters that are not allowed in XML 1.0 + * with corresponding literals: [ < > & ] => [ < > & ] + */ + std::string xml_encode(const std::string& input, bool for_attribute) + { + std::string result(input); + literals_encode(result, xml_elem_literals); + if (for_attribute) + { + literals_encode(result, xml_attr_literals); + } + return result; + } + + /** + * @brief Replace some of XML literals that are defined in XML 1.0 + * with corresponding characters: [ < > & ] => [ < > & ] + */ + std::string xml_decode(const std::string& input, bool for_attribute) + { + std::string result(input); + literals_decode(result, xml_elem_literals); + if (for_attribute) + { + literals_decode(result, xml_attr_literals); + } + return result; + } + /** * @brief Replace all control characters (c < 0x20) with replacement in * string. @@ -1552,7 +1621,7 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions) if (iter != substitutions.end()) { S32 secFromEpoch = 0; - BOOL r = LLStringUtil::convertToS32(iter->second, secFromEpoch); + bool r = LLStringUtil::convertToS32(iter->second, secFromEpoch); if (r) { found_replacement = formatDatetime(replacement, tokens[0], param, secFromEpoch); |