From 0eeb310d9ed8654ac4c96c444ebad49a567ad618 Mon Sep 17 00:00:00 2001 From: Noel Date: Mon, 21 Dec 2020 11:25:03 +0200 Subject: reduce duplication in sax converter Change-Id: I05bfb50e81a84b5f3bb7749e85058f967cb4b4ea Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108094 Tested-by: Jenkins Reviewed-by: Noel Grandin --- sax/source/tools/converter.cxx | 415 +++++++---------------------------------- 1 file changed, 68 insertions(+), 347 deletions(-) (limited to 'sax') diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx index de2c66dc7435..a4a793c0392e 100644 --- a/sax/source/tools/converter.cxx +++ b/sax/source/tools/converter.cxx @@ -51,9 +51,20 @@ const char* const gpsPC = "pc"; const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 14; +static sal_Int64 toInt64_WithLength(const sal_Unicode * str, sal_Int16 radix, sal_Int32 nStrLength ) +{ + return rtl_ustr_toInt64_WithLength(str, radix, nStrLength); +} +static sal_Int64 toInt64_WithLength(const char * str, sal_Int16 radix, sal_Int32 nStrLength ) +{ + return rtl_str_toInt64_WithLength(str, radix, nStrLength); +} + + /** convert string to measure using optional min and max values*/ -bool Converter::convertMeasure( sal_Int32& rValue, - std::u16string_view rString, +template +static bool lcl_convertMeasure( sal_Int32& rValue, + V rString, sal_Int16 nTargetUnit /* = MeasureUnit::MM_100TH */, sal_Int32 nMin /* = SAL_MIN_INT32 */, sal_Int32 nMax /* = SAL_MAX_INT32 */ ) @@ -266,217 +277,25 @@ bool Converter::convertMeasure( sal_Int32& rValue, /** convert string to measure using optional min and max values*/ bool Converter::convertMeasure( sal_Int32& rValue, - std::string_view rString, + std::u16string_view rString, sal_Int16 nTargetUnit /* = MeasureUnit::MM_100TH */, sal_Int32 nMin /* = SAL_MIN_INT32 */, sal_Int32 nMax /* = SAL_MAX_INT32 */ ) { - bool bNeg = false; - double nVal = 0; - - sal_Int32 nPos = 0; - sal_Int32 const nLen = rString.size(); - - // skip white space - while( (nPos < nLen) && (rString[nPos] <= ' ') ) - nPos++; - - if( nPos < nLen && '-' == rString[nPos] ) - { - bNeg = true; - nPos++; - } - - // get number - while( nPos < nLen && - '0' <= rString[nPos] && - '9' >= rString[nPos] ) - { - // TODO: check overflow! - nVal *= 10; - nVal += (rString[nPos] - '0'); - nPos++; - } - if( nPos < nLen && '.' == rString[nPos] ) - { - nPos++; - double nDiv = 1.; - - while( nPos < nLen && - '0' <= rString[nPos] && - '9' >= rString[nPos] ) - { - // TODO: check overflow! - nDiv *= 10; - nVal += ( static_cast(rString[nPos] - '0') / nDiv ); - nPos++; - } - } - - // skip white space - while( (nPos < nLen) && (rString[nPos] <= ' ') ) - nPos++; - - if( nPos < nLen ) - { - - if( MeasureUnit::PERCENT == nTargetUnit ) - { - if( '%' != rString[nPos] ) - return false; - } - else if( MeasureUnit::PIXEL == nTargetUnit ) - { - if( nPos + 1 >= nLen || - ('p' != rString[nPos] && - 'P' != rString[nPos])|| - ('x' != rString[nPos+1] && - 'X' != rString[nPos+1]) ) - return false; - } - else - { - OSL_ENSURE( MeasureUnit::TWIP == nTargetUnit || MeasureUnit::POINT == nTargetUnit || - MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit || - MeasureUnit::PIXEL == nTargetUnit, "unit is not supported"); - const char *aCmpsL[3] = { nullptr, nullptr, nullptr }; - const char *aCmpsU[3] = { nullptr, nullptr, nullptr }; - double aScales[3] = { 1., 1., 1. }; - - if( MeasureUnit::TWIP == nTargetUnit ) - { - switch( rString[nPos] ) - { - case u'c': - case u'C': - aCmpsL[0] = "cm"; - aCmpsU[0] = "CM"; - aScales[0] = (72.*20.)/2.54; // twip - break; - case u'i': - case u'I': - aCmpsL[0] = "in"; - aCmpsU[0] = "IN"; - aScales[0] = 72.*20.; // twip - break; - case u'm': - case u'M': - aCmpsL[0] = "mm"; - aCmpsU[0] = "MM"; - aScales[0] = (72.*20.)/25.4; // twip - break; - case u'p': - case u'P': - aCmpsL[0] = "pt"; - aCmpsU[0] = "PT"; - aScales[0] = 20.; // twip - - aCmpsL[1] = "pc"; - aCmpsU[1] = "PC"; - aScales[1] = 12.*20.; // twip - break; - } - } - else if( MeasureUnit::MM_100TH == nTargetUnit || MeasureUnit::MM_10TH == nTargetUnit ) - { - double nScaleFactor = (MeasureUnit::MM_100TH == nTargetUnit) ? 100.0 : 10.0; - switch( rString[nPos] ) - { - case u'c': - case u'C': - aCmpsL[0] = "cm"; - aCmpsU[0] = "CM"; - aScales[0] = 10.0 * nScaleFactor; // mm/100 - break; - case u'i': - case u'I': - aCmpsL[0] = "in"; - aCmpsU[0] = "IN"; - aScales[0] = 1000.*2.54; // mm/100 - break; - case u'm': - case u'M': - aCmpsL[0] = "mm"; - aCmpsU[0] = "MM"; - aScales[0] = 1.0 * nScaleFactor; // mm/100 - break; - case u'p': - case u'P': - aCmpsL[0] = "pt"; - aCmpsU[0] = "PT"; - aScales[0] = (10.0 * nScaleFactor*2.54)/72.; // mm/100 - - aCmpsL[1] = "pc"; - aCmpsU[1] = "PC"; - aScales[1] = (10.0 * nScaleFactor*2.54)/12.; // mm/100 - - aCmpsL[2] = "px"; - aCmpsU[2] = "PX"; - aScales[2] = 0.28 * nScaleFactor; // mm/100 - break; - } - } - else if( MeasureUnit::POINT == nTargetUnit ) - { - if( rString[nPos] == 'p' || rString[nPos] == 'P' ) - { - aCmpsL[0] = "pt"; - aCmpsU[0] = "PT"; - aScales[0] = 1; - } - } - - if( aCmpsL[0] == nullptr ) - return false; - - double nScale = 0.; - for( sal_uInt16 i= 0; i < 3; i++ ) - { - sal_Int32 nTmp = nPos; // come back to the initial position before each iteration - const char *pL = aCmpsL[i]; - if( pL ) - { - const char *pU = aCmpsU[i]; - while( nTmp < nLen && *pL ) - { - sal_Unicode c = rString[nTmp]; - if( c != *pL && c != *pU ) - break; - pL++; - pU++; - nTmp++; - } - if( !*pL && (nTmp == nLen || ' ' == rString[nTmp]) ) - { - nScale = aScales[i]; - break; - } - } - } - - if( 0. == nScale ) - return false; - - // TODO: check overflow - if( nScale != 1. ) - nVal *= nScale; - } - } - - nVal += .5; - if( bNeg ) - nVal = -nVal; - - if( nVal <= static_cast(nMin) ) - rValue = nMin; - else if( nVal >= static_cast(nMax) ) - rValue = nMax; - else - rValue = static_cast(nVal); + return lcl_convertMeasure(rValue, rString, nTargetUnit, nMin, nMax); +} - return true; +/** convert string to measure using optional min and max values*/ +bool Converter::convertMeasure( sal_Int32& rValue, + std::string_view rString, + sal_Int16 nTargetUnit /* = MeasureUnit::MM_100TH */, + sal_Int32 nMin /* = SAL_MIN_INT32 */, + sal_Int32 nMax /* = SAL_MAX_INT32 */ ) +{ + return lcl_convertMeasure(rValue, rString, nTargetUnit, nMin, nMax); } + /** convert measure in given unit to string with given unit */ void Converter::convertMeasure( OUStringBuffer& rBuffer, sal_Int32 nMeasure, @@ -710,7 +529,8 @@ static int lcl_gethex( int nChar ) } /** convert string to rgb color */ -bool Converter::convertColor( sal_Int32& rColor, std::u16string_view rValue ) +template +static bool lcl_convertColor( sal_Int32& rColor, V rValue ) { if( rValue.size() != 7 || rValue[0] != '#' ) return false; @@ -718,29 +538,24 @@ bool Converter::convertColor( sal_Int32& rColor, std::u16string_view rValue ) rColor = lcl_gethex( rValue[1] ) * 16 + lcl_gethex( rValue[2] ); rColor <<= 8; - rColor |= ( lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] ) ); + rColor |= lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] ); rColor <<= 8; - rColor |= ( lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] ) ); + rColor |= lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] ); return true; } /** convert string to rgb color */ -bool Converter::convertColor( sal_Int32& rColor, std::string_view rValue ) +bool Converter::convertColor( sal_Int32& rColor, std::u16string_view rValue ) { - if( rValue.size() != 7 || rValue[0] != '#' ) - return false; - - rColor = lcl_gethex( rValue[1] ) * 16 + lcl_gethex( rValue[2] ); - rColor <<= 8; - - rColor |= ( lcl_gethex( rValue[3] ) * 16 + lcl_gethex( rValue[4] ) ); - rColor <<= 8; - - rColor |= ( lcl_gethex( rValue[5] ) * 16 + lcl_gethex( rValue[6] ) ); + return lcl_convertColor(rColor, rValue); +} - return true; +/** convert string to rgb color */ +bool Converter::convertColor( sal_Int32& rColor, std::string_view rValue ) +{ + return lcl_convertColor(rColor, rValue); } const char aHexTab[] = "0123456789abcdef"; @@ -790,8 +605,9 @@ bool Converter::convertNumber( sal_Int32& rValue, } /** convert string to 64-bit number with optional min and max values */ -bool Converter::convertNumber64( sal_Int64& rValue, - std::u16string_view aString, +template +static bool lcl_convertNumber64( sal_Int64& rValue, + V aString, sal_Int64 nMin, sal_Int64 nMax ) { sal_Int32 nPos = 0; @@ -816,7 +632,7 @@ bool Converter::convertNumber64( sal_Int64& rValue, nPos++; } - rValue = rtl_ustr_toInt64_WithLength(aString.data() + nNumberStartPos, 10, nPos - nNumberStartPos); + rValue = toInt64_WithLength(aString.data() + nNumberStartPos, 10, nPos - nNumberStartPos); if( rValue < nMin ) rValue = nMin; @@ -828,41 +644,21 @@ bool Converter::convertNumber64( sal_Int64& rValue, /** convert string to 64-bit number with optional min and max values */ bool Converter::convertNumber64( sal_Int64& rValue, - std::string_view aString, + std::u16string_view aString, sal_Int64 nMin, sal_Int64 nMax ) { - sal_Int32 nPos = 0; - sal_Int32 const nLen = aString.size(); - - // skip white space - while( (nPos < nLen) && (aString[nPos] <= ' ') ) - nPos++; - - sal_Int32 nNumberStartPos = nPos; - - if( nPos < nLen && '-' == aString[nPos] ) - { - nPos++; - } - - // get number - while( nPos < nLen && - '0' <= aString[nPos] && - '9' >= aString[nPos] ) - { - nPos++; - } - - rValue = rtl_str_toInt64_WithLength(aString.data() + nNumberStartPos, 10, nPos - nNumberStartPos); - - if( rValue < nMin ) - rValue = nMin; - else if( rValue > nMax ) - rValue = nMax; + return lcl_convertNumber64(rValue, aString, nMin, nMax); +} - return ( nPos == nLen && rValue >= nMin && rValue <= nMax ); +/** convert string to 64-bit number with optional min and max values */ +bool Converter::convertNumber64( sal_Int64& rValue, + std::string_view aString, + sal_Int64 nMin, sal_Int64 nMax ) +{ + return lcl_convertNumber64(rValue, aString, nMin, nMax); } + /** convert double number to string (using ::rtl::math) */ void Converter::convertDouble( OUStringBuffer& rBuffer, double fNumber, @@ -2617,7 +2413,8 @@ double Converter::GetConversionFactor(OUStringBuffer& rUnit, sal_Int16 nSourceUn return fRetval; } -sal_Int16 Converter::GetUnitFromString(std::u16string_view rString, sal_Int16 nDefaultUnit) +template +static sal_Int16 lcl_GetUnitFromString(V rString, sal_Int16 nDefaultUnit) { sal_Int32 nPos = 0; sal_Int32 nLen = rString.size(); @@ -2650,43 +2447,43 @@ sal_Int16 Converter::GetUnitFromString(std::u16string_view rString, sal_Int16 nD { switch(rString[nPos]) { - case u'%' : + case '%' : { nRetUnit = MeasureUnit::PERCENT; break; } - case u'c': - case u'C': + case 'c': + case 'C': { if(nPos+1 < nLen && (rString[nPos+1] == 'm' || rString[nPos+1] == 'M')) nRetUnit = MeasureUnit::CM; break; } - case u'e': - case u'E': + case 'e': + case 'E': { // CSS1_EMS or CSS1_EMX later break; } - case u'i': - case u'I': + case 'i': + case 'I': { if(nPos+1 < nLen && (rString[nPos+1] == 'n' || rString[nPos+1] == 'N')) nRetUnit = MeasureUnit::INCH; break; } - case u'm': - case u'M': + case 'm': + case 'M': { if(nPos+1 < nLen && (rString[nPos+1] == 'm' || rString[nPos+1] == 'M')) nRetUnit = MeasureUnit::MM; break; } - case u'p': - case u'P': + case 'p': + case 'P': { if(nPos+1 < nLen && (rString[nPos+1] == 't' || rString[nPos+1] == 'T')) @@ -2702,89 +2499,13 @@ sal_Int16 Converter::GetUnitFromString(std::u16string_view rString, sal_Int16 nD return nRetUnit; } +sal_Int16 Converter::GetUnitFromString(std::u16string_view rString, sal_Int16 nDefaultUnit) +{ + return lcl_GetUnitFromString(rString, nDefaultUnit); +} sal_Int16 Converter::GetUnitFromString(std::string_view rString, sal_Int16 nDefaultUnit) { - sal_Int32 nPos = 0; - sal_Int32 nLen = rString.size(); - sal_Int16 nRetUnit = nDefaultUnit; - - // skip white space - while( nPos < nLen && ' ' == rString[nPos] ) - nPos++; - - // skip negative - if( nPos < nLen && '-' == rString[nPos] ) - nPos++; - - // skip number - while( nPos < nLen && '0' <= rString[nPos] && '9' >= rString[nPos] ) - nPos++; - - if( nPos < nLen && '.' == rString[nPos] ) - { - nPos++; - while( nPos < nLen && '0' <= rString[nPos] && '9' >= rString[nPos] ) - nPos++; - } - - // skip white space - while( nPos < nLen && ' ' == rString[nPos] ) - nPos++; - - if( nPos < nLen ) - { - switch(rString[nPos]) - { - case u'%' : - { - nRetUnit = MeasureUnit::PERCENT; - break; - } - case u'c': - case u'C': - { - if(nPos+1 < nLen && (rString[nPos+1] == 'm' - || rString[nPos+1] == 'M')) - nRetUnit = MeasureUnit::CM; - break; - } - case u'e': - case u'E': - { - // CSS1_EMS or CSS1_EMX later - break; - } - case u'i': - case u'I': - { - if(nPos+1 < nLen && (rString[nPos+1] == 'n' - || rString[nPos+1] == 'N')) - nRetUnit = MeasureUnit::INCH; - break; - } - case u'm': - case u'M': - { - if(nPos+1 < nLen && (rString[nPos+1] == 'm' - || rString[nPos+1] == 'M')) - nRetUnit = MeasureUnit::MM; - break; - } - case u'p': - case u'P': - { - if(nPos+1 < nLen && (rString[nPos+1] == 't' - || rString[nPos+1] == 'T')) - nRetUnit = MeasureUnit::POINT; - if(nPos+1 < nLen && (rString[nPos+1] == 'c' - || rString[nPos+1] == 'C')) - nRetUnit = MeasureUnit::TWIP; - break; - } - } - } - - return nRetUnit; + return lcl_GetUnitFromString(rString, nDefaultUnit); } bool Converter::convertAny(OUStringBuffer& rsValue, -- cgit v1.2.3