refactor(Core/Misc): Rewrite name handling functions that use raw buffers (#2230)

This commit is contained in:
Viste
2019-08-26 22:12:19 +03:00
committed by Francesco Borzì
parent 0b88e24808
commit bc1ad036a5
2 changed files with 41 additions and 44 deletions

View File

@@ -15,6 +15,7 @@
#include "SFMT.h"
#include "Errors.h" // for ASSERT
#include <ace/TSS_T.h>
#include <array>
typedef ACE_TSS<SFMTRand> SFMTRandTSS;
static SFMTRandTSS sfmtRand;
@@ -400,43 +401,48 @@ typedef wchar_t const* const* wstrlist;
std::wstring GetMainPartOfName(std::wstring wname, uint32 declension)
{
// supported only Cyrillic cases
if (wname.size() < 1 || !isCyrillicCharacter(wname[0]) || declension > 5)
if (wname.empty() || !isCyrillicCharacter(wname[0]) || declension > 5)
return wname;
// Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently)
static wchar_t const a_End[] = { wchar_t(1), wchar_t(0x0430), wchar_t(0x0000)};
static wchar_t const o_End[] = { wchar_t(1), wchar_t(0x043E), wchar_t(0x0000)};
static wchar_t const ya_End[] = { wchar_t(1), wchar_t(0x044F), wchar_t(0x0000)};
static wchar_t const ie_End[] = { wchar_t(1), wchar_t(0x0435), wchar_t(0x0000)};
static wchar_t const i_End[] = { wchar_t(1), wchar_t(0x0438), wchar_t(0x0000)};
static wchar_t const yeru_End[] = { wchar_t(1), wchar_t(0x044B), wchar_t(0x0000)};
static wchar_t const u_End[] = { wchar_t(1), wchar_t(0x0443), wchar_t(0x0000)};
static wchar_t const yu_End[] = { wchar_t(1), wchar_t(0x044E), wchar_t(0x0000)};
static wchar_t const oj_End[] = { wchar_t(2), wchar_t(0x043E), wchar_t(0x0439), wchar_t(0x0000)};
static wchar_t const ie_j_End[] = { wchar_t(2), wchar_t(0x0435), wchar_t(0x0439), wchar_t(0x0000)};
static wchar_t const io_j_End[] = { wchar_t(2), wchar_t(0x0451), wchar_t(0x0439), wchar_t(0x0000)};
static wchar_t const o_m_End[] = { wchar_t(2), wchar_t(0x043E), wchar_t(0x043C), wchar_t(0x0000)};
static wchar_t const io_m_End[] = { wchar_t(2), wchar_t(0x0451), wchar_t(0x043C), wchar_t(0x0000)};
static wchar_t const ie_m_End[] = { wchar_t(2), wchar_t(0x0435), wchar_t(0x043C), wchar_t(0x0000)};
static wchar_t const soft_End[] = { wchar_t(1), wchar_t(0x044C), wchar_t(0x0000)};
static wchar_t const j_End[] = { wchar_t(1), wchar_t(0x0439), wchar_t(0x0000)};
static std::wstring const a_End = { wchar_t(0x0430), wchar_t(0x0000) };
static std::wstring const o_End = { wchar_t(0x043E), wchar_t(0x0000) };
static std::wstring const ya_End = { wchar_t(0x044F), wchar_t(0x0000) };
static std::wstring const ie_End = { wchar_t(0x0435), wchar_t(0x0000) };
static std::wstring const i_End = { wchar_t(0x0438), wchar_t(0x0000) };
static std::wstring const yeru_End = { wchar_t(0x044B), wchar_t(0x0000) };
static std::wstring const u_End = { wchar_t(0x0443), wchar_t(0x0000) };
static std::wstring const yu_End = { wchar_t(0x044E), wchar_t(0x0000) };
static std::wstring const oj_End = { wchar_t(0x043E), wchar_t(0x0439), wchar_t(0x0000) };
static std::wstring const ie_j_End = { wchar_t(0x0435), wchar_t(0x0439), wchar_t(0x0000) };
static std::wstring const io_j_End = { wchar_t(0x0451), wchar_t(0x0439), wchar_t(0x0000) };
static std::wstring const o_m_End = { wchar_t(0x043E), wchar_t(0x043C), wchar_t(0x0000) };
static std::wstring const io_m_End = { wchar_t(0x0451), wchar_t(0x043C), wchar_t(0x0000) };
static std::wstring const ie_m_End = { wchar_t(0x0435), wchar_t(0x043C), wchar_t(0x0000) };
static std::wstring const soft_End = { wchar_t(0x044C), wchar_t(0x0000) };
static std::wstring const j_End = { wchar_t(0x0439), wchar_t(0x0000) };
static wchar_t const* const dropEnds[6][8] = {
{ &a_End[1], &o_End[1], &ya_End[1], &ie_End[1], &soft_End[1], &j_End[1], NULL, NULL },
{ &a_End[1], &ya_End[1], &yeru_End[1], &i_End[1], NULL, NULL, NULL, NULL },
{ &ie_End[1], &u_End[1], &yu_End[1], &i_End[1], NULL, NULL, NULL, NULL },
{ &u_End[1], &yu_End[1], &o_End[1], &ie_End[1], &soft_End[1], &ya_End[1], &a_End[1], NULL },
{ &oj_End[1], &io_j_End[1], &ie_j_End[1], &o_m_End[1], &io_m_End[1], &ie_m_End[1], &yu_End[1], NULL },
{ &ie_End[1], &i_End[1], NULL, NULL, NULL, NULL, NULL, NULL }
};
static std::array<std::array<std::wstring const*, 7>, 6> const dropEnds = {{
{ &a_End, &o_End, &ya_End, &ie_End, &soft_End, &j_End, nullptr },
{ &a_End, &ya_End, &yeru_End, &i_End, nullptr, nullptr, nullptr },
{ &ie_End, &u_End, &yu_End, &i_End, nullptr, nullptr, nullptr },
{ &u_End, &yu_End, &o_End, &ie_End, &soft_End, &ya_End, &a_End },
{ &oj_End, &io_j_End, &ie_j_End, &o_m_End, &io_m_End, &ie_m_End, &yu_End },
{ &ie_End, &i_End, nullptr, nullptr, nullptr, nullptr, nullptr }
}};
for (wchar_t const* const* itr = &dropEnds[declension][0]; *itr; ++itr)
std::size_t const thisLen = wname.length();
std::array<std::wstring const*, 7> const& endings = dropEnds[declension];
for (auto itr = endings.begin(), end = endings.end(); (itr != end) && *itr; ++itr)
{
size_t len = size_t((*itr)[-1]); // get length from string size field
std::wstring const& ending = **itr;
std::size_t const endLen = ending.length();
if (!(endLen <= thisLen))
continue;
if (wname.substr(wname.size()-len, len)==*itr)
return wname.substr(0, wname.size()-len);
if (wname.substr(thisLen-endLen, thisLen) == ending)
return wname.substr(0, thisLen-endLen);
}
return wname;