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

Reply via email to