svl/source/numbers/numfmuno.cxx |   51 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

New commits:
commit 8661d5579bd19a9e294ddff64bbe817b537dbd46
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Tue Jun 14 17:21:18 2022 +0200
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Wed Jun 15 11:03:53 2022 +0200

    Resolves: tdf#149325 tdf#52602 SvNumberFormatsObj::queryKey try also 
uppercase
    
    ... keywords; that should catch most lower case queries. If there
    are still remaining mismatches then either implement the bScan
    thing, or enhance addNew() to not fail on case-different format
    codes. That could be hit for the `General` keyword, for example.
    
    Change-Id: Ic728b8c5e38db76eb791cb305595f84acf7dc867
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135854
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/svl/source/numbers/numfmuno.cxx b/svl/source/numbers/numfmuno.cxx
index 98ead86e432d..4c3d4abda553 100644
--- a/svl/source/numbers/numfmuno.cxx
+++ b/svl/source/numbers/numfmuno.cxx
@@ -411,8 +411,55 @@ sal_Int32 SAL_CALL SvNumberFormatsObj::queryKey( const 
OUString& aFormat,
     {
         //! FIXME: Something still needs to happen here ...
     }
-    sal_Int32 nRet = pFormatter->GetEntryKey( aFormat, eLang );
-    return nRet;
+    sal_uInt32 nRet = pFormatter->GetEntryKey( aFormat, eLang );
+    if (nRet == NUMBERFORMAT_ENTRY_NOT_FOUND)
+    {
+        // This seems to be a workaround for what maybe the bScan option was
+        // intended for? Tokenize the format code?
+
+        // The format string based search is vague and fuzzy, as it is case
+        // sensitive, but the format string is only half way cased, the
+        // keywords (except the "General" keyword) are uppercased and literals
+        // of course are not. Clients using this queryKey() and if not
+        // successful addNew() may still fail if the result of PutEntry() is
+        // false because the format actually existed, just with a different
+        // casing. The only clean way is to just use PutEntry() and ignore the
+        // duplicate case, which clients can't because the API doesn't provide
+        // the information.
+        // Try just another possibilty here, without any guarantee.
+
+        // Use only ASCII upper, because keywords are only those.
+        // Do not transliterate any quoted literals.
+        const sal_Int32 nLen = aFormat.getLength();
+        OUStringBuffer aBuf(0);
+        sal_Unicode* p = aBuf.appendUninitialized( nLen + 1);
+        memcpy( p, aFormat.getStr(), (nLen + 1) * sizeof(sal_Unicode));   // 
including 0-char
+        aBuf.setLength( nLen);
+        assert(p == aBuf.getStr());
+        sal_Unicode const * const pStop = p + aBuf.getLength();
+        bool bQuoted = false;
+        for ( ; p < pStop; ++p)
+        {
+            if (bQuoted)
+            {
+                // Format codes don't have embedded doubled quotes, i.e. "a""b"
+                // is two literals displayed as `ab`.
+                if (*p == '"')
+                    bQuoted = false;
+            }
+            else if (*p == '"')
+                bQuoted = true;
+            else if ('a' <= *p && *p <= 'z')
+                *p -= 0x20;     // upper
+            else if (*p == '\\')
+                ++p;            // skip escaped next char
+                // Theoretically that should cater for UTF-32 with
+                // iterateCodePoints(), but such character would not match any
+                // of [a-z\"] in its UTF-16 units.
+        }
+        nRet = pFormatter->GetEntryKey( aBuf, eLang );
+    }
+    return static_cast<sal_Int32>(nRet);
 }
 
 sal_Int32 SAL_CALL SvNumberFormatsObj::addNew( const OUString& aFormat,

Reply via email to