summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
Diffstat (limited to 'oox')
-rw-r--r--oox/qa/token/tokenmap-test.cxx12
-rw-r--r--oox/source/core/fasttokenhandler.cxx20
-rw-r--r--oox/source/crypto/AgileEngine.cxx2
-rw-r--r--oox/source/drawingml/customshapeproperties.cxx2
-rw-r--r--oox/source/drawingml/table/tablecell.cxx2
-rw-r--r--oox/source/helper/attributelist.cxx110
-rw-r--r--oox/source/mathml/importutils.cxx2
-rw-r--r--oox/source/token/tokenmap.cxx86
8 files changed, 111 insertions, 125 deletions
diff --git a/oox/qa/token/tokenmap-test.cxx b/oox/qa/token/tokenmap-test.cxx
index e30b6aef806b..b8b29911c30f 100644
--- a/oox/qa/token/tokenmap-test.cxx
+++ b/oox/qa/token/tokenmap-test.cxx
@@ -30,9 +30,6 @@ public:
CPPUNIT_TEST(test_roundTrip);
CPPUNIT_TEST(test_roundTripUnicode);
CPPUNIT_TEST_SUITE_END();
-
-private:
- TokenMap tokenMap;
};
void TokenmapTest::test_roundTrip()
@@ -40,10 +37,9 @@ void TokenmapTest::test_roundTrip()
for ( sal_Int32 nToken = 0; nToken < XML_TOKEN_COUNT; ++nToken )
{
// check that the getIdentifier <-> getToken roundtrip works
- Sequence< sal_Int8 > rUtf8Name = tokenMap.getUtf8TokenName(nToken);
- sal_Int32 ret = tokenMap.getTokenFromUTF8(
- reinterpret_cast< const char * >(rUtf8Name.getConstArray()),
- rUtf8Name.getLength() );
+ Sequence< sal_Int8 > rUtf8Name = TokenMap::getUtf8TokenName(nToken);
+ sal_Int32 ret = TokenMap::getTokenFromUtf8(std::string_view(
+ reinterpret_cast<const char*>(rUtf8Name.getConstArray()), rUtf8Name.getLength()));
CPPUNIT_ASSERT_EQUAL(ret, nToken);
}
}
@@ -53,7 +49,7 @@ void TokenmapTest::test_roundTripUnicode()
for (sal_Int32 nToken = 0; nToken < XML_TOKEN_COUNT; ++nToken)
{
// check that the getIdentifier <-> getToken roundtrip works for OUString
- OUString sName = tokenMap.getUnicodeTokenName(nToken);
+ OUString sName = TokenMap::getUnicodeTokenName(nToken);
sal_Int32 ret = oox::TokenMap::getTokenFromUnicode(sName);
CPPUNIT_ASSERT_EQUAL(ret, nToken);
}
diff --git a/oox/source/core/fasttokenhandler.cxx b/oox/source/core/fasttokenhandler.cxx
index 08531b16dc96..34c0405ee847 100644
--- a/oox/source/core/fasttokenhandler.cxx
+++ b/oox/source/core/fasttokenhandler.cxx
@@ -29,15 +29,6 @@ namespace oox::core {
using namespace ::com::sun::star::uno;
-FastTokenHandler::FastTokenHandler() :
- mrTokenMap( StaticTokenMap() )
-{
-}
-
-FastTokenHandler::~FastTokenHandler()
-{
-}
-
// XServiceInfo
OUString SAL_CALL FastTokenHandler::getImplementationName()
{
@@ -57,17 +48,18 @@ Sequence< OUString > SAL_CALL FastTokenHandler::getSupportedServiceNames()
Sequence< sal_Int8 > FastTokenHandler::getUTF8Identifier( sal_Int32 nToken )
{
- return mrTokenMap.getUtf8TokenName( nToken );
+ return TokenMap::getUtf8TokenName(nToken);
}
sal_Int32 FastTokenHandler::getTokenFromUTF8( const Sequence< sal_Int8 >& rIdentifier )
{
- return mrTokenMap.getTokenFromUtf8( rIdentifier );
+ return TokenMap::getTokenFromUtf8(std::string_view(
+ reinterpret_cast<const char*>(rIdentifier.getConstArray()), rIdentifier.getLength()));
}
-sal_Int32 FastTokenHandler::getTokenDirect( const char *pToken, sal_Int32 nLength ) const
+sal_Int32 FastTokenHandler::getTokenDirect(std::string_view token) const
{
- return mrTokenMap.getTokenFromUTF8( pToken, nLength );
+ return TokenMap::getTokenFromUtf8(token);
}
} // namespace oox::core
@@ -76,7 +68,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
com_sun_star_comp_oox_core_FastTokenHandler_get_implementation(
uno::XComponentContext* /*pCtx*/, uno::Sequence<uno::Any> const& /*rSeq*/)
{
- return cppu::acquire(new oox::core::FastTokenHandler());
+ return cppu::acquire(new oox::core::FastTokenHandler);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/crypto/AgileEngine.cxx b/oox/source/crypto/AgileEngine.cxx
index 5fa217d42044..1f164aa6ab42 100644
--- a/oox/source/crypto/AgileEngine.cxx
+++ b/oox/source/crypto/AgileEngine.cxx
@@ -65,7 +65,7 @@ public:
return Sequence<sal_Int8>();
}
- virtual sal_Int32 getTokenDirect( const char * /* pToken */, sal_Int32 /* nLength */ ) const override
+ virtual sal_Int32 getTokenDirect(std::string_view /* token */) const override
{
return -1;
}
diff --git a/oox/source/drawingml/customshapeproperties.cxx b/oox/source/drawingml/customshapeproperties.cxx
index 447f5262b13f..1b069f8939d7 100644
--- a/oox/source/drawingml/customshapeproperties.cxx
+++ b/oox/source/drawingml/customshapeproperties.cxx
@@ -117,7 +117,7 @@ CustomShapeProperties::CustomShapeProperties()
OUString CustomShapeProperties::getShapePresetTypeName() const
{
- return StaticTokenMap().getUnicodeTokenName(mnShapePresetType);
+ return TokenMap::getUnicodeTokenName(mnShapePresetType);
}
bool CustomShapeProperties::representsDefaultShape() const
diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx
index 21948145e1d2..3a10597996ba 100644
--- a/oox/source/drawingml/table/tablecell.cxx
+++ b/oox/source/drawingml/table/tablecell.cxx
@@ -605,7 +605,7 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, cons
else if ( getVertToken() != XML_horz && getVertToken() != XML_eaVert )
{
// put the vert value in the grab bag for roundtrip
- const OUString aTokenName(StaticTokenMap().getUnicodeTokenName(getVertToken()));
+ const OUString aTokenName(TokenMap::getUnicodeTokenName(getVertToken()));
Sequence<PropertyValue> aGrabBag;
xPropSet->getPropertyValue(u"CellInteropGrabBag"_ustr) >>= aGrabBag;
PropertyValue aPropertyValue = comphelper::makePropertyValue(u"mso-tcPr-vert-value"_ustr, aTokenName);
diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx
index 488105d4eed1..dc5c54c14d3d 100644
--- a/oox/source/helper/attributelist.cxx
+++ b/oox/source/helper/attributelist.cxx
@@ -62,6 +62,19 @@ sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd )
return *rpcStr++;
}
+template<typename C> sal_uInt32 decodeUnsigned_impl(std::basic_string_view<C> rValue)
+{
+ return getLimitedValue<sal_uInt32, sal_Int64>(o3tl::toInt64(rValue), 0, SAL_MAX_UINT32);
+}
+
+template <typename C> sal_Int32 decodeIntegerHex_impl(std::basic_string_view<C> rValue)
+{
+ // It looks like all Office Open XML attributes containing hexadecimal
+ // values are based on xsd:hexBinary and so use an unsigned representation:
+ return static_cast<sal_Int32>(o3tl::toUInt32(rValue, 16));
+ //TODO: Change this function to return sal_uInt32 and get rid of the
+ // cast, but that will have a ripple effect
+}
} // namespace
#define STRING_TO_TOKEN(color) if (sColorName == u"" #color) return XML_##color
@@ -98,12 +111,13 @@ OUString AttributeConversion::decodeXString( const OUString& rValue )
// string shorter than one encoded character - no need to decode
if( rValue.getLength() < XSTRING_ENCCHAR_LEN )
return rValue;
- if (rValue.indexOf(u"_x") == -1)
+ sal_Int32 index = rValue.indexOf(u"_x");
+ if (index == -1)
return rValue;
- OUStringBuffer aBuffer;
- const sal_Unicode* pcStr = rValue.getStr();
- const sal_Unicode* pcEnd = pcStr + rValue.getLength();
+ OUStringBuffer aBuffer(rValue.subView(0, index));
+ const sal_Unicode* pcStr = rValue.getStr() + index;
+ const sal_Unicode* pcEnd = rValue.getStr() + rValue.getLength();
while( pcStr < pcEnd )
aBuffer.append( lclGetXChar( pcStr, pcEnd ) );
return comphelper::string::sanitizeStringSurrogates(aBuffer.makeStringAndClear());
@@ -116,7 +130,7 @@ sal_Int32 AttributeConversion::decodeInteger( std::u16string_view rValue )
sal_uInt32 AttributeConversion::decodeUnsigned( std::u16string_view rValue )
{
- return getLimitedValue< sal_uInt32, sal_Int64 >( o3tl::toInt64(rValue), 0, SAL_MAX_UINT32 );
+ return decodeUnsigned_impl(rValue);
}
sal_Int64 AttributeConversion::decodeHyper( std::u16string_view rValue )
@@ -126,27 +140,19 @@ sal_Int64 AttributeConversion::decodeHyper( std::u16string_view rValue )
sal_Int32 AttributeConversion::decodeIntegerHex( std::u16string_view rValue )
{
- // It looks like all Office Open XML attributes containing hexadecimal
- // values are based on xsd:hexBinary and so use an unsigned representation:
- return static_cast< sal_Int32 >(o3tl::toUInt32(rValue, 16));
- //TODO: Change this function to return sal_uInt32 and get rid of the
- // cast, but that will have a ripple effect
+ return decodeIntegerHex_impl(rValue);
}
AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) :
- mxAttribs( rxAttribs ),
- mpAttribList( nullptr )
+ mxAttribs(&sax_fastparser::castToFastAttributeList(rxAttribs))
{
- OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" );
}
-sax_fastparser::FastAttributeList *AttributeList::getAttribList() const
+AttributeList::~AttributeList() = default;
+
+css::uno::Reference<css::xml::sax::XFastAttributeList> AttributeList::getFastAttributeList() const
{
- if( mpAttribList == nullptr )
- {
- mpAttribList = &sax_fastparser::castToFastAttributeList( mxAttribs );
- }
- return mpAttribList;
+ return mxAttribs;
}
bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const
@@ -173,46 +179,43 @@ std::optional< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const
std::optional< OUString > AttributeList::getString( sal_Int32 nAttrToken ) const
{
// check if the attribute exists (empty string may be different to missing attribute)
- if( mxAttribs->hasAttribute( nAttrToken ) )
- return std::optional< OUString >( mxAttribs->getOptionalValue( nAttrToken ) );
+ if (sal_Int32 index = mxAttribs->getAttributeIndex(nAttrToken); index >= 0)
+ return mxAttribs->getValueByIndex(index);
return std::optional< OUString >();
}
OUString AttributeList::getStringDefaulted( sal_Int32 nAttrToken ) const
{
- // check if the attribute exists (empty string may be different to missing attribute)
- if( mxAttribs->hasAttribute( nAttrToken ) )
- return mxAttribs->getOptionalValue( nAttrToken );
- return OUString();
+ return mxAttribs->getOptionalValue(nAttrToken);
}
std::optional< OUString > AttributeList::getXString( sal_Int32 nAttrToken ) const
{
// check if the attribute exists (empty string may be different to missing attribute)
- if( mxAttribs->hasAttribute( nAttrToken ) )
- return std::optional< OUString >( AttributeConversion::decodeXString( mxAttribs->getOptionalValue( nAttrToken ) ) );
+ if (sal_Int32 index = mxAttribs->getAttributeIndex(nAttrToken); index >= 0)
+ return AttributeConversion::decodeXString(mxAttribs->getValueByIndex(index));
return std::optional< OUString >();
}
std::optional< double > AttributeList::getDouble( sal_Int32 nAttrToken ) const
{
double nValue;
- bool bValid = getAttribList()->getAsDouble( nAttrToken, nValue );
+ bool bValid = mxAttribs->getAsDouble(nAttrToken, nValue);
return bValid ? std::optional< double >( nValue ) : std::optional< double >();
}
std::optional< sal_Int32 > AttributeList::getInteger( sal_Int32 nAttrToken ) const
{
sal_Int32 nValue;
- bool bValid = getAttribList()->getAsInteger( nAttrToken, nValue );
+ bool bValid = mxAttribs->getAsInteger(nAttrToken, nValue);
return bValid ? std::optional< sal_Int32 >( nValue ) : std::optional< sal_Int32 >();
}
std::optional< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nAttrToken ) const
{
- OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
- bool bValid = !aValue.isEmpty();
- return bValid ? std::optional< sal_uInt32 >( AttributeConversion::decodeUnsigned( aValue ) ) : std::optional< sal_uInt32 >();
+ std::string_view aValue = getView(nAttrToken);
+ bool bValid = !aValue.empty();
+ return bValid ? std::optional< sal_uInt32 >( decodeUnsigned_impl( aValue ) ) : std::optional< sal_uInt32 >();
}
std::optional< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const
@@ -224,19 +227,19 @@ std::optional< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const
std::optional< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nAttrToken ) const
{
- OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
- bool bValid = !aValue.isEmpty();
- return bValid ? std::optional< sal_Int32 >( AttributeConversion::decodeIntegerHex( aValue ) ) : std::optional< sal_Int32 >();
+ std::string_view aValue = getView(nAttrToken);
+ bool bValid = !aValue.empty();
+ return bValid ? std::optional< sal_Int32 >( decodeIntegerHex_impl( aValue ) ) : std::optional< sal_Int32 >();
}
std::optional< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const
{
- std::string_view pAttr;
+ sal_Int32 index = mxAttribs->getAttributeIndex(nAttrToken);
+ if (index == -1)
+ return std::optional< bool >();
+ std::string_view pAttr = mxAttribs->getAsViewByIndex(index);
// catch the common cases as quickly as possible first
- bool bHasAttr = getAttribList()->getAsView( nAttrToken, pAttr );
- if( !bHasAttr )
- return std::optional< bool >();
if( pAttr == "false" )
return std::optional< bool >( false );
if( pAttr == "true" )
@@ -245,7 +248,7 @@ std::optional< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const
// now for all the crazy stuff
// boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0"
- switch( getToken( nAttrToken, XML_TOKEN_INVALID ) )
+ switch (mxAttribs->getValueTokenByIndex(index))
{
case XML_t: return std::optional< bool >( true ); // used in VML
case XML_true: return std::optional< bool >( true );
@@ -254,8 +257,7 @@ std::optional< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const
case XML_false: return std::optional< bool >( false );
case XML_off: return std::optional< bool >( false );
}
- std::optional< sal_Int32 > onValue = getInteger( nAttrToken );
- return onValue.has_value() ? std::optional< bool >( onValue.value() != 0 ) : std::optional< bool >();
+ return std::optional<bool>(o3tl::toInt32(pAttr) != 0);
}
std::optional< util::DateTime > AttributeList::getDateTime( sal_Int32 nAttrToken ) const
@@ -288,17 +290,8 @@ sal_Int32 AttributeList::getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) co
OUString AttributeList::getString( sal_Int32 nAttrToken, const OUString& rDefault ) const
{
- // try to avoid slow exception throw/catch if we can
- if (rDefault.isEmpty())
- return mxAttribs->getOptionalValue( nAttrToken );
-
- try
- {
- return mxAttribs->getValue( nAttrToken );
- }
- catch( Exception& )
- {
- }
+ if (sal_Int32 index = mxAttribs->getAttributeIndex(nAttrToken); index >= 0)
+ return mxAttribs->getValueByIndex(index);
return rDefault;
}
@@ -310,7 +303,7 @@ OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefau
std::string_view AttributeList::getView( sal_Int32 nAttrToken ) const
{
std::string_view p;
- getAttribList()->getAsView(nAttrToken, p);
+ mxAttribs->getAsView(nAttrToken, p);
return p;
}
@@ -357,12 +350,9 @@ util::DateTime AttributeList::getDateTime( sal_Int32 nAttrToken, const util::Dat
std::vector<sal_Int32> AttributeList::getTokenList(sal_Int32 nAttrToken) const
{
std::vector<sal_Int32> aValues;
- OUString sValue = getString(nAttrToken, u""_ustr);
- sal_Int32 nIndex = 0;
- do
- {
- aValues.push_back(AttributeConversion::decodeToken(o3tl::getToken(sValue, 0, ' ', nIndex)));
- } while (nIndex >= 0);
+ if (std::string_view sValue = getView(nAttrToken); !sValue.empty())
+ for (size_t index = 0; index != std::string_view::npos;)
+ aValues.push_back(TokenMap::getTokenFromUtf8(o3tl::getToken(sValue, ' ', index)));
return aValues;
}
diff --git a/oox/source/mathml/importutils.cxx b/oox/source/mathml/importutils.cxx
index 7aa8a1a924e5..4f6c243b9970 100644
--- a/oox/source/mathml/importutils.cxx
+++ b/oox/source/mathml/importutils.cxx
@@ -52,7 +52,7 @@ AttributeListBuilder::AttributeListBuilder( const uno::Reference< xml::sax::XFas
OString tokenToString( int token )
{
- uno::Sequence< sal_Int8 > const & aTokenNameSeq = StaticTokenMap().getUtf8TokenName( token & TOKEN_MASK );
+ uno::Sequence<sal_Int8> const& aTokenNameSeq = TokenMap::getUtf8TokenName(token & TOKEN_MASK);
OString tokenname( reinterpret_cast< const char* >( aTokenNameSeq.getConstArray() ), aTokenNameSeq.getLength() );
if( tokenname.isEmpty())
tokenname = "???"_ostr;
diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx
index 1e51116192c6..dcd1481cbe15 100644
--- a/oox/source/token/tokenmap.cxx
+++ b/oox/source/token/tokenmap.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <array>
+
#include <oox/token/tokenmap.hxx>
#include <string.h>
@@ -25,8 +29,6 @@
namespace oox {
-using ::com::sun::star::uno::Sequence;
-
namespace {
// include auto-generated Perfect_Hash
#if defined __clang__
@@ -42,55 +44,61 @@ namespace {
#endif
} // namespace
-const css::uno::Sequence< sal_Int8 > TokenMap::EMPTY_BYTE_SEQ;
+static sal_Int32 getTokenPerfectHash(const char* pStr, sal_Int32 nLength)
+{
+ const struct xmltoken* pToken = Perfect_Hash::in_word_set( pStr, nLength );
+ return pToken ? pToken->nToken : XML_TOKEN_INVALID;
+}
-TokenMap::TokenMap() :
- maTokenNames( static_cast< size_t >( XML_TOKEN_COUNT ) )
+css::uno::Sequence<sal_Int8> const& TokenMap::getUtf8TokenName(sal_Int32 nToken)
{
- static const char* sppcTokenNames[] =
+ static const auto saTokenNames = []()
{
+ static constexpr std::string_view sppcTokenNames[] = {
// include auto-generated C array with token names as C strings
#include <tokennames.inc>
- ""
- };
-
- const char* const* ppcTokenName = sppcTokenNames;
- for (auto & tokenName : maTokenNames)
- {
- OString aUtf8Token( *ppcTokenName );
- tokenName = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUtf8Token.getStr() ), aUtf8Token.getLength() );
- ++ppcTokenName;
- }
+ };
+ static_assert(std::size(sppcTokenNames) == XML_TOKEN_COUNT);
- for (unsigned char c = 'a'; c <= 'z'; c++)
- {
- const struct xmltoken* pToken = Perfect_Hash::in_word_set(
- reinterpret_cast< const char* >( &c ), 1 );
- mnAlphaTokens[ c - 'a' ] = pToken ? pToken->nToken : XML_TOKEN_INVALID;
- }
-}
+ std::vector<css::uno::Sequence<sal_Int8>> aTokenNames;
+ aTokenNames.reserve(std::size(sppcTokenNames));
+ std::transform(
+ std::begin(sppcTokenNames), std::end(sppcTokenNames), std::back_inserter(aTokenNames),
+ [](auto aUtf8Token)
+ {
+ return css::uno::Sequence<sal_Int8>(
+ reinterpret_cast<const sal_Int8*>(aUtf8Token.data()), aUtf8Token.size());
+ });
+ return aTokenNames;
+ }();
-TokenMap::~TokenMap()
-{
+ SAL_WARN_IF(nToken < 0 || nToken >= XML_TOKEN_COUNT, "oox", "Wrong nToken parameter");
+ if (0 <= nToken && nToken < XML_TOKEN_COUNT)
+ return saTokenNames[nToken];
+ static const css::uno::Sequence<sal_Int8> EMPTY_BYTE_SEQ;
+ return EMPTY_BYTE_SEQ;
}
-sal_Int32 TokenMap::getTokenFromUnicode( std::u16string_view rUnicodeName )
-{
- OString aUtf8Name = OUStringToOString( rUnicodeName, RTL_TEXTENCODING_UTF8 );
- const struct xmltoken* pToken = Perfect_Hash::in_word_set( aUtf8Name.getStr(), aUtf8Name.getLength() );
- return pToken ? pToken->nToken : XML_TOKEN_INVALID;
-}
-sal_Int32 TokenMap::getTokenPerfectHash( const char *pStr, sal_Int32 nLength )
+/** Returns the token identifier for a UTF8 string passed in pToken */
+sal_Int32 TokenMap::getTokenFromUtf8(std::string_view token)
{
- const struct xmltoken* pToken = Perfect_Hash::in_word_set( pStr, nLength );
- return pToken ? pToken->nToken : XML_TOKEN_INVALID;
-}
+ static const auto snAlphaTokens = []()
+ {
+ std::array<sal_Int32, 26> nAlphaTokens{};
+ for (char c = 'a'; c <= 'z'; c++)
+ nAlphaTokens[c - 'a'] = getTokenPerfectHash(&c, 1);
+ return nAlphaTokens;
+ }();
-TokenMap& StaticTokenMap()
-{
- static TokenMap SINGLETON;
- return SINGLETON;
+ // 50% of OOXML tokens are primarily 1 lower-case character, a-z
+ if (token.size() == 1)
+ {
+ char c = token[0];
+ if (c >= 'a' && c <= 'z')
+ return snAlphaTokens[c - 'a'];
+ }
+ return getTokenPerfectHash(token.data(), token.size());
}
} // namespace oox