summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2022-06-14 17:21:18 +0200
committerEike Rathke <erack@redhat.com>2022-06-15 11:03:53 +0200
commit8661d5579bd19a9e294ddff64bbe817b537dbd46 (patch)
treea3dba05dcb75abf15622ce7969fa36a284ce45e5 /svl
parent20b19869eab5b991551a6bee7803e5b5c3dffee3 (diff)
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 <erack@redhat.com>
Diffstat (limited to 'svl')
-rw-r--r--svl/source/numbers/numfmuno.cxx51
1 files changed, 49 insertions, 2 deletions
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,