diff --git a/sal/inc/rtl/ustring.h b/sal/inc/rtl/ustring.h index ab2707d00eb2..35be5fed1e8a 100644 --- a/sal/inc/rtl/ustring.h +++ b/sal/inc/rtl/ustring.h @@ -1073,6 +1073,25 @@ SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_ustr_toBoolean( SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_toInt32( const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C(); +/** Interpret a string as an unsigned long integer. + + This function cannot be used for language-specific conversion. The string + must be null-terminated. + + @param str + a null-terminated string. + + @param radix + the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX + (36), inclusive. + + @return + the long integer value represented by the string, or 0 if the string does + not represent a long integer. + */ +SAL_DLLPUBLIC sal_uInt64 SAL_CALL rtl_ustr_toUInt64( + const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C(); + /** Interpret a string as a long integer. This function cannot be used for language-specific conversion. The string diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx index 192ba2bee0e2..8190d208ae68 100644 --- a/sal/inc/rtl/ustring.hxx +++ b/sal/inc/rtl/ustring.hxx @@ -1842,6 +1842,20 @@ public: return rtl_ustr_toInt64( pData->buffer, radix ); } + /** + Returns the uint64 value from this string. + + This function can't be used for language specific conversion. + + @param radix the radix (between 2 and 36) + @return the uint64 represented from this string. + 0 if this string represents no number. + */ + sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const SAL_THROW(()) + { + return rtl_ustr_toUInt64( pData->buffer, radix ); + } + /** Returns the float value from this string. diff --git a/sal/rtl/source/strtmpl.cxx b/sal/rtl/source/strtmpl.cxx index 619f64e4a6ed..f5cbddd8e6f7 100644 --- a/sal/rtl/source/strtmpl.cxx +++ b/sal/rtl/source/strtmpl.cxx @@ -24,6 +24,8 @@ #include #include +#include +#include /* inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest, @@ -914,97 +916,108 @@ sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr ) } /* ----------------------------------------------------------------------- */ +namespace { + template static inline T IMPL_RTL_STRNAME( toInt )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + { + BOOST_STATIC_ASSERT(std::numeric_limits::is_signed); + sal_Bool bNeg; + sal_Int16 nDigit; + T n = 0; + + if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) + nRadix = 10; + + /* Skip whitespaces */ + while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) + pStr++; + + if ( *pStr == '-' ) + { + bNeg = sal_True; + pStr++; + } + else + { + if ( *pStr == '+' ) + pStr++; + bNeg = sal_False; + } + + while ( *pStr ) + { + nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); + if ( nDigit < 0 ) + break; + + n *= nRadix; + n += nDigit; + + pStr++; + } + + if ( bNeg ) + return -n; + else + return n; + } + + + template static inline T IMPL_RTL_STRNAME( toUInt )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + { + BOOST_STATIC_ASSERT(!std::numeric_limits::is_signed); + sal_Int16 nDigit; + T n = 0; + + if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) + nRadix = 10; + + /* Skip whitespaces */ + while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) + ++pStr; + + // skip optional explicit sign + if ( *pStr == '+' ) + ++pStr; + + while ( *pStr ) + { + nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); + if ( nDigit < 0 ) + break; + + n *= nRadix; + n += nDigit; + + ++pStr; + } + + return n; + } +} sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr, sal_Int16 nRadix ) SAL_THROW_EXTERN_C() { - sal_Bool bNeg; - sal_Int16 nDigit; - sal_Int32 n = 0; - - if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) - nRadix = 10; - - /* Skip whitespaces */ - while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) - pStr++; - - if ( *pStr == '-' ) - { - bNeg = sal_True; - pStr++; - } - else - { - if ( *pStr == '+' ) - pStr++; - bNeg = sal_False; - } - - while ( *pStr ) - { - nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); - if ( nDigit < 0 ) - break; - - n *= nRadix; - n += nDigit; - - pStr++; - } - - if ( bNeg ) - return -n; - else - return n; + return IMPL_RTL_STRNAME( toInt )(pStr, nRadix); } -/* ----------------------------------------------------------------------- */ - sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr, sal_Int16 nRadix ) SAL_THROW_EXTERN_C() { - sal_Bool bNeg; - sal_Int16 nDigit; - sal_Int64 n = 0; + return IMPL_RTL_STRNAME( toInt )(pStr, nRadix); +} - if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) - nRadix = 10; +/* ----------------------------------------------------------------------- */ - /* Skip whitespaces */ - while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) - pStr++; - - if ( *pStr == '-' ) - { - bNeg = sal_True; - pStr++; - } - else - { - if ( *pStr == '+' ) - pStr++; - bNeg = sal_False; - } - - while ( *pStr ) - { - nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); - if ( nDigit < 0 ) - break; - - n *= nRadix; - n += nDigit; - - pStr++; - } - - if ( bNeg ) - return -n; - else - return n; +sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + SAL_THROW_EXTERN_C() +{ + return IMPL_RTL_STRNAME( toUInt )(pStr, nRadix); } /* ======================================================================= */ diff --git a/sal/util/sal.map b/sal/util/sal.map index 1bebb0aa0334..e21ff0a5a384 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -660,6 +660,7 @@ LIBO_UDK_4.1 { # symbols available in >= LibO 4.1 rtl_uString_alloc; rtl_str_valueOfUInt64; rtl_ustr_valueOfUInt64; + rtl_ustr_toUInt64; } LIBO_UDK_4.0; PRIVATE_1.0 {