diff --git a/coding/string_utf8_multilang.cpp b/coding/string_utf8_multilang.cpp index 51d22c4d2c..86fe581068 100644 --- a/coding/string_utf8_multilang.cpp +++ b/coding/string_utf8_multilang.cpp @@ -193,7 +193,7 @@ void StringUtf8Multilang::AddString(int8_t lang, string const & utf8s) { size_t const next = GetNextIndex(i); - if ((m_s[i] & 0x3F) == lang) + if ((m_s[i] & kLangCodeMask) == lang) { ++i; m_s.replace(i, next - i, utf8s); @@ -216,7 +216,7 @@ void StringUtf8Multilang::RemoveString(int8_t lang) { size_t const next = GetNextIndex(i); - if ((m_s[i] & 0x3F) == lang) + if ((m_s[i] & kLangCodeMask) == lang) { m_s.erase(i, next - i); return; @@ -238,7 +238,7 @@ bool StringUtf8Multilang::GetString(int8_t lang, string & utf8s) const { size_t const next = GetNextIndex(i); - if ((m_s[i] & 0x3F) == lang) + if ((m_s[i] & kLangCodeMask) == lang) { ++i; utf8s.assign(m_s.c_str() + i, next - i); @@ -259,7 +259,7 @@ StringUtf8Multilang::TranslationPositions StringUtf8Multilang::GenerateTranslati while (i < sz) { size_t const next = GetNextIndex(i); - int8_t const code = m_s[i] & 0x3F; + int8_t const code = m_s[i] & kLangCodeMask; if (GetLangByCode(code) != kReservedLang) result[code] = Position{i + 1, next - i - 1}; @@ -282,7 +282,7 @@ bool StringUtf8Multilang::HasString(int8_t lang) const for (size_t i = 0; i < m_s.size(); i = GetNextIndex(i)) { - if ((m_s[i] & 0x3F) == lang) + if ((m_s[i] & kLangCodeMask) == lang) return true; } diff --git a/coding/string_utf8_multilang.hpp b/coding/string_utf8_multilang.hpp index 7f84cab87e..9e663af9e0 100644 --- a/coding/string_utf8_multilang.hpp +++ b/coding/string_utf8_multilang.hpp @@ -91,6 +91,10 @@ public: /// How many languages we support on indexing stage. See full list in cpp file. /// TODO(AlexZ): Review and replace invalid languages by valid ones. static int8_t constexpr kMaxSupportedLanguages = 64; + // 6 bits language code mask. The language code is encoded with 6 bits that are prepended with + // "10". + static int8_t constexpr kLangCodeMask = 0x3F; + static_assert(kMaxSupportedLanguages == kLangCodeMask + 1, ""); static char constexpr kReservedLang[] = "reserved"; using Languages = buffer_vector; @@ -112,19 +116,22 @@ public: inline void Clear() { m_s.clear(); } inline bool IsEmpty() const { return m_s.empty(); } + // This method complexity is O(||utf8s||) when adding a new name and O(||m_s|| + ||utf8s||) when + // replacing an existing name. void AddString(int8_t lang, std::string const & utf8s); void AddString(std::string const & lang, std::string const & utf8s) { int8_t const l = GetLangIndex(lang); - if (l >= 0) + if (l != kUnsupportedLanguageCode) AddString(l, utf8s); } + // This method complexity is O(||m_s||). void RemoveString(int8_t lang); void RemoveString(std::string const & lang) { int8_t const l = GetLangIndex(lang); - if (l >= 0) + if (l != kUnsupportedLanguageCode) RemoveString(l); } @@ -138,7 +145,7 @@ public: while (i < sz) { size_t const next = GetNextIndex(i); - int8_t const code = m_s[i] & 0x3F; + int8_t const code = m_s[i] & kLangCodeMask; if (GetLangByCode(code) != kReservedLang && wrapper(code, m_s.substr(i + 1, next - i - 1)) == base::ControlFlow::Break) {