include/o3tl/numeric.hxx | 8 +- sax/source/tools/fastserializer.cxx | 2 scripting/source/stringresource/stringresource.cxx | 21 +------ sdext/source/pdfimport/pdfparse/pdfentries.cxx | 19 +------ svgio/inc/svgtools.hxx | 1 svgio/source/svgreader/svgtools.cxx | 57 ++++----------------- svtools/source/svhtml/parhtml.cxx | 8 +- svtools/source/svrtf/parrtf.cxx | 20 +------ sw/source/filter/html/parcss1.cxx | 29 ++-------- vcl/source/filter/idxf/dxfreprd.cxx | 26 ++------- 10 files changed, 49 insertions(+), 142 deletions(-)
New commits: commit e18a815190140dd959ade58abf1b9311af10057e Author: Mike Kaganski <[email protected]> AuthorDate: Sat Feb 14 14:30:23 2026 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Sat Feb 14 11:40:50 2026 +0100 Use rtl::isAscii(Hex)Digit and o3tl::convertToHex Since some code needs flexibility in error handling, where hardcoded error value of -1 wasn't handy, o3tl::convertToHex was changed to accept the error value as its template parameter. Change-Id: Ifc771cc8fa29a801d4556dea969fc3ea7e620df5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199367 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins diff --git a/include/o3tl/numeric.hxx b/include/o3tl/numeric.hxx index 3736d60b60d1..87da173329a4 100644 --- a/include/o3tl/numeric.hxx +++ b/include/o3tl/numeric.hxx @@ -23,7 +23,7 @@ struct divide_by_zero final : public std::runtime_error } }; -template <o3tl::integral T, o3tl::integral U> +template <o3tl::integral T, T error = T(-1), o3tl::integral U> constexpr T convertToHex(U aChar) { if (aChar >= '0' && aChar <= '9') @@ -32,13 +32,13 @@ constexpr T convertToHex(U aChar) return T(aChar - 'a' + 10); else if (aChar >= 'A' && aChar <= 'F') return T(aChar - 'A' + 10); - return T(-1); + return error; } -template <o3tl::integral T, o3tl::integral U> +template <o3tl::integral T, T error = T(-1), o3tl::integral U> constexpr T convertToHex(U cHigh, U cLow) { - return (o3tl::convertToHex<T>(cHigh) << 4) | o3tl::convertToHex<T>(cLow); + return (o3tl::convertToHex<T, error>(cHigh) << 4) | o3tl::convertToHex<T, error>(cLow); } template <o3tl::integral T> diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx index dcd170aece6d..54039859539a 100644 --- a/sax/source/tools/fastserializer.cxx +++ b/sax/source/tools/fastserializer.cxx @@ -135,7 +135,7 @@ namespace sax_fastparser { static bool isHexDigit( char c ) { - return ('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'); + return rtl::isAsciiHexDigit(static_cast<unsigned char>(c)); } void FastSaxSerializer::write( const char* pStr, sal_Int32 nLen, bool bEscape ) diff --git a/scripting/source/stringresource/stringresource.cxx b/scripting/source/stringresource/stringresource.cxx index ec304ffc1d0b..a403f59c1b6d 100644 --- a/scripting/source/stringresource/stringresource.cxx +++ b/scripting/source/stringresource/stringresource.cxx @@ -33,6 +33,7 @@ #include <com/sun/star/ucb/SimpleFileAccess.hpp> #include <osl/diagnose.h> +#include <o3tl/numeric.hxx> #include <o3tl/string_view.hxx> #include <rtl/ref.hxx> #include <rtl/tencinfo.h> @@ -1635,20 +1636,6 @@ static void skipWhites( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri ) } } -static bool isHexDigit( sal_Unicode c, sal_uInt16& nDigitVal ) -{ - bool bRet = true; - if( c >= '0' && c <= '9' ) - nDigitVal = c - '0'; - else if( c >= 'a' && c <= 'f' ) - nDigitVal = c - 'a' + 10; - else if( c >= 'A' && c <= 'F' ) - nDigitVal = c - 'A' + 10; - else - bRet = false; - return bRet; -} - static sal_Unicode getEscapeChar( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri ) { sal_Int32 i = ri; @@ -1681,9 +1668,11 @@ static sal_Unicode getEscapeChar( const sal_Unicode* pBuf, sal_Int32 nLen, sal_I // Process hex digits sal_Int32 nDigitCount = 0; - sal_uInt16 nDigitVal; - while( i < nLen && isHexDigit( pBuf[i], nDigitVal ) ) + while (i < nLen) { + int nDigitVal = o3tl::convertToHex<int>(pBuf[i]); + if (nDigitVal < 0) + break; cRet = 16 * cRet + nDigitVal; nDigitCount++; diff --git a/sdext/source/pdfimport/pdfparse/pdfentries.cxx b/sdext/source/pdfimport/pdfparse/pdfentries.cxx index 6f781149c3e8..d000a18dcea3 100644 --- a/sdext/source/pdfimport/pdfparse/pdfentries.cxx +++ b/sdext/source/pdfimport/pdfparse/pdfentries.cxx @@ -22,6 +22,7 @@ #include <comphelper/hash.hxx> +#include <o3tl/numeric.hxx> #include <rtl/strbuf.hxx> #include <rtl/ustring.hxx> #include <rtl/ustrbuf.hxx> @@ -163,22 +164,8 @@ OUString PDFName::getFilteredName() const { if( (i < nLen - 3) && pStr[i] == '#' ) { - char rResult = 0; - i++; - if( pStr[i] >= '0' && pStr[i] <= '9' ) - rResult = char( pStr[i]-'0' ) << 4; - else if( pStr[i] >= 'a' && pStr[i] <= 'f' ) - rResult = char( pStr[i]-'a' + 10 ) << 4; - else if( pStr[i] >= 'A' && pStr[i] <= 'F' ) - rResult = char( pStr[i]-'A' + 10 ) << 4; - i++; - if( pStr[i] >= '0' && pStr[i] <= '9' ) - rResult |= char( pStr[i]-'0' ); - else if( pStr[i] >= 'a' && pStr[i] <= 'f' ) - rResult |= char( pStr[i]-'a' + 10 ); - else if( pStr[i] >= 'A' && pStr[i] <= 'F' ) - rResult |= char( pStr[i]-'A' + 10 ); - aFilter.append( rResult ); + aFilter.append(o3tl::convertToHex<char, 0>(pStr[i + 1], pStr[i + 2])); + i += 2; } else aFilter.append( pStr[i] ); diff --git a/svgio/inc/svgtools.hxx b/svgio/inc/svgtools.hxx index dfeb12d9ea49..7bcea2ccedf1 100644 --- a/svgio/inc/svgtools.hxx +++ b/svgio/inc/svgtools.hxx @@ -105,7 +105,6 @@ namespace svgio::svgreader SvgUnit readUnit(std::u16string_view rCandidate, sal_Int32& nPos, const sal_Int32 nLen); bool readNumberAndUnit(std::u16string_view rCandidate, sal_Int32& nPos, SvgNumber& aNum, const sal_Int32 nLen); bool readAngle(std::u16string_view rCandidate, sal_Int32& nPos, double& fAngle, const sal_Int32 nLen); - sal_Int32 read_hex(sal_Unicode aChar); bool match_colorKeyword(basegfx::BColor& rColor, const OUString& rName); bool read_color(const OUString& rCandidate, basegfx::BColor& rColor, SvgNumber& rOpacity); basegfx::B2DRange readViewBox(std::u16string_view rCandidate, InfoProvider const & rInfoProvider); diff --git a/svgio/source/svgreader/svgtools.cxx b/svgio/source/svgreader/svgtools.cxx index 11b6aa74db0d..f6078bf49010 100644 --- a/svgio/source/svgreader/svgtools.cxx +++ b/svgio/source/svgreader/svgtools.cxx @@ -20,7 +20,9 @@ #include <svgtools.hxx> #include <sal/log.hxx> #include <tools/color.hxx> +#include <rtl/character.hxx> #include <rtl/math.hxx> +#include <o3tl/numeric.hxx> #include <o3tl/string_view.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> @@ -340,21 +342,9 @@ namespace svgio::svgreader void copyHex(std::u16string_view rCandidate, sal_Int32& nPos, OUStringBuffer& rTarget, const sal_Int32 nLen) { - bool bOnHex(true); - - while(bOnHex && nPos < nLen) + for (; nPos < nLen && rtl::isAsciiHexDigit(rCandidate[nPos]); ++nPos) { - const sal_Unicode aChar(rCandidate[nPos]); - - bOnHex = ('0' <= aChar && '9' >= aChar) - || ('A' <= aChar && 'F' >= aChar) - || ('a' <= aChar && 'f' >= aChar); - - if(bOnHex) - { - rTarget.append(aChar); - nPos++; - } + rTarget.append(rCandidate[nPos]); } } @@ -617,27 +607,6 @@ namespace svgio::svgreader return false; } - sal_Int32 read_hex(sal_Unicode nChar) - { - if(nChar >= '0' && nChar <= '9') - { - return nChar - u'0'; - } - else if(nChar >= 'A' && nChar <= 'F') - { - return 10 + sal_Int32(nChar - u'A'); - } - else if(nChar >= 'a' && nChar <= 'f') - { - return 10 + sal_Int32(nChar - u'a'); - } - else - { - // error - return 0; - } - } - bool match_colorKeyword(basegfx::BColor& rColor, const OUString& rName) { auto const aResult = aColorTokenMapperList.find(rName.toAsciiLowerCase().trim()); @@ -673,9 +642,9 @@ namespace svgio::svgreader if(3 == nLength) { - const sal_Int32 nR(read_hex(aNum[0])); - const sal_Int32 nG(read_hex(aNum[1])); - const sal_Int32 nB(read_hex(aNum[2])); + const sal_Int32 nR(o3tl::convertToHex<sal_Int32, 0>(aNum[0])); + const sal_Int32 nG(o3tl::convertToHex<sal_Int32, 0>(aNum[1])); + const sal_Int32 nB(o3tl::convertToHex<sal_Int32, 0>(aNum[2])); rColor.setRed((nR | (nR << 4)) * fFactor); rColor.setGreen((nG | (nG << 4)) * fFactor); @@ -685,12 +654,12 @@ namespace svgio::svgreader } else if(6 == nLength) { - const sal_Int32 nR1(read_hex(aNum[0])); - const sal_Int32 nR2(read_hex(aNum[1])); - const sal_Int32 nG1(read_hex(aNum[2])); - const sal_Int32 nG2(read_hex(aNum[3])); - const sal_Int32 nB1(read_hex(aNum[4])); - const sal_Int32 nB2(read_hex(aNum[5])); + const sal_Int32 nR1(o3tl::convertToHex<sal_Int32, 0>(aNum[0])); + const sal_Int32 nR2(o3tl::convertToHex<sal_Int32, 0>(aNum[1])); + const sal_Int32 nG1(o3tl::convertToHex<sal_Int32, 0>(aNum[2])); + const sal_Int32 nG2(o3tl::convertToHex<sal_Int32, 0>(aNum[3])); + const sal_Int32 nB1(o3tl::convertToHex<sal_Int32, 0>(aNum[4])); + const sal_Int32 nB2(o3tl::convertToHex<sal_Int32, 0>(aNum[5])); rColor.setRed((nR2 | (nR1 << 4)) * fFactor); rColor.setGreen((nG2 | (nG1 << 4)) * fFactor); diff --git a/svtools/source/svhtml/parhtml.cxx b/svtools/source/svhtml/parhtml.cxx index 0356d7c1a645..fb1a84b13ee4 100644 --- a/svtools/source/svhtml/parhtml.cxx +++ b/svtools/source/svhtml/parhtml.cxx @@ -18,6 +18,7 @@ */ #include <comphelper/string.hxx> +#include <o3tl/numeric.hxx> #include <o3tl/safeint.hxx> #include <o3tl/string_view.hxx> #include <tools/stream.hxx> @@ -163,7 +164,7 @@ void HTMLOption::GetColor( Color& rColor ) const DBG_ASSERT( (nToken>=HtmlOptionId::COLOR_START && nToken<HtmlOptionId::COLOR_END) || nToken==HtmlOptionId::SIZE, "GetColor: Option is not a color." ); - OUString aTmp(aValue.toAsciiLowerCase()); + OUString aTmp(aValue); sal_uInt32 nColor = SAL_MAX_UINT32; if (!aTmp.isEmpty() && aTmp[0] != '#') nColor = GetHTMLColor(aTmp); @@ -184,10 +185,7 @@ void HTMLOption::GetColor( Color& rColor ) const c = nPos<aTmp.getLength() ? aTmp[nPos++] : '0'; } nColor *= 16; - if( c >= '0' && c <= '9' ) - nColor += (c - '0'); - else if( c >= 'a' && c <= 'f' ) - nColor += (c + 0xa - 'a'); + nColor += o3tl::convertToHex<sal_uInt32, 0>(c); } } diff --git a/svtools/source/svrtf/parrtf.cxx b/svtools/source/svrtf/parrtf.cxx index 82d69f7881ac..a7a9a1bbc01c 100644 --- a/svtools/source/svrtf/parrtf.cxx +++ b/svtools/source/svrtf/parrtf.cxx @@ -22,6 +22,7 @@ #include <comphelper/scopeguard.hxx> +#include <o3tl/numeric.hxx> #include <rtl/character.hxx> #include <rtl/strbuf.hxx> #include <rtl/tencinfo.h> @@ -295,21 +296,10 @@ int SvRTFParser::GetNextToken_() sal_Unicode SvRTFParser::GetHexValue() { // collect Hex values - int n; - sal_Unicode nHexVal = 0; - - for( n = 0; n < 2; ++n ) - { - nHexVal *= 16; - nNextCh = GetNextChar(); - if( nNextCh >= '0' && nNextCh <= '9' ) - nHexVal += (nNextCh - 48); - else if( nNextCh >= 'a' && nNextCh <= 'f' ) - nHexVal += (nNextCh - 87); - else if( nNextCh >= 'A' && nNextCh <= 'F' ) - nHexVal += (nNextCh - 55); - } - return nHexVal; + sal_uInt32 nHi = GetNextChar(); + sal_uInt32 nLo = GetNextChar(); + nNextCh = nLo; + return o3tl::convertToHex<sal_Unicode, 0>(nHi, nLo); } void SvRTFParser::ScanText() diff --git a/sw/source/filter/html/parcss1.cxx b/sw/source/filter/html/parcss1.cxx index a32de72ab52f..6c6ec66c9025 100644 --- a/sw/source/filter/html/parcss1.cxx +++ b/sw/source/filter/html/parcss1.cxx @@ -17,6 +17,9 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + +#include <o3tl/numeric.hxx> #include <o3tl/string_view.hxx> #include <o3tl/unit_conversion.hxx> #include <osl/diagnose.h> @@ -311,11 +314,7 @@ CSS1Token CSS1Parser::GetNextToken() do { sTmpBuffer.append( m_cNextCh ); m_cNextCh = GetNextChar(); - } while( sTmpBuffer.getLength() < 7 && - ( ('0'<=m_cNextCh && '9'>=m_cNextCh) || - ('A'<=m_cNextCh && 'F'>=m_cNextCh) || - ('a'<=m_cNextCh && 'f'>=m_cNextCh) ) && - !IsEOF() ); + } while (sTmpBuffer.getLength() < 7 && rtl::isAsciiHexDigit(m_cNextCh) && !IsEOF()); if( sTmpBuffer.getLength()==6 ) { @@ -510,11 +509,7 @@ CSS1Token CSS1Parser::GetNextToken() do { sTmpBuffer.append( m_cNextCh ); m_cNextCh = GetNextChar(); - } while( sTmpBuffer.getLength() < 9 && - ( ('0'<=m_cNextCh && '9'>=m_cNextCh) || - ('A'<=m_cNextCh && 'F'>=m_cNextCh) || - ('a'<=m_cNextCh && 'f'>=m_cNextCh) ) && - !IsEOF() ); + } while (sTmpBuffer.getLength() < 9 && rtl::isAsciiHexDigit(m_cNextCh) && !IsEOF()); if( sTmpBuffer.getLength()==6 || sTmpBuffer.getLength()==3 ) { @@ -587,10 +582,7 @@ CSS1Token CSS1Parser::GetNextToken() sTmpBuffer.append( m_cNextCh ); if( bHexColor ) { - bHexColor = sTmpBuffer.getLength()<7 && - ( ('0'<=m_cNextCh && '9'>=m_cNextCh) || - ('A'<=m_cNextCh && 'F'>=m_cNextCh) || - ('a'<=m_cNextCh && 'f'>=m_cNextCh) ); + bHexColor = sTmpBuffer.getLength() < 7 && rtl::isAsciiHexDigit(m_cNextCh); } m_cNextCh = GetNextChar(); } while( (rtl::isAsciiAlphanumeric(m_cNextCh) || @@ -1325,14 +1317,7 @@ bool CSS1Expression::GetColor( Color &rColor ) const { sal_Unicode c = (i<aValue.getLength() ? aValue[i] : '0' ); - if( c >= '0' && c <= '9' ) - c -= 48; - else if( c >= 'A' && c <= 'F' ) - c -= 55; - else if( c >= 'a' && c <= 'f' ) - c -= 87; - else - c = 16; + c = o3tl::convertToHex<sal_Unicode, 16>(c); nColor *= 16; if( c<16 ) diff --git a/vcl/source/filter/idxf/dxfreprd.cxx b/vcl/source/filter/idxf/dxfreprd.cxx index 7124e296e303..f2d61bedadef 100644 --- a/vcl/source/filter/idxf/dxfreprd.cxx +++ b/vcl/source/filter/idxf/dxfreprd.cxx @@ -23,6 +23,7 @@ #include "dxfreprd.hxx" #include <osl/nlsupport.h> +#include <rtl/character.hxx> #include <unotools/defaultencoding.hxx> #include <unotools/wincodepage.hxx> @@ -423,17 +424,6 @@ void DXFRepresentation::CalcBoundingBox(const DXFEntities & rEntities, mbInCalc = false; } -namespace { - bool lcl_isDec(sal_Unicode ch) - { - return ch >= L'0' && ch <= L'9'; - } - bool lcl_isHex(sal_Unicode ch) - { - return lcl_isDec(ch) || (ch >= L'A' && ch <= L'F') || (ch >= L'a' && ch <= L'f'); - } -} - OUString DXFRepresentation::ToOUString(std::string_view s) const { OUString result = OStringToOUString(s, getTextEncoding(), @@ -450,9 +440,9 @@ OUString DXFRepresentation::ToOUString(std::string_view s) const sal_Int32 pos = result.indexOf("%%"); // %%nnn, where nnn - 3-digit decimal ASCII code while (pos != -1 && pos <= result.getLength() - 5) { OUString asciiNum = result.copy(pos + 2, 3); - if (lcl_isDec(asciiNum[0]) && - lcl_isDec(asciiNum[1]) && - lcl_isDec(asciiNum[2])) + if (rtl::isAsciiDigit(asciiNum[0]) && + rtl::isAsciiDigit(asciiNum[1]) && + rtl::isAsciiDigit(asciiNum[2])) { char ch = static_cast<char>(asciiNum.toUInt32()); OUString codePt(&ch, 1, mEnc); @@ -464,10 +454,10 @@ OUString DXFRepresentation::ToOUString(std::string_view s) const pos = result.indexOf("\U+"); // \U+XXXX, where XXXX - 4-digit hex unicode while (pos != -1 && pos <= result.getLength() - 7) { OUString codePtNum = result.copy(pos + 3, 4); - if (lcl_isHex(codePtNum[0]) && - lcl_isHex(codePtNum[1]) && - lcl_isHex(codePtNum[2]) && - lcl_isHex(codePtNum[3])) + if (rtl::isAsciiHexDigit(codePtNum[0]) && + rtl::isAsciiHexDigit(codePtNum[1]) && + rtl::isAsciiHexDigit(codePtNum[2]) && + rtl::isAsciiHexDigit(codePtNum[3])) { OUString codePt(static_cast<sal_Unicode>(codePtNum.toUInt32(16))); result = result.replaceAll(result.subView(pos, 7), codePt, pos);
