comphelper/source/misc/string.cxx |   30 ++++++++++
 include/comphelper/string.hxx     |    7 ++
 include/tools/urlobj.hxx          |   64 ++++++++++++++++++----
 tools/source/fsys/urlobj.cxx      |  107 +++++++++++++++++++-------------------
 4 files changed, 142 insertions(+), 66 deletions(-)

New commits:
commit 6510cbc486867db25d1d772f4a3b0b7b9bb2fc08
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri May 20 12:54:07 2022 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Fri May 20 19:54:57 2022 +0200

    elide temporary OUStringBuffer in INetURLObject
    
    which requires a version of replaceAt for OUStringBuffer, which I'll put
    in comphelper::string:: for now
    
    Change-Id: I70b319b018e29a7dac26965dd92f6c4f9ea470ec
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134679
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/comphelper/source/misc/string.cxx 
b/comphelper/source/misc/string.cxx
index 8daeb377482a..0041f53d153d 100644
--- a/comphelper/source/misc/string.cxx
+++ b/comphelper/source/misc/string.cxx
@@ -624,6 +624,36 @@ OUString setToken(const OUString& rIn, sal_Int32 nToken, 
sal_Unicode cTok,
     return rIn;
 }
 
+/** Similar to OUString::replaceAt, but for an OUStringBuffer.
+
+    Replace n = count characters
+    from position index in this string with newStr.
+ */
+void replaceAt(OUStringBuffer& rIn, sal_Int32 nIndex, sal_Int32 nCount, 
std::u16string_view newStr )
+{
+    assert(nIndex >= 0 && nIndex <= rIn.getLength());
+    assert(nCount >= 0);
+    assert(nCount <= rIn.getLength() - nIndex);
+
+    /* Append? */
+    const sal_Int32 nOldLength = rIn.getLength();
+    if ( nIndex == nOldLength )
+    {
+        rIn.append(newStr);
+        return;
+    }
+
+    sal_Int32 nNewLength = nOldLength + newStr.size() - nCount;
+    if (static_cast<sal_Int32>(newStr.size()) > nCount)
+        rIn.ensureCapacity(nOldLength + newStr.size() - nCount);
+
+    sal_Unicode* pStr = const_cast<sal_Unicode*>(rIn.getStr());
+    memmove(pStr + nIndex + newStr.size(), pStr + nIndex + nCount, nOldLength 
- nIndex + nCount);
+    memcpy(pStr + nIndex, newStr.data(), newStr.size());
+
+    rIn.setLength(nNewLength);
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/string.hxx b/include/comphelper/string.hxx
index 4fe10b71b3f0..86ca9c4d8ecb 100644
--- a/include/comphelper/string.hxx
+++ b/include/comphelper/string.hxx
@@ -231,6 +231,13 @@ inline OUStringBuffer& padToLength(
     return detail::padToLength(rBuffer, nLength, cFill);
 }
 
+/** Similar to OUString::replaceAt, but for an OUStringBuffer.
+
+    Replace n = count characters
+    from position index in this string with newStr.
+ */
+COMPHELPER_DLLPUBLIC void replaceAt(OUStringBuffer& rIn, sal_Int32 index, 
sal_Int32 count, std::u16string_view newStr );
+
 /** Replace a token in a string
     @param rIn       OUString in which the token is to be replaced
     @param nToken    which nToken to replace
diff --git a/include/tools/urlobj.hxx b/include/tools/urlobj.hxx
index b99187a1caa3..6096e60df1b2 100644
--- a/include/tools/urlobj.hxx
+++ b/include/tools/urlobj.hxx
@@ -822,10 +822,33 @@ public:
         @return  The text, encoded according to the given mechanism and
         charset ('forbidden' characters replaced by escape sequences).
      */
-    static inline OUString encode(std::u16string_view rText, Part ePart,
-                                   EncodeMechanism eMechanism,
-                                   rtl_TextEncoding eCharset
-                                       = RTL_TEXTENCODING_UTF8);
+    static void encode( OUStringBuffer& rOutputBuffer,
+                           std::u16string_view rText, Part ePart,
+                           EncodeMechanism eMechanism,
+                           rtl_TextEncoding eCharset
+                               = RTL_TEXTENCODING_UTF8);
+
+    /** Encode some text as part of a URI.
+
+        @param rText  Some text (for its interpretation, see the general
+        discussion for set-methods).
+
+        @param ePart  The part says which characters are 'forbidden' and must
+        be encoded (replaced by escape sequences).  Characters outside the US-
+        ASCII range are always 'forbidden.'
+
+        @param eMechanism  See the general discussion for set-methods.
+
+        @param eCharset  See the general discussion for set-methods.
+
+        @return  The text, encoded according to the given mechanism and
+        charset ('forbidden' characters replaced by escape sequences).
+     */
+    static OUString encode( std::u16string_view rText, Part ePart,
+                           EncodeMechanism eMechanism,
+                           rtl_TextEncoding eCharset
+                               = RTL_TEXTENCODING_UTF8);
+
 
     /** Decode some text.
 
@@ -1093,12 +1116,14 @@ private:
     TOOLS_DLLPRIVATE static inline void appendEscape(
         OUStringBuffer & rTheText, sal_uInt32 nOctet);
 
-    static OUString encodeText(
+    static void encodeText(
+        OUStringBuffer& rOutputBuffer,
         sal_Unicode const * pBegin, sal_Unicode const * pEnd,
         Part ePart, EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
         bool bKeepVisibleEscapes);
 
-    static inline OUString encodeText(
+    static inline void encodeText(
+        OUStringBuffer& rOutputBuffer,
         std::u16string_view rTheText, Part ePart,
         EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
         bool bKeepVisibleEscapes);
@@ -1118,15 +1143,17 @@ private:
 };
 
 // static
-inline OUString INetURLObject::encodeText(std::u16string_view rTheText,
+inline void INetURLObject::encodeText( OUStringBuffer& rOutputBuffer,
+                                           std::u16string_view rTheText,
                                            Part ePart,
                                            EncodeMechanism eMechanism,
                                            rtl_TextEncoding eCharset,
                                            bool bKeepVisibleEscapes)
 {
-    return encodeText(rTheText.data(),
-                      rTheText.data() + rTheText.size(), ePart,
-                      eMechanism, eCharset, bKeepVisibleEscapes);
+    encodeText(rOutputBuffer,
+                rTheText.data(),
+                rTheText.data() + rTheText.size(), ePart,
+                eMechanism, eCharset, bKeepVisibleEscapes);
 }
 
 inline OUString INetURLObject::decode(SubString const & rSubString,
@@ -1283,12 +1310,23 @@ inline bool INetURLObject::SetMark(std::u16string_view 
rTheFragment,
                setFragment(rTheFragment, eMechanism, eCharset);
 }
 
+// static
+inline void INetURLObject::encode(OUStringBuffer& rOutputBuffer,
+                                   std::u16string_view rText, Part ePart,
+                                   EncodeMechanism eMechanism,
+                                   rtl_TextEncoding eCharset)
+{
+    encodeText(rOutputBuffer, rText, ePart, eMechanism, eCharset, false);
+}
+
 // static
 inline OUString INetURLObject::encode(std::u16string_view rText, Part ePart,
-                                       EncodeMechanism eMechanism,
-                                       rtl_TextEncoding eCharset)
+                                   EncodeMechanism eMechanism,
+                                   rtl_TextEncoding eCharset)
 {
-    return encodeText(rText, ePart, eMechanism, eCharset, false);
+    OUStringBuffer aBuf;
+    encodeText(aBuf, rText, ePart, eMechanism, eCharset, false);
+    return aBuf.makeStringAndClear();
 }
 
 // static
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
index a6f2329e281d..78c6d22af504 100644
--- a/tools/source/fsys/urlobj.cxx
+++ b/tools/source/fsys/urlobj.cxx
@@ -45,6 +45,7 @@
 
 #include <com/sun/star/uno/Sequence.hxx>
 #include <comphelper/base64.hxx>
+#include <comphelper/string.hxx>
 
 using namespace css;
 
@@ -2085,8 +2086,9 @@ bool INetURLObject::convertIntToExt(std::u16string_view 
rTheIntURIRef,
                                     DecodeMechanism eDecodeMechanism,
                                     rtl_TextEncoding eCharset)
 {
-    OUString aSynExtURIRef(encodeText(rTheIntURIRef, PART_VISIBLE,
-                                       EncodeMechanism::NotCanonical, 
eCharset, true));
+    OUStringBuffer aSynExtURIRef(256);
+    encodeText(aSynExtURIRef, rTheIntURIRef, PART_VISIBLE,
+               EncodeMechanism::NotCanonical, eCharset, true);
     sal_Unicode const * pBegin = aSynExtURIRef.getStr();
     sal_Unicode const * pEnd = pBegin + aSynExtURIRef.getLength();
     sal_Unicode const * p = pBegin;
@@ -2094,8 +2096,7 @@ bool INetURLObject::convertIntToExt(std::u16string_view 
rTheIntURIRef,
     bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::Kind::Internal;
     if (bConvert)
     {
-        aSynExtURIRef =
-            aSynExtURIRef.replaceAt(0, p - pBegin,
+        comphelper::string::replaceAt(aSynExtURIRef, 0, p - pBegin,
                 OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
     }
     rTheExtURIRef = decode(aSynExtURIRef, eDecodeMechanism, eCharset);
@@ -2108,8 +2109,9 @@ bool INetURLObject::convertExtToInt(std::u16string_view 
rTheExtURIRef,
                                     DecodeMechanism eDecodeMechanism,
                                     rtl_TextEncoding eCharset)
 {
-    OUString aSynIntURIRef(encodeText(rTheExtURIRef, PART_VISIBLE,
-                                       EncodeMechanism::NotCanonical, 
eCharset, true));
+    OUStringBuffer aSynIntURIRef(256);
+    encodeText(aSynIntURIRef, rTheExtURIRef, PART_VISIBLE,
+               EncodeMechanism::NotCanonical, eCharset, true);
     sal_Unicode const * pBegin = aSynIntURIRef.getStr();
     sal_Unicode const * pEnd = pBegin + aSynIntURIRef.getLength();
     sal_Unicode const * p = pBegin;
@@ -2117,9 +2119,8 @@ bool INetURLObject::convertExtToInt(std::u16string_view 
rTheExtURIRef,
     bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::Kind::External;
     if (bConvert)
     {
-        aSynIntURIRef =
-            aSynIntURIRef.replaceAt(0, p - pBegin,
-                OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
+        comphelper::string::replaceAt(aSynIntURIRef, 0, p - pBegin,
+            OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
     }
     rTheIntURIRef = decode(aSynIntURIRef, eDecodeMechanism, eCharset);
     return bConvert;
@@ -2288,8 +2289,9 @@ bool INetURLObject::setUser(std::u16string_view rTheUser,
         return false;
     }
 
-    OUString aNewUser(encodeText(rTheUser, PART_USER_PASSWORD,
-                                  EncodeMechanism::WasEncoded, eCharset, 
false));
+    OUStringBuffer aNewUser;
+    encodeText(aNewUser, rTheUser, PART_USER_PASSWORD,
+              EncodeMechanism::WasEncoded, eCharset, false);
     sal_Int32 nDelta;
     if (m_aUser.isPresent())
         nDelta = m_aUser.set(m_aAbsURIRef, aNewUser);
@@ -2343,8 +2345,9 @@ bool INetURLObject::setPassword(std::u16string_view 
rThePassword,
 {
     if (!getSchemeInfo().m_bPassword)
         return false;
-    OUString aNewAuth(encodeText(rThePassword, PART_USER_PASSWORD,
-                                  EncodeMechanism::WasEncoded, eCharset, 
false));
+    OUStringBuffer aNewAuth;
+    encodeText(aNewAuth, rThePassword, PART_USER_PASSWORD,
+                  EncodeMechanism::WasEncoded, eCharset, false);
     sal_Int32 nDelta;
     if (m_aAuth.isPresent())
         nDelta = m_aAuth.set(m_aAbsURIRef, aNewAuth);
@@ -3355,8 +3358,8 @@ bool INetURLObject::insertName(std::u16string_view 
rTheName,
     OUStringBuffer aNewPath(256);
     aNewPath.append(pPathBegin, pPrefixEnd - pPathBegin);
     aNewPath.append('/');
-    aNewPath.append(encodeText(rTheName, PART_PCHAR,
-                           eMechanism, eCharset, true));
+    encodeText(aNewPath, rTheName, PART_PCHAR,
+               eMechanism, eCharset, true);
     if (bInsertSlash) {
         aNewPath.append('/');
     }
@@ -3384,8 +3387,9 @@ bool INetURLObject::setQuery(std::u16string_view 
rTheQuery,
 {
     if (!getSchemeInfo().m_bQuery)
         return false;
-    OUString aNewQuery(encodeText(rTheQuery, PART_URIC,
-                                   eMechanism, eCharset, true));
+    OUStringBuffer aNewQuery;
+    encodeText(aNewQuery, rTheQuery, PART_URIC,
+               eMechanism, eCharset, true);
     sal_Int32 nDelta;
     if (m_aQuery.isPresent())
         nDelta = m_aQuery.set(m_aAbsURIRef, aNewQuery);
@@ -3417,8 +3421,9 @@ bool INetURLObject::setFragment(std::u16string_view 
rTheFragment,
 {
     if (HasError())
         return false;
-    OUString aNewFragment(encodeText(rTheFragment, PART_URIC,
-                                      eMechanism, eCharset, true));
+    OUStringBuffer aNewFragment;
+    encodeText(aNewFragment, rTheFragment, PART_URIC,
+              eMechanism, eCharset, true);
     if (m_aFragment.isPresent())
         m_aFragment.set(m_aAbsURIRef, aNewFragment);
     else
@@ -3441,22 +3446,21 @@ bool INetURLObject::hasDosVolume(FSysStyle eStyle) const
 }
 
 // static
-OUString INetURLObject::encodeText(sal_Unicode const * pBegin,
-                                    sal_Unicode const * pEnd,
-                                    Part ePart, EncodeMechanism eMechanism,
-                                    rtl_TextEncoding eCharset,
-                                    bool bKeepVisibleEscapes)
+void INetURLObject::encodeText( OUStringBuffer& rOutputBuffer,
+                                sal_Unicode const * pBegin,
+                                sal_Unicode const * pEnd,
+                                Part ePart, EncodeMechanism eMechanism,
+                                rtl_TextEncoding eCharset,
+                                bool bKeepVisibleEscapes)
 {
-    OUStringBuffer aResult(256);
     while (pBegin < pEnd)
     {
         EscapeType eEscapeType;
         sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd,
                                      eMechanism, eCharset, eEscapeType);
-        appendUCS4(aResult, nUTF32, eEscapeType, ePart,
+        appendUCS4(rOutputBuffer, nUTF32, eEscapeType, ePart,
                    eCharset, bKeepVisibleEscapes);
     }
-    return aResult.makeStringAndClear();
 }
 
 // static
@@ -3790,10 +3794,10 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
         {
             if (!rTheUser.empty())
             {
-                m_aUser.set(m_aAbsURIRef,
-                            encodeText(rTheUser, PART_USER_PASSWORD,
-                                       EncodeMechanism::WasEncoded, 
RTL_TEXTENCODING_UTF8, false),
-                            m_aAbsURIRef.getLength());
+                OUStringBuffer aNewUser;
+                encodeText(aNewUser, rTheUser, PART_USER_PASSWORD,
+                           EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, 
false);
+                m_aUser.set(m_aAbsURIRef, aNewUser, m_aAbsURIRef.getLength());
                 bUserInfo = true;
             }
         }
@@ -3807,10 +3811,10 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
             if (getSchemeInfo().m_bPassword)
             {
                 m_aAbsURIRef.append(':');
-                m_aAuth.set(m_aAbsURIRef,
-                            encodeText(rThePassword, PART_USER_PASSWORD,
-                                       EncodeMechanism::WasEncoded, 
RTL_TEXTENCODING_UTF8, false),
-                            m_aAbsURIRef.getLength());
+                OUStringBuffer aNewAuth;
+                encodeText(aNewAuth, rThePassword, PART_USER_PASSWORD,
+                           EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, 
false);
+                m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aAbsURIRef.getLength());
                 bUserInfo = true;
             }
             else
@@ -4101,12 +4105,11 @@ bool INetURLObject::setName(std::u16string_view 
rTheName, EncodeMechanism eMecha
     while (p != pSegEnd && *p != ';')
         ++p;
 
-    return setPath(
-        rtl::OUStringConcatenation(std::u16string_view(pPathBegin, pSegBegin - 
pPathBegin)
-            + encodeText(rTheName, PART_PCHAR, eMechanism, eCharset, true)
-            + std::u16string_view(p, pPathEnd - p)),
-        EncodeMechanism::NotCanonical,
-        RTL_TEXTENCODING_UTF8);
+    OUStringBuffer aNewPath(256);
+    aNewPath.append(std::u16string_view(pPathBegin, pSegBegin - pPathBegin));
+    encodeText(aNewPath, rTheName, PART_PCHAR, eMechanism, eCharset, true);
+    aNewPath.append(std::u16string_view(p, pPathEnd - p));
+    return setPath(aNewPath, EncodeMechanism::NotCanonical, 
RTL_TEXTENCODING_UTF8);
 }
 
 bool INetURLObject::hasExtension()
@@ -4178,12 +4181,11 @@ bool INetURLObject::setBase(std::u16string_view 
rTheBase, sal_Int32 nIndex,
     if (!pExtension)
         pExtension = p;
 
-    return setPath(
-        rtl::OUStringConcatenation(std::u16string_view(pPathBegin, pSegBegin - 
pPathBegin)
-            + encodeText(rTheBase, PART_PCHAR, eMechanism, eCharset, true)
-            + std::u16string_view(pExtension, pPathEnd - pExtension)),
-        EncodeMechanism::NotCanonical,
-        RTL_TEXTENCODING_UTF8);
+    OUStringBuffer aNewPath(256);
+    aNewPath.append(std::u16string_view(pPathBegin, pSegBegin - pPathBegin));
+    encodeText(aNewPath, rTheBase, PART_PCHAR, eMechanism, eCharset, true);
+    aNewPath.append(std::u16string_view(pExtension, pPathEnd - pExtension));
+    return setPath(aNewPath, EncodeMechanism::NotCanonical, 
RTL_TEXTENCODING_UTF8);
 }
 
 OUString INetURLObject::getExtension(sal_Int32 nIndex,
@@ -4238,12 +4240,11 @@ bool INetURLObject::setExtension(std::u16string_view 
rTheExtension,
     if (!pExtension)
         pExtension = p;
 
-    return setPath(
-        
rtl::OUStringConcatenation(OUString::Concat(std::u16string_view(pPathBegin, 
pExtension - pPathBegin)) + "."
-            + encodeText(rTheExtension, PART_PCHAR, 
EncodeMechanism::WasEncoded, eCharset, true)
-            + std::u16string_view(p, pPathEnd - p)),
-        EncodeMechanism::NotCanonical,
-        RTL_TEXTENCODING_UTF8);
+    OUStringBuffer aNewPath(256);
+    aNewPath.append(OUString::Concat(std::u16string_view(pPathBegin, 
pExtension - pPathBegin)) + ".");
+    encodeText(aNewPath, rTheExtension, PART_PCHAR, 
EncodeMechanism::WasEncoded, eCharset, true);
+    aNewPath.append(std::u16string_view(p, pPathEnd - p));
+    return setPath(aNewPath, EncodeMechanism::NotCanonical, 
RTL_TEXTENCODING_UTF8);
 }
 
 bool INetURLObject::removeExtension(sal_Int32 nIndex, bool bIgnoreFinalSlash)

Reply via email to