diff options
-rw-r--r-- | include/rtl/string.h | 78 | ||||
-rw-r--r-- | include/rtl/string.hxx | 9 | ||||
-rw-r--r-- | sal/rtl/string.cxx | 10 | ||||
-rw-r--r-- | sal/rtl/strtmpl.hxx | 76 | ||||
-rw-r--r-- | sal/util/sal.map | 8 | ||||
-rw-r--r-- | sdext/source/pdfimport/wrapper/wrapper.cxx | 31 |
6 files changed, 199 insertions, 13 deletions
diff --git a/include/rtl/string.h b/include/rtl/string.h index bfbb45057fd9..c0f724245d9e 100644 --- a/include/rtl/string.h +++ b/include/rtl/string.h @@ -747,6 +747,31 @@ SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_str_toBoolean( SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_toInt32( const char * str, sal_Int16 radix ) SAL_THROW_EXTERN_C(); +/** Interpret a string as an 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_STR_MIN_RADIX (2) and RTL_STR_MAX_RADIX + (36), inclusive. + + @param len + the length of the character array. + + @return + the integer value represented by the string, or 0 if the string does not + represent an integer. + + @since LibreOffice 7.2 + @internal + */ +SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_toInt32_WithLength( + const char * str, sal_Int16 radix, sal_Int32 nStrLength ) SAL_THROW_EXTERN_C(); + /** Interpret a string as an unsigned integer. This function cannot be used for language-specific conversion. The string @@ -1309,6 +1334,59 @@ SAL_DLLPUBLIC void SAL_CALL rtl_string_newTrim( SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_string_getToken( rtl_String ** newStr , rtl_String * str, sal_Int32 token, char cTok, sal_Int32 idx ) SAL_THROW_EXTERN_C(); +/** Create a new string by extracting a single token from another string. + + Starting at index, the token's next token is searched for. If there is no + such token, the result is an empty string. Otherwise, all characters from + the start of that token and up to, but not including the next occurrence + of cTok make up the resulting token. The return value is the position of + the next token, or -1 if no more tokens follow. + + Example code could look like + rtl_String * pToken = NULL; + sal_Int32 nIndex = 0; + do + { + ... + nIndex = rtl_string_getToken(&pToken, pStr, 0, ';', nIndex); + ... + } + while (nIndex >= 0); + + The new string does not necessarily have a reference count of 1, so it + must not be modified without checking the reference count. This function + does not handle out-of-memory conditions. + + @param ppViewStr + pointer to the start of the token. The pointed-to data must be null or a valid + string. If either token or index is negative, nullptr is stored in + newStr (and -1 is returned). + + @param pViewLength + length of the token. + + @param str + a valid string. + + @param token + the number of the token to return, starting at index. + + @param cTok + the character that separates the tokens. + + @param idx + the position at which searching for the token starts. Must not be greater + than the length of str. + + @return + the index of the next token, or -1 if no more tokens follow. + + @since LibreOffice 7.2 + @internal + */ +SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_string_getTokenView( + const char ** ppViewStr , sal_Int32* pViewLength, rtl_String * str, sal_Int32 token, char cTok, sal_Int32 idx ) SAL_THROW_EXTERN_C(); + /* ======================================================================= */ /** Supply an ASCII string literal together with its length. diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx index f80dd7410da7..c16519fa14df 100644 --- a/include/rtl/string.hxx +++ b/include/rtl/string.hxx @@ -1765,6 +1765,15 @@ public: index = rtl_string_getToken( &pNew, pData, token, cTok, index ); return OString( pNew, SAL_NO_ACQUIRE ); } +#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING" + std::string_view getTokenView( sal_Int32 token, char cTok, sal_Int32& index ) const + { + const char* pViewData = nullptr; + sal_Int32 nViewLength = 0; + index = rtl_string_getTokenView( &pViewData, &nViewLength, pData, token, cTok, index ); + return std::string_view(pViewData, nViewLength); + } +#endif /** Returns a token from the string. diff --git a/sal/rtl/string.cxx b/sal/rtl/string.cxx index 94be8029032a..2eb4654caeb4 100644 --- a/sal/rtl/string.cxx +++ b/sal/rtl/string.cxx @@ -559,6 +559,11 @@ sal_Int32 SAL_CALL rtl_str_toInt32(const char* pStr, sal_Int16 nRadix) SAL_THROW return rtl::str::toInt32(pStr, nRadix); } +sal_Int32 SAL_CALL rtl_str_toInt32_WithLength(const char* pStr, sal_Int16 nRadix, sal_Int32 nStrLength) SAL_THROW_EXTERN_C() +{ + return rtl::str::toInt32_WithLength(pStr, nRadix, nStrLength); +} + sal_Int64 SAL_CALL rtl_str_toInt64(const char* pStr, sal_Int16 nRadix) SAL_THROW_EXTERN_C() { return rtl::str::toInt64(pStr, nRadix); @@ -700,4 +705,9 @@ sal_Int32 SAL_CALL rtl_string_getToken(rtl_String** ppThis, rtl_String* pStr, sa return rtl::str::getToken(ppThis, pStr, nToken, cTok, nIndex); } +sal_Int32 SAL_CALL rtl_string_getTokenView(const char ** ppViewStr , sal_Int32* pViewLength, rtl_String* pStr, sal_Int32 nToken, + char cTok, sal_Int32 nIndex) SAL_THROW_EXTERN_C() +{ + return rtl::str::getTokenView(ppViewStr, pViewLength, pStr, nToken, cTok, nIndex); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/strtmpl.hxx b/sal/rtl/strtmpl.hxx index fdb26fd15cf1..a25e8216d154 100644 --- a/sal/rtl/strtmpl.hxx +++ b/sal/rtl/strtmpl.hxx @@ -914,6 +914,15 @@ sal_Int32 toInt32 ( const IMPL_RTL_STRCODE* pStr, } template <typename IMPL_RTL_STRCODE> +sal_Int32 toInt32_WithLength ( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix, + sal_Int32 nStrLength ) +{ + assert(pStr); + return toInt_WithLength<sal_Int32, sal_uInt32>(pStr, nRadix, nStrLength); +} + +template <typename IMPL_RTL_STRCODE> sal_Int64 toInt64 ( const IMPL_RTL_STRCODE* pStr, sal_Int16 nRadix ) { @@ -1731,6 +1740,73 @@ sal_Int32 getToken ( IMPL_RTL_STRINGDATA** ppThis return -1; } } + + +/* ----------------------------------------------------------------------- */ + +template <typename IMPL_RTL_STRINGDATA> +sal_Int32 getTokenView ( const char ** ppViewStr, + sal_Int32 * pViewLength, + IMPL_RTL_STRINGDATA* pStr, + sal_Int32 nToken, + STRCODE<IMPL_RTL_STRINGDATA> cTok, + sal_Int32 nIndex ) +{ + assert(ppViewStr); + assert(pViewLength); + assert(pStr); + const auto* pCharStr = pStr->buffer; + sal_Int32 nLen = pStr->length-nIndex; + sal_Int32 nTokCount = 0; + + // Set ppThis to an empty string and return -1 if either nToken or nIndex is + // negative: + if (nIndex < 0) + nToken = -1; + + pCharStr += nIndex; + const auto* pOrgCharStr = pCharStr; + const auto* pCharStrStart = pCharStr; + while ( nLen > 0 ) + { + if ( *pCharStr == cTok ) + { + nTokCount++; + + if ( nTokCount == nToken ) + pCharStrStart = pCharStr+1; + else + { + if ( nTokCount > nToken ) + break; + } + } + + pCharStr++; + nLen--; + } + + if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) ) + { + if( (nToken < 0) || (nTokCount < nToken) ) + return -1; + else if( nLen > 0 ) + return nIndex+(pCharStr-pOrgCharStr)+1; + else return -1; + } + else + { + *ppViewStr = pCharStrStart; + *pViewLength = pCharStr-pCharStrStart; + if ( nLen ) + return nIndex+(pCharStr-pOrgCharStr)+1; + else + return -1; + } +} + + + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/util/sal.map b/sal/util/sal.map index 49efb2a436cd..2f74ceb9150e 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -753,7 +753,13 @@ PRIVATE_1.6 { # LibreOffice 6.4 PRIVATE_1.7 { # LibreOffice 7.1 global: rtl_uString_newReplaceAllFromIndexUtf16LUtf16L; -} PRIVATE_1.5; +} PRIVATE_1.6; + +PRIVATE_1.8 { # LibreOffice 7.2 + global: + rtl_string_getTokenView; + rtl_str_toInt32_WithLength; +} PRIVATE_1.7; PRIVATE_textenc.1 { # LibreOffice 3.6 global: diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx index 1b9a6c18af97..953d437ab5e2 100644 --- a/sdext/source/pdfimport/wrapper/wrapper.cxx +++ b/sdext/source/pdfimport/wrapper/wrapper.cxx @@ -151,7 +151,7 @@ class Parser sal_Int32 m_nCharIndex; - OString readNextToken(); + std::string_view readNextToken(); void readInt32( sal_Int32& o_Value ); sal_Int32 readInt32(); void readInt64( sal_Int64& o_Value ); @@ -244,35 +244,42 @@ OString lcl_unescapeLineFeeds(const OString& i_rStr) return aResult; } -OString Parser::readNextToken() +std::string_view Parser::readNextToken() { OSL_PRECOND(m_nCharIndex!=-1,"insufficient input"); - return m_aLine.getToken(m_nNextToken,' ',m_nCharIndex); + return m_aLine.getTokenView(m_nNextToken,' ',m_nCharIndex); } void Parser::readInt32( sal_Int32& o_Value ) { - o_Value = readNextToken().toInt32(); + std::string_view tok = readNextToken(); + o_Value = rtl_str_toInt32_WithLength(tok.data(), 10, tok.size()); } sal_Int32 Parser::readInt32() { - return readNextToken().toInt32(); + std::string_view tok = readNextToken(); + return rtl_str_toInt32_WithLength(tok.data(), 10, tok.size()); } void Parser::readInt64( sal_Int64& o_Value ) { - o_Value = readNextToken().toInt64(); + std::string_view tok = readNextToken(); + o_Value = rtl_str_toInt64_WithLength(tok.data(), 10, tok.size()); } void Parser::readDouble( double& o_Value ) { - o_Value = readNextToken().toDouble(); + std::string_view tok = readNextToken(); + o_Value = rtl_math_stringToDouble(tok.data(), tok.data() + tok.size(), '.', 0, + nullptr, nullptr); } double Parser::readDouble() { - return readNextToken().toDouble(); + std::string_view tok = readNextToken(); + return rtl_math_stringToDouble(tok.data(), tok.data() + tok.size(), '.', 0, + nullptr, nullptr); } void Parser::readBinaryData( uno::Sequence<sal_Int8>& rBuf ) @@ -679,7 +686,7 @@ void Parser::readFont() uno::Sequence<beans::PropertyValue> Parser::readImageImpl() { - OString aToken = readNextToken(); + std::string_view aToken = readNextToken(); const sal_Int32 nImageSize( readInt32() ); OUString aFileName; @@ -809,9 +816,9 @@ void Parser::parseLine( const OString& rLine ) OSL_PRECOND( m_xContext.is(), "Invalid service factory" ); m_nNextToken = 0; m_nCharIndex = 0; m_aLine = rLine; - const OString& rCmd = readNextToken(); - const hash_entry* pEntry = PdfKeywordHash::in_word_set( rCmd.getStr(), - rCmd.getLength() ); + const std::string_view rCmd = readNextToken(); + const hash_entry* pEntry = PdfKeywordHash::in_word_set( rCmd.data(), + rCmd.size() ); OSL_ASSERT(pEntry); switch( pEntry->eKey ) { |