unotools/source/i18n/resmgr.cxx | 43 ++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-)
New commits: commit 7712eb23bc97090fdd655a36dfca0019d43799e6 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sun Jul 18 10:07:57 2021 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Jul 19 08:54:40 2021 +0200 tdf#143409: fix Translation is not applied in some UI regression from commit 0771ac00acc8730f77db76b901724f1513a32723 Author: Noel Grandin <n...@peralex.com> Date: Tue Jun 15 21:12:25 2021 +0200 use string_view in the Translate API Because I mixed string_view with C-style null-terminated strings. We are using string_view.data() to pass stuff to boost, but of course, doing that loses the fact that the string data has associated length, as it finds the length by looking for a terminating NULL. Change-Id: Ia0eb7be5621506dfe0a40a21f360da1b446f5591 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119120 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/unotools/source/i18n/resmgr.cxx b/unotools/source/i18n/resmgr.cxx index cdca420e2636..d35282025c4e 100644 --- a/unotools/source/i18n/resmgr.cxx +++ b/unotools/source/i18n/resmgr.cxx @@ -48,6 +48,7 @@ #include <boost/locale.hpp> #include <boost/locale/gnu_gettext.hpp> +#include <array> #include <unordered_map> #include <memory> @@ -199,27 +200,49 @@ namespace Translate OUString get(std::string_view sContextAndId, const std::locale &loc) { - std::string_view sContext; - std::string_view sId; - const char *p = strchr(sContextAndId.data(), '\004'); - if (!p) - sId = sContextAndId; + constexpr int BUFLEN = 128; + // this function is performance-sensitive, so we allocate string data on stack + std::array<char, BUFLEN> sStackBuffer; + std::unique_ptr<char[]> xHeapBuffer; + char* pBuffer; + if (sContextAndId.size() < BUFLEN - 1) + pBuffer = sStackBuffer.data(); else { - sContext = std::string_view(sContextAndId.data(), p - sContextAndId.data()); - sId = sContextAndId.substr(p - sContextAndId.data() + 1); - assert(!strchr(sId.data(), '\004') && "should be using nget, not get"); + xHeapBuffer = std::make_unique<char[]>(sContextAndId.size()+1); + pBuffer = xHeapBuffer.get(); + } + + const char* pContext; + const char* pId; + auto idx = sContextAndId.find('\004'); + memcpy(pBuffer, sContextAndId.data(), sContextAndId.size()); + if (idx == std::string_view::npos) + { + pBuffer[sContextAndId.size()] = 0; + // point pContext at the null byte so it is an empty string + pContext = pBuffer + sContextAndId.size(); + pId = pBuffer; + } + else + { + // stick a null byte in the middle to split it into two null-terminated strings + pBuffer[idx] = 0; + pBuffer[sContextAndId.size()] = 0; + pContext = pBuffer; + pId = pBuffer + idx + 1; + assert(!strchr(pId, '\004') && "should be using nget, not get"); } //if it's a key id locale, generate it here if (std::use_facet<boost::locale::info>(loc).language() == "qtz") { OString sKeyId(genKeyId(OString(sContextAndId).replace('\004', '|'))); - return OUString::fromUtf8(sKeyId) + u"\u2016" + createFromUtf8(sId.data(), sId.size()); + return OUString::fromUtf8(sKeyId) + u"\u2016" + createFromUtf8(pId, strlen(pId)); } //otherwise translate it - const std::string ret = boost::locale::pgettext(sContext.data(), sId.data(), loc); + const std::string ret = boost::locale::pgettext(pContext, pId, loc); OUString result(ExpandVariables(createFromUtf8(ret.data(), ret.size()))); if (comphelper::LibreOfficeKit::isActive()) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits