1*ca5ec200SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*ca5ec200SAndrew Rist * distributed with this work for additional information 6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance 9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at 10*ca5ec200SAndrew Rist * 11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*ca5ec200SAndrew Rist * 13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an 15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the 17*ca5ec200SAndrew Rist * specific language governing permissions and limitations 18*ca5ec200SAndrew Rist * under the License. 19*ca5ec200SAndrew Rist * 20*ca5ec200SAndrew Rist *************************************************************/ 21*ca5ec200SAndrew Rist 22*ca5ec200SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "oox/helper/attributelist.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <osl/diagnose.h> 27cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 28cdf0e10cSrcweir #include "oox/token/tokenmap.hxx" 29cdf0e10cSrcweir 30cdf0e10cSrcweir namespace oox { 31cdf0e10cSrcweir 32cdf0e10cSrcweir // ============================================================================ 33cdf0e10cSrcweir 34cdf0e10cSrcweir using namespace ::com::sun::star::uno; 35cdf0e10cSrcweir using namespace ::com::sun::star::util; 36cdf0e10cSrcweir using namespace ::com::sun::star::xml::sax; 37cdf0e10cSrcweir 38cdf0e10cSrcweir using ::rtl::OUString; 39cdf0e10cSrcweir using ::rtl::OUStringBuffer; 40cdf0e10cSrcweir 41cdf0e10cSrcweir // ============================================================================ 42cdf0e10cSrcweir 43cdf0e10cSrcweir namespace { 44cdf0e10cSrcweir 45cdf0e10cSrcweir const sal_Int32 XSTRING_ENCCHAR_LEN = 7; 46cdf0e10cSrcweir 47cdf0e10cSrcweir bool lclAddHexDigit( sal_Unicode& orcChar, sal_Unicode cDigit, int nBitShift ) 48cdf0e10cSrcweir { 49cdf0e10cSrcweir if( ('0' <= cDigit) && (cDigit <= '9') ) { orcChar |= ((cDigit - '0') << nBitShift); return true; } 50cdf0e10cSrcweir if( ('a' <= cDigit) && (cDigit <= 'f') ) { orcChar |= ((cDigit - 'a' + 10) << nBitShift); return true; } 51cdf0e10cSrcweir if( ('A' <= cDigit) && (cDigit <= 'F') ) { orcChar |= ((cDigit - 'A' + 10) << nBitShift); return true; } 52cdf0e10cSrcweir return false; 53cdf0e10cSrcweir } 54cdf0e10cSrcweir 55cdf0e10cSrcweir sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd ) 56cdf0e10cSrcweir { 57cdf0e10cSrcweir sal_Unicode cChar = 0; 58cdf0e10cSrcweir if( (pcEnd - rpcStr >= XSTRING_ENCCHAR_LEN) && 59cdf0e10cSrcweir (rpcStr[ 0 ] == '_') && 60cdf0e10cSrcweir (rpcStr[ 1 ] == 'x') && 61cdf0e10cSrcweir (rpcStr[ 6 ] == '_') && 62cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 2 ], 12 ) && 63cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 3 ], 8 ) && 64cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 4 ], 4 ) && 65cdf0e10cSrcweir lclAddHexDigit( cChar, rpcStr[ 5 ], 0 ) ) 66cdf0e10cSrcweir { 67cdf0e10cSrcweir rpcStr += XSTRING_ENCCHAR_LEN; 68cdf0e10cSrcweir return cChar; 69cdf0e10cSrcweir } 70cdf0e10cSrcweir return *rpcStr++; 71cdf0e10cSrcweir } 72cdf0e10cSrcweir 73cdf0e10cSrcweir } // namespace 74cdf0e10cSrcweir 75cdf0e10cSrcweir // ---------------------------------------------------------------------------- 76cdf0e10cSrcweir 77cdf0e10cSrcweir sal_Int32 AttributeConversion::decodeToken( const OUString& rValue ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir return StaticTokenMap::get().getTokenFromUnicode( rValue ); 80cdf0e10cSrcweir } 81cdf0e10cSrcweir 82cdf0e10cSrcweir OUString AttributeConversion::decodeXString( const OUString& rValue ) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir // string shorter than one encoded character - no need to decode 85cdf0e10cSrcweir if( rValue.getLength() < XSTRING_ENCCHAR_LEN ) 86cdf0e10cSrcweir return rValue; 87cdf0e10cSrcweir OUStringBuffer aBuffer; 88cdf0e10cSrcweir const sal_Unicode* pcStr = rValue.getStr(); 89cdf0e10cSrcweir const sal_Unicode* pcEnd = pcStr + rValue.getLength(); 90cdf0e10cSrcweir while( pcStr < pcEnd ) 91cdf0e10cSrcweir aBuffer.append( lclGetXChar( pcStr, pcEnd ) ); 92cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir 95cdf0e10cSrcweir double AttributeConversion::decodeDouble( const OUString& rValue ) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir return rValue.toDouble(); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir 100cdf0e10cSrcweir sal_Int32 AttributeConversion::decodeInteger( const OUString& rValue ) 101cdf0e10cSrcweir { 102cdf0e10cSrcweir return rValue.toInt32(); 103cdf0e10cSrcweir } 104cdf0e10cSrcweir 105cdf0e10cSrcweir sal_uInt32 AttributeConversion::decodeUnsigned( const OUString& rValue ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64(), 0, SAL_MAX_UINT32 ); 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir sal_Int64 AttributeConversion::decodeHyper( const OUString& rValue ) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir return rValue.toInt64(); 113cdf0e10cSrcweir } 114cdf0e10cSrcweir 115cdf0e10cSrcweir sal_Int32 AttributeConversion::decodeIntegerHex( const OUString& rValue ) 116cdf0e10cSrcweir { 117cdf0e10cSrcweir return rValue.toInt32( 16 ); 118cdf0e10cSrcweir } 119cdf0e10cSrcweir 120cdf0e10cSrcweir sal_uInt32 AttributeConversion::decodeUnsignedHex( const OUString& rValue ) 121cdf0e10cSrcweir { 122cdf0e10cSrcweir return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64( 16 ), 0, SAL_MAX_UINT32 ); 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir sal_Int64 AttributeConversion::decodeHyperHex( const OUString& rValue ) 126cdf0e10cSrcweir { 127cdf0e10cSrcweir return rValue.toInt64( 16 ); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir // ============================================================================ 131cdf0e10cSrcweir 132cdf0e10cSrcweir AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) : 133cdf0e10cSrcweir mxAttribs( rxAttribs ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" ); 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const 139cdf0e10cSrcweir { 140cdf0e10cSrcweir return mxAttribs->hasAttribute( nAttrToken ); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir 143cdf0e10cSrcweir // optional return values ----------------------------------------------------- 144cdf0e10cSrcweir 145cdf0e10cSrcweir OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const 146cdf0e10cSrcweir { 147cdf0e10cSrcweir sal_Int32 nToken = mxAttribs->getOptionalValueToken( nAttrToken, XML_TOKEN_INVALID ); 148cdf0e10cSrcweir return OptValue< sal_Int32 >( nToken != XML_TOKEN_INVALID, nToken ); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir OptValue< OUString > AttributeList::getString( sal_Int32 nAttrToken ) const 152cdf0e10cSrcweir { 153cdf0e10cSrcweir // check if the attribute exists (empty string may be different to missing attribute) 154cdf0e10cSrcweir if( mxAttribs->hasAttribute( nAttrToken ) ) 155cdf0e10cSrcweir return OptValue< OUString >( mxAttribs->getOptionalValue( nAttrToken ) ); 156cdf0e10cSrcweir return OptValue< OUString >(); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir OptValue< OUString > AttributeList::getXString( sal_Int32 nAttrToken ) const 160cdf0e10cSrcweir { 161cdf0e10cSrcweir // check if the attribute exists (empty string may be different to missing attribute) 162cdf0e10cSrcweir if( mxAttribs->hasAttribute( nAttrToken ) ) 163cdf0e10cSrcweir return OptValue< OUString >( AttributeConversion::decodeXString( mxAttribs->getOptionalValue( nAttrToken ) ) ); 164cdf0e10cSrcweir return OptValue< OUString >(); 165cdf0e10cSrcweir } 166cdf0e10cSrcweir 167cdf0e10cSrcweir OptValue< double > AttributeList::getDouble( sal_Int32 nAttrToken ) const 168cdf0e10cSrcweir { 169cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 170cdf0e10cSrcweir bool bValid = aValue.getLength() > 0; 171cdf0e10cSrcweir return OptValue< double >( bValid, bValid ? AttributeConversion::decodeDouble( aValue ) : 0.0 ); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nAttrToken ) const 175cdf0e10cSrcweir { 176cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 177cdf0e10cSrcweir bool bValid = aValue.getLength() > 0; 178cdf0e10cSrcweir return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeInteger( aValue ) : 0 ); 179cdf0e10cSrcweir } 180cdf0e10cSrcweir 181cdf0e10cSrcweir OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nAttrToken ) const 182cdf0e10cSrcweir { 183cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 184cdf0e10cSrcweir bool bValid = aValue.getLength() > 0; 185cdf0e10cSrcweir return OptValue< sal_uInt32 >( bValid, AttributeConversion::decodeUnsigned( aValue ) ); 186cdf0e10cSrcweir } 187cdf0e10cSrcweir 188cdf0e10cSrcweir OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const 189cdf0e10cSrcweir { 190cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 191cdf0e10cSrcweir bool bValid = aValue.getLength() > 0; 192cdf0e10cSrcweir return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyper( aValue ) : 0 ); 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nAttrToken ) const 196cdf0e10cSrcweir { 197cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 198cdf0e10cSrcweir bool bValid = aValue.getLength() > 0; 199cdf0e10cSrcweir return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeIntegerHex( aValue ) : 0 ); 200cdf0e10cSrcweir } 201cdf0e10cSrcweir 202cdf0e10cSrcweir OptValue< sal_uInt32 > AttributeList::getUnsignedHex( sal_Int32 nAttrToken ) const 203cdf0e10cSrcweir { 204cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 205cdf0e10cSrcweir bool bValid = aValue.getLength() > 0; 206cdf0e10cSrcweir return OptValue< sal_uInt32 >( bValid, bValid ? AttributeConversion::decodeUnsignedHex( aValue ) : 0 ); 207cdf0e10cSrcweir } 208cdf0e10cSrcweir 209cdf0e10cSrcweir OptValue< sal_Int64 > AttributeList::getHyperHex( sal_Int32 nAttrToken ) const 210cdf0e10cSrcweir { 211cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 212cdf0e10cSrcweir bool bValid = aValue.getLength() > 0; 213cdf0e10cSrcweir return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyperHex( aValue ) : 0 ); 214cdf0e10cSrcweir } 215cdf0e10cSrcweir 216cdf0e10cSrcweir OptValue< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const 217cdf0e10cSrcweir { 218cdf0e10cSrcweir // boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0" 219cdf0e10cSrcweir switch( getToken( nAttrToken, XML_TOKEN_INVALID ) ) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir case XML_t: return OptValue< bool >( true ); // used in VML 222cdf0e10cSrcweir case XML_true: return OptValue< bool >( true ); 223cdf0e10cSrcweir case XML_on: return OptValue< bool >( true ); 224cdf0e10cSrcweir case XML_f: return OptValue< bool >( false ); // used in VML 225cdf0e10cSrcweir case XML_false: return OptValue< bool >( false ); 226cdf0e10cSrcweir case XML_off: return OptValue< bool >( false ); 227cdf0e10cSrcweir } 228cdf0e10cSrcweir OptValue< sal_Int32 > onValue = getInteger( nAttrToken ); 229cdf0e10cSrcweir return OptValue< bool >( onValue.has(), onValue.get() != 0 ); 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nAttrToken ) const 233cdf0e10cSrcweir { 234cdf0e10cSrcweir OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); 235cdf0e10cSrcweir DateTime aDateTime; 236cdf0e10cSrcweir bool bValid = (aValue.getLength() == 19) && (aValue[ 4 ] == '-') && (aValue[ 7 ] == '-') && 237cdf0e10cSrcweir (aValue[ 10 ] == 'T') && (aValue[ 13 ] == ':') && (aValue[ 16 ] == ':'); 238cdf0e10cSrcweir if( bValid ) 239cdf0e10cSrcweir { 240cdf0e10cSrcweir aDateTime.Year = static_cast< sal_uInt16 >( aValue.copy( 0, 4 ).toInt32() ); 241cdf0e10cSrcweir aDateTime.Month = static_cast< sal_uInt16 >( aValue.copy( 5, 2 ).toInt32() ); 242cdf0e10cSrcweir aDateTime.Day = static_cast< sal_uInt16 >( aValue.copy( 8, 2 ).toInt32() ); 243cdf0e10cSrcweir aDateTime.Hours = static_cast< sal_uInt16 >( aValue.copy( 11, 2 ).toInt32() ); 244cdf0e10cSrcweir aDateTime.Minutes = static_cast< sal_uInt16 >( aValue.copy( 14, 2 ).toInt32() ); 245cdf0e10cSrcweir aDateTime.Seconds = static_cast< sal_uInt16 >( aValue.copy( 17, 2 ).toInt32() ); 246cdf0e10cSrcweir } 247cdf0e10cSrcweir return OptValue< DateTime >( bValid, aDateTime ); 248cdf0e10cSrcweir } 249cdf0e10cSrcweir 250cdf0e10cSrcweir // defaulted return values ---------------------------------------------------- 251cdf0e10cSrcweir 252cdf0e10cSrcweir sal_Int32 AttributeList::getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const 253cdf0e10cSrcweir { 254cdf0e10cSrcweir return mxAttribs->getOptionalValueToken( nAttrToken, nDefault ); 255cdf0e10cSrcweir } 256cdf0e10cSrcweir 257cdf0e10cSrcweir OUString AttributeList::getString( sal_Int32 nAttrToken, const OUString& rDefault ) const 258cdf0e10cSrcweir { 259cdf0e10cSrcweir try 260cdf0e10cSrcweir { 261cdf0e10cSrcweir return mxAttribs->getValue( nAttrToken ); 262cdf0e10cSrcweir } 263cdf0e10cSrcweir catch( Exception& ) 264cdf0e10cSrcweir { 265cdf0e10cSrcweir } 266cdf0e10cSrcweir return rDefault; 267cdf0e10cSrcweir } 268cdf0e10cSrcweir 269cdf0e10cSrcweir OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const 270cdf0e10cSrcweir { 271cdf0e10cSrcweir return getXString( nAttrToken ).get( rDefault ); 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir double AttributeList::getDouble( sal_Int32 nAttrToken, double fDefault ) const 275cdf0e10cSrcweir { 276cdf0e10cSrcweir return getDouble( nAttrToken ).get( fDefault ); 277cdf0e10cSrcweir } 278cdf0e10cSrcweir 279cdf0e10cSrcweir sal_Int32 AttributeList::getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const 280cdf0e10cSrcweir { 281cdf0e10cSrcweir return getInteger( nAttrToken ).get( nDefault ); 282cdf0e10cSrcweir } 283cdf0e10cSrcweir 284cdf0e10cSrcweir sal_uInt32 AttributeList::getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const 285cdf0e10cSrcweir { 286cdf0e10cSrcweir return getUnsigned( nAttrToken ).get( nDefault ); 287cdf0e10cSrcweir } 288cdf0e10cSrcweir 289cdf0e10cSrcweir sal_Int64 AttributeList::getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const 290cdf0e10cSrcweir { 291cdf0e10cSrcweir return getHyper( nAttrToken ).get( nDefault ); 292cdf0e10cSrcweir } 293cdf0e10cSrcweir 294cdf0e10cSrcweir sal_Int32 AttributeList::getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const 295cdf0e10cSrcweir { 296cdf0e10cSrcweir return getIntegerHex( nAttrToken ).get( nDefault ); 297cdf0e10cSrcweir } 298cdf0e10cSrcweir 299cdf0e10cSrcweir sal_uInt32 AttributeList::getUnsignedHex( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const 300cdf0e10cSrcweir { 301cdf0e10cSrcweir return getUnsignedHex( nAttrToken ).get( nDefault ); 302cdf0e10cSrcweir } 303cdf0e10cSrcweir 304cdf0e10cSrcweir sal_Int64 AttributeList::getHyperHex( sal_Int32 nAttrToken, sal_Int64 nDefault ) const 305cdf0e10cSrcweir { 306cdf0e10cSrcweir return getHyperHex( nAttrToken ).get( nDefault ); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir 309cdf0e10cSrcweir bool AttributeList::getBool( sal_Int32 nAttrToken, bool bDefault ) const 310cdf0e10cSrcweir { 311cdf0e10cSrcweir return getBool( nAttrToken ).get( bDefault ); 312cdf0e10cSrcweir } 313cdf0e10cSrcweir 314cdf0e10cSrcweir DateTime AttributeList::getDateTime( sal_Int32 nAttrToken, const DateTime& rDefault ) const 315cdf0e10cSrcweir { 316cdf0e10cSrcweir return getDateTime( nAttrToken ).get( rDefault ); 317cdf0e10cSrcweir } 318cdf0e10cSrcweir 319cdf0e10cSrcweir // ============================================================================ 320cdf0e10cSrcweir 321cdf0e10cSrcweir } // namespace oox 322