comphelper/source/misc/mimeconfighelper.cxx                       |   21 ---
 configmgr/source/valueparser.cxx                                  |   22 +--
 dbaccess/source/filter/hsqldb/utils.cxx                           |   27 ----
 filter/source/msfilter/rtfutil.cxx                                |   21 ---
 include/o3tl/numeric.hxx                                          |   37 ++++--
 include/tools/Guid.hxx                                            |   50 
++------
 include/tools/inetmime.hxx                                        |    5 
 o3tl/CppunitTest_o3tl_tests.mk                                    |    1 
 o3tl/qa/test-numeric.cxx                                          |   57 
++++++++++
 oox/source/dump/dumperbase.cxx                                    |   12 --
 oox/source/ppt/pptfilterhelpers.cxx                               |   24 ----
 sal/rtl/bootstrap.cxx                                             |   17 --
 sax/source/tools/converter.cxx                                    |   19 ---
 stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx |   12 --
 svl/source/crypto/cryptosign.cxx                                  |   21 ---
 svl/source/numbers/zformat.cxx                                    |   27 +---
 sw/qa/extras/htmlexport/htmlmodeltestbase.hxx                     |    3 
 sw/source/uibase/config/modcfg.cxx                                |   13 --
 sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx                 |    5 
 sw/source/writerfilter/rtftok/rtftokenizer.cxx                    |    3 
 vcl/qa/cppunit/pdfexport/PDFEncryptionTest.cxx                    |   19 ---
 vcl/source/gdi/WidgetDefinitionReader.cxx                         |   19 ---
 xmloff/source/core/xmluconv.cxx                                   |   16 --
 xmloff/source/transform/TransformerBase.cxx                       |   19 ---
 xmlreader/source/xmlreader.cxx                                    |   16 +-
 25 files changed, 180 insertions(+), 306 deletions(-)

New commits:
commit 2990620e202eb59edce160264e25ca63ba4a93ba
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Jan 17 14:06:35 2025 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Mon Jan 20 01:39:16 2025 +0100

    remove code duplication - conversion hex char to value
    
    We use the same funciton all over the place, so create a common
    function in o3tl and use that in all instances where we duplicated
    the code.
    
    Change-Id: I74091fbbde8c2ba8c7e4ab30194ab53e2a338e52
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180372
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/comphelper/source/misc/mimeconfighelper.cxx 
b/comphelper/source/misc/mimeconfighelper.cxx
index 0cdacb41554f..1702bba64c0a 100644
--- a/comphelper/source/misc/mimeconfighelper.cxx
+++ b/comphelper/source/misc/mimeconfighelper.cxx
@@ -33,6 +33,7 @@
 #include <comphelper/documentconstants.hxx>
 #include <comphelper/propertysequence.hxx>
 #include <rtl/ustrbuf.hxx>
+#include <o3tl/numeric.hxx>
 #include <utility>
 
 
@@ -68,20 +69,6 @@ OUString 
MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Seq
     return aResult.makeStringAndClear();
 }
 
-
-static sal_uInt8 GetDigit_Impl( char aChar )
-{
-    if ( aChar >= '0' && aChar <= '9' )
-        return aChar - '0';
-    else if ( aChar >= 'a' && aChar <= 'f' )
-        return aChar - 'a' + 10;
-    else if ( aChar >= 'A' && aChar <= 'F' )
-        return aChar - 'A' + 10;
-    else
-        return 16;
-}
-
-
 uno::Sequence< sal_Int8 > 
MimeConfigurationHelper::GetSequenceClassIDRepresentation( std::u16string_view 
aClassID )
 {
     size_t nLength = aClassID.size();
@@ -95,10 +82,10 @@ uno::Sequence< sal_Int8 > 
MimeConfigurationHelper::GetSequenceClassIDRepresentat
         sal_Int32 nSeqInd = 0;
         while( nSeqInd < 16 && nStrPointer + 1U < nLength )
         {
-            sal_uInt8 nDigit1 = GetDigit_Impl( aCharClassID[nStrPointer++] );
-            sal_uInt8 nDigit2 = GetDigit_Impl( aCharClassID[nStrPointer++] );
+            sal_uInt8 nDigit1 = 
o3tl::convertToHex<sal_uInt8>(aCharClassID[nStrPointer++]);
+            sal_uInt8 nDigit2 = 
o3tl::convertToHex<sal_uInt8>(aCharClassID[nStrPointer++]);
 
-            if ( nDigit1 > 15 || nDigit2 > 15 )
+            if (nDigit1 > 15 || nDigit2 > 15)
                 break;
 
             pResult[nSeqInd++] = static_cast<sal_Int8>( nDigit1 * 16 + nDigit2 
);
diff --git a/configmgr/source/valueparser.cxx b/configmgr/source/valueparser.cxx
index edf39add25e5..0b07efda235b 100644
--- a/configmgr/source/valueparser.cxx
+++ b/configmgr/source/valueparser.cxx
@@ -26,6 +26,7 @@
 #include <com/sun/star/uno/Sequence.hxx>
 #include <comphelper/sequence.hxx>
 #include <o3tl/string_view.hxx>
+#include <o3tl/numeric.hxx>
 #include <rtl/math.h>
 #include <rtl/string.h>
 #include <rtl/string.hxx>
@@ -47,21 +48,14 @@ namespace configmgr {
 
 namespace {
 
-bool parseHexDigit(char c, int * value) {
+bool parseHexDigit(char c, int * value)
+{
     assert(value != nullptr);
-    if (c >= '0' && c <= '9') {
-        *value = c - '0';
-        return true;
-    }
-    if (c >= 'A' && c <= 'F') {
-        *value = c - 'A' + 10;
-        return true;
-    }
-    if (c >= 'a' && c <= 'f') {
-        *value = c - 'a' + 10;
-        return true;
-    }
-    return false;
+    int converted = o3tl::convertToHex<int>(c);
+    if (converted < 0)
+        return false;
+    *value = converted;
+    return true;
 }
 
 bool parseValue(xmlreader::Span const & text, sal_Bool * value) {
diff --git a/dbaccess/source/filter/hsqldb/utils.cxx 
b/dbaccess/source/filter/hsqldb/utils.cxx
index 4ed05ae5075a..ac479d9e05a2 100644
--- a/dbaccess/source/filter/hsqldb/utils.cxx
+++ b/dbaccess/source/filter/hsqldb/utils.cxx
@@ -22,35 +22,12 @@
 #include <comphelper/processfactory.hxx>
 #include <connectivity/dbexception.hxx>
 #include <sal/log.hxx>
+#include <o3tl/numeric.hxx>
 
 #include "utils.hxx"
 
 using namespace dbahsql;
 
-namespace
-{
-int getHexValue(sal_Unicode c)
-{
-    if (c >= '0' && c <= '9')
-    {
-        return c - '0';
-    }
-    else if (c >= 'A' && c <= 'F')
-    {
-        return c - 'A' + 10;
-    }
-    else if (c >= 'a' && c <= 'f')
-    {
-        return c - 'a' + 10;
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-} // unnamed namespace
-
 //Convert ascii escaped unicode to utf-8
 OUString utils::convertToUTF8(std::string_view original)
 {
@@ -69,7 +46,7 @@ OUString utils::convertToUTF8(std::string_view original)
             sal_Unicode c = 0;
             for (sal_Int32 j = 0; j != 4; ++j)
             {
-                auto const n = getHexValue(res[i + j]);
+                auto const n = o3tl::convertToHex<int>(res[i + j]);
                 if (n == -1)
                 {
                     escape = false;
diff --git a/filter/source/msfilter/rtfutil.cxx 
b/filter/source/msfilter/rtfutil.cxx
index f61cc9a5ce16..bb1b85876bfd 100644
--- a/filter/source/msfilter/rtfutil.cxx
+++ b/filter/source/msfilter/rtfutil.cxx
@@ -15,6 +15,7 @@
 #include <rtl/character.hxx>
 #include <tools/stream.hxx>
 #include <sot/storage.hxx>
+#include <o3tl/numeric.hxx>
 
 namespace
 {
@@ -250,24 +251,6 @@ OString OutStringUpr(std::string_view pToken, 
std::u16string_view rStr, rtl_Text
            + OutString(rStr, eDestEnc) + "}}}";
 }
 
-int AsHex(char ch)
-{
-    int ret = 0;
-    if (rtl::isAsciiDigit(static_cast<unsigned char>(ch)))
-        ret = ch - '0';
-    else
-    {
-        if (ch >= 'a' && ch <= 'f')
-            ret = ch - 'a';
-        else if (ch >= 'A' && ch <= 'F')
-            ret = ch - 'A';
-        else
-            return -1;
-        ret += 10;
-    }
-    return ret;
-}
-
 OString WriteHex(const sal_uInt8* pData, sal_uInt32 nSize, SvStream* pStream, 
sal_uInt32 nLimit)
 {
     OStringBuffer aRet;
@@ -313,7 +296,7 @@ bool ExtractOLE2FromObjdata(const OString& rObjdata, 
SvStream& rOle2)
         if (ch != 0x0d && ch != 0x0a)
         {
             b = b << 4;
-            sal_Int8 parsed = msfilter::rtfutil::AsHex(ch);
+            sal_Int8 parsed = o3tl::convertToHex<sal_Int8>(ch);
             if (parsed == -1)
                 return false;
             b += parsed;
diff --git a/include/o3tl/numeric.hxx b/include/o3tl/numeric.hxx
index 9980319a648b..5a6b4b17858b 100644
--- a/include/o3tl/numeric.hxx
+++ b/include/o3tl/numeric.hxx
@@ -7,22 +7,39 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#ifndef INCLUDED_O3TL_NUMERIC_HXX
-#define INCLUDED_O3TL_NUMERIC_HXX
-
+#pragma once
 #include <stdexcept>
+#include <o3tl/concepts.hxx>
 
 namespace o3tl
 {
-    struct divide_by_zero final : public std::runtime_error
+
+struct divide_by_zero final : public std::runtime_error
+{
+    explicit divide_by_zero()
+        : std::runtime_error("divide by zero")
     {
-        explicit divide_by_zero()
-            : std::runtime_error("divide by zero")
-        {
-        }
-    };
+    }
+};
+
+template <o3tl::integral T, o3tl::integral U>
+constexpr T convertToHex(U aChar)
+{
+    if (aChar >= '0' && aChar <= '9')
+        return T(aChar - '0');
+    else if (aChar >= 'a' && aChar <= 'f')
+        return T(aChar - 'a' + 10);
+    else if (aChar >= 'A' && aChar <= 'F')
+        return T(aChar - 'A' + 10);
+    return T(-1);
 }
 
-#endif
+template <o3tl::integral T, o3tl::integral U>
+constexpr T convertToHex(U cHigh, U cLow)
+{
+    return (o3tl::convertToHex<T>(cHigh) << 4) | o3tl::convertToHex<T>(cLow);
+}
+
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/Guid.hxx b/include/tools/Guid.hxx
index 3922a3da9ff2..1f7cc374a387 100644
--- a/include/tools/Guid.hxx
+++ b/include/tools/Guid.hxx
@@ -16,6 +16,7 @@
 #include <algorithm>
 #include <stdio.h>
 #include <cctype>
+#include <o3tl/numeric.hxx>
 
 namespace tools
 {
@@ -26,23 +27,6 @@ private:
 
     GuidArrayType maGuidArray;
 
-    static sal_uInt8 gethex(char nChar)
-    {
-        if (nChar >= '0' && nChar <= '9')
-            return nChar - '0';
-        else if (nChar >= 'a' && nChar <= 'f')
-            return nChar - 'a' + 10;
-        else if (nChar >= 'A' && nChar <= 'F')
-            return nChar - 'A' + 10;
-        else
-            return 0;
-    }
-
-    static sal_uInt8 covertHexChar(char high, char low)
-    {
-        return (gethex(high) << 4) + gethex(low);
-    }
-
     void parse(std::string_view rString)
     {
         if (rString.size() != 38)
@@ -68,26 +52,26 @@ private:
             if (!std::isxdigit(rString[x]))
                 return;
 
-        maGuidArray[0] = covertHexChar(rString[1], rString[2]);
-        maGuidArray[1] = covertHexChar(rString[3], rString[4]);
-        maGuidArray[2] = covertHexChar(rString[5], rString[6]);
-        maGuidArray[3] = covertHexChar(rString[7], rString[8]);
+        maGuidArray[0] = o3tl::convertToHex<sal_uInt8>(rString[1], rString[2]);
+        maGuidArray[1] = o3tl::convertToHex<sal_uInt8>(rString[3], rString[4]);
+        maGuidArray[2] = o3tl::convertToHex<sal_uInt8>(rString[5], rString[6]);
+        maGuidArray[3] = o3tl::convertToHex<sal_uInt8>(rString[7], rString[8]);
 
-        maGuidArray[4] = covertHexChar(rString[10], rString[11]);
-        maGuidArray[5] = covertHexChar(rString[12], rString[13]);
+        maGuidArray[4] = o3tl::convertToHex<sal_uInt8>(rString[10], 
rString[11]);
+        maGuidArray[5] = o3tl::convertToHex<sal_uInt8>(rString[12], 
rString[13]);
 
-        maGuidArray[6] = covertHexChar(rString[15], rString[16]);
-        maGuidArray[7] = covertHexChar(rString[17], rString[18]);
+        maGuidArray[6] = o3tl::convertToHex<sal_uInt8>(rString[15], 
rString[16]);
+        maGuidArray[7] = o3tl::convertToHex<sal_uInt8>(rString[17], 
rString[18]);
 
-        maGuidArray[8] = covertHexChar(rString[20], rString[21]);
-        maGuidArray[9] = covertHexChar(rString[22], rString[23]);
+        maGuidArray[8] = o3tl::convertToHex<sal_uInt8>(rString[20], 
rString[21]);
+        maGuidArray[9] = o3tl::convertToHex<sal_uInt8>(rString[22], 
rString[23]);
 
-        maGuidArray[10] = covertHexChar(rString[25], rString[26]);
-        maGuidArray[11] = covertHexChar(rString[27], rString[28]);
-        maGuidArray[12] = covertHexChar(rString[29], rString[30]);
-        maGuidArray[13] = covertHexChar(rString[31], rString[32]);
-        maGuidArray[14] = covertHexChar(rString[33], rString[34]);
-        maGuidArray[15] = covertHexChar(rString[35], rString[36]);
+        maGuidArray[10] = o3tl::convertToHex<sal_uInt8>(rString[25], 
rString[26]);
+        maGuidArray[11] = o3tl::convertToHex<sal_uInt8>(rString[27], 
rString[28]);
+        maGuidArray[12] = o3tl::convertToHex<sal_uInt8>(rString[29], 
rString[30]);
+        maGuidArray[13] = o3tl::convertToHex<sal_uInt8>(rString[31], 
rString[32]);
+        maGuidArray[14] = o3tl::convertToHex<sal_uInt8>(rString[33], 
rString[34]);
+        maGuidArray[15] = o3tl::convertToHex<sal_uInt8>(rString[35], 
rString[36]);
     }
 
 public:
diff --git a/include/tools/inetmime.hxx b/include/tools/inetmime.hxx
index bd0ba36bb1b9..3c8dd90c06b5 100644
--- a/include/tools/inetmime.hxx
+++ b/include/tools/inetmime.hxx
@@ -23,6 +23,7 @@
 #include <rtl/character.hxx>
 #include <rtl/string.hxx>
 #include <rtl/ustring.hxx>
+#include <o3tl/numeric.hxx>
 
 #include <unordered_map>
 
@@ -217,9 +218,7 @@ inline int INetMIME::getWeight(sal_uInt32 nChar)
 // static
 inline int INetMIME::getHexWeight(sal_uInt32 nChar)
 {
-    return rtl::isAsciiDigit(nChar) ? int(nChar - '0') :
-           nChar >= 'A' && nChar <= 'F' ? int(nChar - 'A' + 10) :
-           nChar >= 'a' && nChar <= 'f' ? int(nChar - 'a' + 10) : -1;
+    return o3tl::convertToHex<int>(nChar);
 }
 
 // static
diff --git a/o3tl/CppunitTest_o3tl_tests.mk b/o3tl/CppunitTest_o3tl_tests.mk
index 8e7fbc4d39f9..1715659ffbee 100644
--- a/o3tl/CppunitTest_o3tl_tests.mk
+++ b/o3tl/CppunitTest_o3tl_tests.mk
@@ -31,6 +31,7 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,o3tl_tests,\
        o3tl/qa/test-cow_wrapper \
        o3tl/qa/test-enumarray \
        o3tl/qa/test-lru_map \
+       o3tl/qa/test-numeric \
        o3tl/qa/test-safeint \
        o3tl/qa/test-sorted_vector \
        o3tl/qa/test-string_view \
diff --git a/o3tl/qa/test-numeric.cxx b/o3tl/qa/test-numeric.cxx
new file mode 100644
index 000000000000..005050be01fd
--- /dev/null
+++ b/o3tl/qa/test-numeric.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <o3tl/numeric.hxx>
+#include <sal/types.h>
+#include <sal/config.h>
+
+static_assert(o3tl::convertToHex<int>(' ') == -1);
+static_assert(o3tl::convertToHex<int>('*') == -1);
+static_assert(o3tl::convertToHex<int>('?') == -1);
+static_assert(o3tl::convertToHex<int>('1') == 0x01);
+static_assert(o3tl::convertToHex<int>('9') == 0x09);
+static_assert(o3tl::convertToHex<int>('a') == 0x0a);
+static_assert(o3tl::convertToHex<int>('A') == 0x0A);
+static_assert(o3tl::convertToHex<int>('f') == 0x0f);
+static_assert(o3tl::convertToHex<int>('F') == 0x0f);
+static_assert(o3tl::convertToHex<int>('g') == -1);
+static_assert(o3tl::convertToHex<int>('G') == -1);
+static_assert(o3tl::convertToHex<sal_uInt8>('G') == 0xff);
+
+static_assert(o3tl::convertToHex<int>(u' ') == -1);
+static_assert(o3tl::convertToHex<int>(u'*') == -1);
+static_assert(o3tl::convertToHex<int>(u'?') == -1);
+static_assert(o3tl::convertToHex<int>(u'1') == 0x01);
+static_assert(o3tl::convertToHex<int>(u'9') == 0x09);
+static_assert(o3tl::convertToHex<int>(u'a') == 0x0a);
+static_assert(o3tl::convertToHex<int>(u'A') == 0x0A);
+static_assert(o3tl::convertToHex<int>(u'f') == 0x0f);
+static_assert(o3tl::convertToHex<int>(u'F') == 0x0f);
+static_assert(o3tl::convertToHex<int>(u'g') == -1);
+static_assert(o3tl::convertToHex<int>(u'G') == -1);
+
+static_assert(o3tl::convertToHex<sal_uInt8>(u'*') == 0xff);
+static_assert(o3tl::convertToHex<sal_uInt8>(u'A') == 0x0a);
+static_assert(o3tl::convertToHex<sal_uInt8>(u'G') == 0xff);
+
+static_assert(o3tl::convertToHex<sal_uInt8>('0', '1') == 0x01);
+static_assert(o3tl::convertToHex<sal_uInt8>('0', 'A') == 0x0a);
+static_assert(o3tl::convertToHex<sal_uInt8>('0', 'F') == 0x0f);
+static_assert(o3tl::convertToHex<sal_uInt8>('1', '0') == 0x10);
+static_assert(o3tl::convertToHex<sal_uInt8>('A', '0') == 0xa0);
+static_assert(o3tl::convertToHex<sal_uInt8>('F', '0') == 0xf0);
+
+static_assert(o3tl::convertToHex<sal_uInt8>(u'0', u'1') == 0x01);
+static_assert(o3tl::convertToHex<sal_uInt8>(u'0', u'A') == 0x0a);
+static_assert(o3tl::convertToHex<sal_uInt8>(u'0', u'F') == 0x0f);
+static_assert(o3tl::convertToHex<sal_uInt8>(u'1', u'0') == 0x10);
+static_assert(o3tl::convertToHex<sal_uInt8>(u'A', u'0') == 0xa0);
+static_assert(o3tl::convertToHex<sal_uInt8>(u'F', u'0') == 0xf0);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx
index 995346b0914a..736748be6d6a 100644
--- a/oox/source/dump/dumperbase.cxx
+++ b/oox/source/dump/dumperbase.cxx
@@ -33,6 +33,7 @@
 #include <oox/helper/textinputstream.hxx>
 #include <tools/time.hxx>
 #include <o3tl/string_view.hxx>
+#include <o3tl/numeric.hxx>
 #include <utility>
 
 #ifdef DBG_UTIL
@@ -695,15 +696,10 @@ bool StringHelper::convertFromHex( sal_Int64& ornData, 
std::u16string_view rData
     for( size_t nPos = 0, nLen = rData.size(); nPos < nLen; ++nPos )
     {
         sal_Unicode cChar = rData[ nPos ];
-        if( ('0' <= cChar) && (cChar <= '9') )
-            cChar -= '0';
-        else if( ('A' <= cChar) && (cChar <= 'F') )
-            cChar -= ('A' - 10);
-        else if( ('a' <= cChar) && (cChar <= 'f') )
-            cChar -= ('a' - 10);
-        else
+        sal_Int32 nValue = o3tl::convertToHex<sal_Int32>(cChar);
+        if (nValue == -1)
             return false;
-        ornData = (ornData << 4) + cChar;
+        ornData = (ornData << 4) + nValue;
     }
     return true;
 }
diff --git a/oox/source/ppt/pptfilterhelpers.cxx 
b/oox/source/ppt/pptfilterhelpers.cxx
index 74de14c01c6d..1c01ade57c2e 100644
--- a/oox/source/ppt/pptfilterhelpers.cxx
+++ b/oox/source/ppt/pptfilterhelpers.cxx
@@ -29,20 +29,7 @@
 #include <oox/ppt/pptfilterhelpers.hxx>
 #include <tools/color.hxx>
 #include <o3tl/string_view.hxx>
-
-namespace {
-    int lcl_gethex(int nChar)
-    {
-        if (nChar >= '0' && nChar <= '9')
-            return nChar - '0';
-        else if (nChar >= 'a' && nChar <= 'f')
-            return nChar - 'a' + 10;
-        else if (nChar >= 'A' && nChar <= 'F')
-            return nChar - 'A' + 10;
-        else
-            return 0;
-    }
-}
+#include <o3tl/numeric.hxx>
 
 namespace oox::ppt {
 
@@ -276,12 +263,9 @@ namespace oox::ppt {
                     if (aString.getLength() >= 7 && aString[0] == '#')
                     {
                         Color aColor;
-                        
aColor.SetRed(static_cast<sal_uInt8>(lcl_gethex(aString[1]) * 16
-                                                             + 
lcl_gethex(aString[2])));
-                        
aColor.SetGreen(static_cast<sal_uInt8>(lcl_gethex(aString[3]) * 16
-                                                               + 
lcl_gethex(aString[4])));
-                        
aColor.SetBlue(static_cast<sal_uInt8>(lcl_gethex(aString[5]) * 16
-                                                              + 
lcl_gethex(aString[6])));
+                        
aColor.SetRed(o3tl::convertToHex<sal_uInt8>(aString[1], aString[2]));
+                        
aColor.SetGreen(o3tl::convertToHex<sal_uInt8>(aString[3], aString[4]));
+                        
aColor.SetBlue(o3tl::convertToHex<sal_uInt8>(aString[5], aString[6]));
                         rValue <<= aColor;
                         bRet = true;
                     }
diff --git a/sal/rtl/bootstrap.cxx b/sal/rtl/bootstrap.cxx
index 584d0eaeb4d8..2ca189923108 100644
--- a/sal/rtl/bootstrap.cxx
+++ b/sal/rtl/bootstrap.cxx
@@ -33,6 +33,7 @@
 #include <sal/log.hxx>
 #include <o3tl/lru_map.hxx>
 #include <o3tl/string_view.hxx>
+#include <o3tl/numeric.hxx>
 
 #include <utility>
 #include <vector>
@@ -851,14 +852,6 @@ void rtl_bootstrap_encode(rtl_uString const * value, 
rtl_uString ** encoded)
 
 namespace {
 
-int hex(sal_Unicode c)
-{
-    return
-        c >= '0' && c <= '9' ? c - '0' :
-        c >= 'A' && c <= 'F' ? c - 'A' + 10 :
-        c >= 'a' && c <= 'f' ? c - 'a' + 10 : -1;
-}
-
 sal_Unicode read(std::u16string_view text, std::size_t * pos, bool * escaped)
 {
     assert(pos && *pos < text.length() && escaped);
@@ -867,10 +860,10 @@ sal_Unicode read(std::u16string_view text, std::size_t * 
pos, bool * escaped)
     {
         int n1, n2, n3, n4;
         if (*pos < text.length() - 4 && text[*pos] == 'u' &&
-            ((n1 = hex(text[*pos + 1])) >= 0) &&
-            ((n2 = hex(text[*pos + 2])) >= 0) &&
-            ((n3 = hex(text[*pos + 3])) >= 0) &&
-            ((n4 = hex(text[*pos + 4])) >= 0))
+            ((n1 = o3tl::convertToHex<int>(text[*pos + 1])) >= 0) &&
+            ((n2 = o3tl::convertToHex<int>(text[*pos + 2])) >= 0) &&
+            ((n3 = o3tl::convertToHex<int>(text[*pos + 3])) >= 0) &&
+            ((n4 = o3tl::convertToHex<int>(text[*pos + 4])) >= 0))
         {
             *pos += 5;
             *escaped = true;
diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx
index 61557575350b..c026e35d770a 100644
--- a/sax/source/tools/converter.cxx
+++ b/sax/source/tools/converter.cxx
@@ -33,6 +33,7 @@
 #include <o3tl/string_view.hxx>
 #include <o3tl/typed_flags_set.hxx>
 #include <o3tl/unit_conversion.hxx>
+#include <o3tl/numeric.hxx>
 #include <osl/diagnose.h>
 #include <tools/long.hxx>
 #include <tools/time.hxx>
@@ -628,18 +629,6 @@ void Converter::convertMeasurePx( OUStringBuffer& rBuffer, 
sal_Int32 nValue )
     rBuffer.append( 'x' );
 }
 
-static int lcl_gethex( int nChar )
-{
-    if( nChar >= '0' && nChar <= '9' )
-        return nChar - '0';
-    else if( nChar >= 'a' && nChar <= 'f' )
-        return nChar - 'a' + 10;
-    else if( nChar >= 'A' && nChar <= 'F' )
-        return nChar - 'A' + 10;
-    else
-        return 0;
-}
-
 /** convert string to rgb color */
 template<typename V>
 static bool lcl_convertColor( sal_Int32& rColor, V rValue )
@@ -647,13 +636,13 @@ static bool lcl_convertColor( sal_Int32& rColor, V rValue 
)
     if( rValue.size() != 7 || rValue[0] != '#' )
         return false;
 
-    rColor = lcl_gethex( rValue[1] ) * 16 + lcl_gethex( rValue[2] );
+    rColor = o3tl::convertToHex<sal_Int32>(rValue[1], rValue[2]);
     rColor <<= 8;
 
-    rColor |= lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] );
+    rColor |= o3tl::convertToHex<sal_Int32>(rValue[3], rValue[4]);
     rColor <<= 8;
 
-    rColor |= lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] );
+    rColor |= o3tl::convertToHex<sal_Int32>(rValue[5], rValue[6]);
 
     return true;
 }
diff --git a/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx 
b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
index 03fab8b59e04..ebfadcc4b4c9 100644
--- a/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
+++ b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
@@ -34,6 +34,7 @@
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 #include <o3tl/safeint.hxx>
+#include <o3tl/numeric.hxx>
 
 #include <string_view>
 
@@ -43,19 +44,12 @@ namespace com::sun::star::uri { class XUriReference; }
 
 namespace {
 
-int getHexWeight(sal_Unicode c) {
-    return c >= '0' && c <= '9' ? static_cast< int >(c - '0')
-        : c >= 'A' && c <= 'F' ? static_cast< int >(c - 'A' + 10)
-        : c >= 'a' && c <= 'f' ? static_cast< int >(c - 'a' + 10)
-        : -1;
-}
-
 int parseEscaped(std::u16string_view part, sal_Int32 * index) {
     if (part.size() - *index < 3 || part[*index] != '%') {
         return -1;
     }
-    int n1 = getHexWeight(part[*index + 1]);
-    int n2 = getHexWeight(part[*index + 2]);
+    int n1 = o3tl::convertToHex<int>(part[*index + 1]);
+    int n2 = o3tl::convertToHex<int>(part[*index + 2]);
     if (n1 < 0 || n2 < 0) {
         return -1;
     }
diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx
index 6945c420a2b8..c1f18f647962 100644
--- a/svl/source/crypto/cryptosign.cxx
+++ b/svl/source/crypto/cryptosign.cxx
@@ -14,6 +14,7 @@
 #include <svl/cryptosign.hxx>
 #include <svl/sigstruct.hxx>
 #include <config_crypto.h>
+#include <o3tl/numeric.hxx>
 
 #if USE_CRYPTO_NSS
 #include <systools/curlinit.hxx>
@@ -884,24 +885,6 @@ bool CreateSigningCertificateAttribute(void const * 
pDerEncoded, int nDerEncoded
 
 namespace svl::crypto {
 
-static int AsHex(char ch)
-{
-    int nRet = 0;
-    if (rtl::isAsciiDigit(static_cast<unsigned char>(ch)))
-        nRet = ch - '0';
-    else
-    {
-        if (ch >= 'a' && ch <= 'f')
-            nRet = ch - 'a';
-        else if (ch >= 'A' && ch <= 'F')
-            nRet = ch - 'A';
-        else
-            return -1;
-        nRet += 10;
-    }
-    return nRet;
-}
-
 std::vector<unsigned char> DecodeHexString(std::string_view rHex)
 {
     std::vector<unsigned char> aRet;
@@ -912,7 +895,7 @@ std::vector<unsigned char> DecodeHexString(std::string_view 
rHex)
         for (size_t i = 0; i < nHexLen; ++i)
         {
             nByte = nByte << 4;
-            sal_Int8 nParsed = AsHex(rHex[i]);
+            sal_Int8 nParsed = o3tl::convertToHex<int>(rHex[i]);
             if (nParsed == -1)
             {
                 SAL_WARN("svl.crypto", "DecodeHexString: invalid hex value");
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index eda77fc62859..d72d7202dfe0 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -21,6 +21,7 @@
 
 #include <o3tl/sprintf.hxx>
 #include <o3tl/string_view.hxx>
+#include <o3tl/numeric.hxx>
 #include <comphelper/string.hxx>
 #include <sal/log.hxx>
 #include <tools/debug.hxx>
@@ -1610,25 +1611,15 @@ SvNumberformat::LocaleType 
SvNumberformat::ImpGetLocaleType(std::u16string_view
         cToken = rString[nPos];
         if (cToken == ']')
             break;
-        if ( '0' <= cToken && cToken <= '9' )
-        {
-            nNum *= 16;
-            nNum += cToken - '0';
-        }
-        else if ( 'a' <= cToken && cToken <= 'f' )
-        {
-            nNum *= 16;
-            nNum += cToken - 'a' + 10;
-        }
-        else if ( 'A' <= cToken && cToken <= 'F' )
-        {
-            nNum *= 16;
-            nNum += cToken - 'A' + 10;
-        }
-        else
-        {
+
+        int nValue = o3tl::convertToHex<int>(cToken);
+
+        if (nValue == -1)
             return LocaleType(); // LANGUAGE_DONTKNOW;
-        }
+
+        nNum *= 16;
+        nNum += nValue;
+
         ++nPos;
     }
 
diff --git a/sw/qa/extras/htmlexport/htmlmodeltestbase.hxx 
b/sw/qa/extras/htmlexport/htmlmodeltestbase.hxx
index c3fc357118d8..9e563add4012 100644
--- a/sw/qa/extras/htmlexport/htmlmodeltestbase.hxx
+++ b/sw/qa/extras/htmlexport/htmlmodeltestbase.hxx
@@ -12,6 +12,7 @@
 
 #include <comphelper/propertyvalue.hxx>
 #include <filter/msfilter/rtfutil.hxx>
+#include <o3tl/numeric.hxx>
 #include <svtools/parrtf.hxx>
 #include <svtools/rtftoken.h>
 #include <tools/urlobj.hxx>
@@ -81,7 +82,7 @@ bool TestReqIfRtfReader::WriteObjectData(SvStream& rOLE)
         if (ch != 0x0d && ch != 0x0a)
         {
             b = b << 4;
-            sal_Int8 parsed = msfilter::rtfutil::AsHex(ch);
+            sal_Int8 parsed = o3tl::convertToHex<sal_Int8>(ch);
             if (parsed == -1)
                 return false;
             b += parsed;
diff --git a/sw/source/uibase/config/modcfg.cxx 
b/sw/source/uibase/config/modcfg.cxx
index 0eb74b0a0688..a468aa69ad83 100644
--- a/sw/source/uibase/config/modcfg.cxx
+++ b/sw/source/uibase/config/modcfg.cxx
@@ -20,6 +20,7 @@
 #include <memory>
 #include <comphelper/classids.hxx>
 #include <o3tl/any.hxx>
+#include <o3tl/numeric.hxx>
 #include <tools/fontenum.hxx>
 #include <editeng/svxenum.hxx>
 #include <editeng/editids.hrc>
@@ -155,21 +156,15 @@ OUString 
SwModuleOptions::ConvertWordDelimiter(std::u16string_view aDelim, bool
                         for( sal_Int32 n = 0; n < 2 && i < nDelimLen; ++n, ++i 
)
                         {
                             sal_Unicode nVal = aDelim[i];
-                            if( (nVal >= '0') && ( nVal <= '9') )
-                                nVal -= '0';
-                            else if( (nVal >= 'A') && (nVal <= 'F') )
-                                nVal -= 'A' - 10;
-                            else if( (nVal >= 'a') && (nVal <= 'f') )
-                                nVal -= 'a' - 10;
-                            else
+                            int nConverted = o3tl::convertToHex<int>(nVal);
+                            if (nConverted == -1)
                             {
                                 OSL_FAIL("wrong hex value" );
                                 bValidData = false;
                                 break;
                             }
-
                             nChar <<= 4;
-                            nChar += nVal;
+                            nChar += nConverted;
                         }
                         if( bValidData )
                             sReturn.append(nChar);
diff --git a/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx 
b/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
index ce391551c719..ce5b87f4f20c 100644
--- a/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
+++ b/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
@@ -28,6 +28,7 @@
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <filter/msfilter/util.hxx>
 #include <filter/msfilter/rtfutil.hxx>
+#include <o3tl/numeric.hxx>
 #include <comphelper/string.hxx>
 #include <comphelper/diagnose_ex.hxx>
 #include <tools/globname.hxx>
@@ -891,7 +892,7 @@ void RTFDocumentImpl::resolvePict(bool const bInline, 
uno::Reference<drawing::XS
             if (ch != 0x0d && ch != 0x0a && ch != 0x20)
             {
                 b = b << 4;
-                sal_Int8 parsed = msfilter::rtfutil::AsHex(ch);
+                sal_Int8 parsed = o3tl::convertToHex<sal_Int8>(ch);
                 if (parsed == -1)
                     return;
                 b += parsed;
@@ -2640,7 +2641,7 @@ RTFError RTFDocumentImpl::beforePopState(RTFParserState& 
rState)
                     if (ch != 0x0d && ch != 0x0a)
                     {
                         b = b << 4;
-                        sal_Int8 parsed = msfilter::rtfutil::AsHex(ch);
+                        sal_Int8 parsed = o3tl::convertToHex<sal_Int8>(ch);
                         if (parsed == -1)
                             return RTFError::HEX_INVALID;
                         b += parsed;
diff --git a/sw/source/writerfilter/rtftok/rtftokenizer.cxx 
b/sw/source/writerfilter/rtftok/rtftokenizer.cxx
index 994f5d73e735..0f3829e7dd95 100644
--- a/sw/source/writerfilter/rtftok/rtftokenizer.cxx
+++ b/sw/source/writerfilter/rtftok/rtftokenizer.cxx
@@ -9,6 +9,7 @@
 
 #include "rtftokenizer.hxx"
 #include <o3tl/string_view.hxx>
+#include <o3tl/numeric.hxx>
 #include <oox/token/namespaces.hxx>
 #include <tools/stream.hxx>
 #include <svx/dialmgr.hxx>
@@ -2046,7 +2047,7 @@ RTFError RTFTokenizer::resolveParse()
                             || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 
'F'))
                         {
                             b = b << 4;
-                            sal_Int8 parsed = msfilter::rtfutil::AsHex(ch);
+                            sal_Int8 parsed = o3tl::convertToHex<sal_Int8>(ch);
                             if (parsed == -1)
                                 return RTFError::HEX_INVALID;
                             b += parsed;
diff --git a/vcl/qa/cppunit/pdfexport/PDFEncryptionTest.cxx 
b/vcl/qa/cppunit/pdfexport/PDFEncryptionTest.cxx
index 6c27b7e4d2c1..1ef7e156ccd5 100644
--- a/vcl/qa/cppunit/pdfexport/PDFEncryptionTest.cxx
+++ b/vcl/qa/cppunit/pdfexport/PDFEncryptionTest.cxx
@@ -12,6 +12,7 @@
 
 #include <test/unoapi_test.hxx>
 #include <o3tl/string_view.hxx>
+#include <o3tl/numeric.hxx>
 
 #include <unotools/mediadescriptor.hxx>
 #include <comphelper/crypto/Crypto.hxx>
@@ -59,29 +60,13 @@ public:
     }
 };
 
-// TODO: taken from GUID
-sal_uInt8 gethex(char nChar)
-{
-    if (nChar >= '0' && nChar <= '9')
-        return nChar - '0';
-    else if (nChar >= 'a' && nChar <= 'f')
-        return nChar - 'a' + 10;
-    else if (nChar >= 'A' && nChar <= 'F')
-        return nChar - 'A' + 10;
-    else
-        return 0;
-}
-
-// TODO: taken from GUID
-sal_uInt8 convertHexChar(char high, char low) { return (gethex(high) << 4) + 
gethex(low); }
-
 std::vector<sal_uInt8> parseHex(std::string_view rString)
 {
     std::vector<sal_uInt8> aResult;
     aResult.reserve(rString.size() / 2);
     for (size_t i = 0; i < rString.size(); i += 2)
     {
-        aResult.push_back(convertHexChar(rString[i], rString[i + 1]));
+        aResult.push_back(o3tl::convertToHex<sal_Int32>(rString[i], rString[i 
+ 1]));
     }
     return aResult;
 }
diff --git a/vcl/source/gdi/WidgetDefinitionReader.cxx 
b/vcl/source/gdi/WidgetDefinitionReader.cxx
index 428cbad77838..8e80ab785f46 100644
--- a/vcl/source/gdi/WidgetDefinitionReader.cxx
+++ b/vcl/source/gdi/WidgetDefinitionReader.cxx
@@ -15,6 +15,7 @@
 #include <osl/file.hxx>
 #include <tools/stream.hxx>
 #include <o3tl/string_view.hxx>
+#include <o3tl/numeric.hxx>
 #include <unordered_map>
 
 namespace vcl
@@ -28,18 +29,6 @@ bool lcl_fileExists(OUString const& sFilename)
     return osl::FileBase::E_None == eRC;
 }
 
-int lcl_gethex(char aChar)
-{
-    if (aChar >= '0' && aChar <= '9')
-        return aChar - '0';
-    else if (aChar >= 'a' && aChar <= 'f')
-        return aChar - 'a' + 10;
-    else if (aChar >= 'A' && aChar <= 'F')
-        return aChar - 'A' + 10;
-    else
-        return 0;
-}
-
 bool readColor(OString const& rString, Color& rColor)
 {
     if (rString.getLength() != 7)
@@ -50,9 +39,9 @@ bool readColor(OString const& rString, Color& rColor)
     if (aChar != '#')
         return false;
 
-    rColor.SetRed((lcl_gethex(rString[1]) << 4) | lcl_gethex(rString[2]));
-    rColor.SetGreen((lcl_gethex(rString[3]) << 4) | lcl_gethex(rString[4]));
-    rColor.SetBlue((lcl_gethex(rString[5]) << 4) | lcl_gethex(rString[6]));
+    rColor.SetRed(o3tl::convertToHex<sal_Int32>(rString[1], rString[2]));
+    rColor.SetGreen(o3tl::convertToHex<sal_Int32>(rString[3], rString[4]));
+    rColor.SetBlue(o3tl::convertToHex<sal_Int32>(rString[5], rString[6]));
 
     return true;
 }
diff --git a/xmloff/source/core/xmluconv.cxx b/xmloff/source/core/xmluconv.cxx
index a99ddff236ef..abeb2c610bae 100644
--- a/xmloff/source/core/xmluconv.cxx
+++ b/xmloff/source/core/xmluconv.cxx
@@ -32,6 +32,7 @@
 #include <xmloff/xmlement.hxx>
 #include <xmloff/xmltoken.hxx>
 #include <rtl/math.hxx>
+#include <o3tl/numeric.hxx>
 
 #include <tools/date.hxx>
 #include <tools/time.hxx>
@@ -314,18 +315,6 @@ bool SvXMLUnitConverter::convertEnumImpl(
     return (eTok != XML_TOKEN_INVALID);
 }
 
-static int lcl_gethex( int nChar )
-{
-    if( nChar >= '0' && nChar <= '9' )
-        return nChar - '0';
-    else if( nChar >= 'a' && nChar <= 'f' )
-        return nChar - 'a' + 10;
-    else if( nChar >= 'A' && nChar <= 'F' )
-        return nChar - 'A' + 10;
-    else
-        return 0;
-}
-
 const char aHexTab[] = "0123456789abcdef";
 
 
@@ -950,8 +939,7 @@ bool SvXMLUnitConverter::convertHex( sal_uInt32& nVal, 
std::u16string_view rValu
     nVal = 0;
     for ( int i = 0; i < 8; i++ )
     {
-        nVal = ( nVal << 4 )
-            | sal::static_int_cast< sal_uInt32 >( lcl_gethex( rValue[i] ) );
+        nVal = ( nVal << 4 ) | o3tl::convertToHex<sal_uInt32>(rValue[i]);
     }
 
     return true;
diff --git a/xmloff/source/transform/TransformerBase.cxx 
b/xmloff/source/transform/TransformerBase.cxx
index 7c2d0807a3c2..bc61f989a684 100644
--- a/xmloff/source/transform/TransformerBase.cxx
+++ b/xmloff/source/transform/TransformerBase.cxx
@@ -21,6 +21,7 @@
 #include <rtl/ustrbuf.hxx>
 #include <tools/UnitConversion.hxx>
 #include <osl/diagnose.h>
+#include <o3tl/numeric.hxx>
 #include <com/sun/star/i18n/CharacterClassification.hpp>
 #include <com/sun/star/i18n/UnicodeType.hpp>
 #include <com/sun/star/util/MeasureUnit.hpp>
@@ -1090,26 +1091,14 @@ bool XMLTransformerBase::DecodeStyleName( OUString& 
rName )
         }
         else if( bWithinHex )
         {
-            sal_Unicode cDigit;
-            if( c >= '0' && c <= '9' )
-            {
-                cDigit = c - '0';
-            }
-            else if( c >= 'a' && c <= 'f' )
-            {
-                cDigit = c - 'a' + 10;
-            }
-            else if( c >= 'A' && c <= 'F' )
-            {
-                cDigit = c - 'A' + 10;
-            }
-            else
+            int nValue = o3tl::convertToHex<int>(c);
+            if (nValue == -1)
             {
                 // error
                 bEncoded = false;
                 break;
             }
-            cEnc = (cEnc << 4) + cDigit;
+            cEnc = (cEnc << 4) + nValue;
         }
         else
         {
diff --git a/xmlreader/source/xmlreader.cxx b/xmlreader/source/xmlreader.cxx
index 00489caa4987..ac4f9ad3b325 100644
--- a/xmlreader/source/xmlreader.cxx
+++ b/xmlreader/source/xmlreader.cxx
@@ -24,6 +24,7 @@
 
 #include <com/sun/star/container/NoSuchElementException.hpp>
 #include <com/sun/star/uno/RuntimeException.hpp>
+#include <o3tl/numeric.hxx>
 #include <osl/file.h>
 #include <rtl/character.hxx>
 #include <rtl/string.h>
@@ -388,17 +389,12 @@ char const * XmlReader::handleReference(char const * 
position, char const * end)
         if (*position == 'x') {
             ++position;
             p = position;
-            for (;; ++position) {
-                char c = *position;
-                if (c >= '0' && c <= '9') {
-                    val = 16 * val + (c - '0');
-                } else if (c >= 'A' && c <= 'F') {
-                    val = 16 * val + (c - 'A') + 10;
-                } else if (c >= 'a' && c <= 'f') {
-                    val = 16 * val + (c - 'a') + 10;
-                } else {
+            for (;; ++position)
+            {
+                val = o3tl::convertToHex<sal_uInt32>(*position);
+                if (val >= 16)
                     break;
-                }
+
                 if (!rtl::isUnicodeCodePoint(val)) { // avoid overflow
                     throw css::uno::RuntimeException(
                         "'&#x...' too large in " + fileUrl_ );

Reply via email to