LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/oox/source/helper - attributelist.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 95 122 77.9 %
Date: 2013-07-09 Functions: 26 31 83.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "oox/helper/attributelist.hxx"
      21             : 
      22             : #include <osl/diagnose.h>
      23             : #include <rtl/ustrbuf.hxx>
      24             : #include "oox/token/tokenmap.hxx"
      25             : 
      26             : namespace oox {
      27             : 
      28             : // ============================================================================
      29             : 
      30             : using namespace ::com::sun::star;
      31             : using namespace ::com::sun::star::uno;
      32             : using namespace ::com::sun::star::xml::sax;
      33             : 
      34             : // ============================================================================
      35             : 
      36             : namespace {
      37             : 
      38             : const sal_Int32 XSTRING_ENCCHAR_LEN     = 7;
      39             : 
      40         489 : bool lclAddHexDigit( sal_Unicode& orcChar, sal_Unicode cDigit, int nBitShift )
      41             : {
      42         489 :     if( ('0' <= cDigit) && (cDigit <= '9') ) { orcChar |= ((cDigit - '0') << nBitShift); return true; }
      43           1 :     if( ('a' <= cDigit) && (cDigit <= 'f') ) { orcChar |= ((cDigit - 'a' + 10) << nBitShift); return true; }
      44           1 :     if( ('A' <= cDigit) && (cDigit <= 'F') ) { orcChar |= ((cDigit - 'A' + 10) << nBitShift); return true; }
      45           1 :     return false;
      46             : }
      47             : 
      48        1843 : sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd )
      49             : {
      50        1843 :     sal_Unicode cChar = 0;
      51        4260 :     if( (pcEnd - rpcStr >= XSTRING_ENCCHAR_LEN) &&
      52         698 :         (rpcStr[ 0 ] == '_') &&
      53         247 :         (rpcStr[ 1 ] == 'x') &&
      54         246 :         (rpcStr[ 6 ] == '_') &&
      55         245 :         lclAddHexDigit( cChar, rpcStr[ 2 ], 12 ) &&
      56         244 :         lclAddHexDigit( cChar, rpcStr[ 3 ], 8 ) &&
      57        2087 :         lclAddHexDigit( cChar, rpcStr[ 4 ], 4 ) &&
      58         122 :         lclAddHexDigit( cChar, rpcStr[ 5 ], 0 ) )
      59             :     {
      60         122 :         rpcStr += XSTRING_ENCCHAR_LEN;
      61         122 :         return cChar;
      62             :     }
      63        1721 :     return *rpcStr++;
      64             : }
      65             : 
      66             : } // namespace
      67             : 
      68             : // ----------------------------------------------------------------------------
      69             : 
      70         674 : sal_Int32 AttributeConversion::decodeToken( const OUString& rValue )
      71             : {
      72         674 :     return StaticTokenMap::get().getTokenFromUnicode( rValue );
      73             : }
      74             : 
      75         447 : OUString AttributeConversion::decodeXString( const OUString& rValue )
      76             : {
      77             :     // string shorter than one encoded character - no need to decode
      78         447 :     if( rValue.getLength() < XSTRING_ENCCHAR_LEN )
      79         202 :         return rValue;
      80         245 :     OUStringBuffer aBuffer;
      81         245 :     const sal_Unicode* pcStr = rValue.getStr();
      82         245 :     const sal_Unicode* pcEnd = pcStr + rValue.getLength();
      83        2333 :     while( pcStr < pcEnd )
      84        1843 :         aBuffer.append( lclGetXChar( pcStr, pcEnd ) );
      85         245 :     return aBuffer.makeStringAndClear();
      86             : }
      87             : 
      88         853 : double AttributeConversion::decodeDouble( const OUString& rValue )
      89             : {
      90         853 :     return rValue.toDouble();
      91             : }
      92             : 
      93        6396 : sal_Int32 AttributeConversion::decodeInteger( const OUString& rValue )
      94             : {
      95        6396 :     return rValue.toInt32();
      96             : }
      97             : 
      98          36 : sal_uInt32 AttributeConversion::decodeUnsigned( const OUString& rValue )
      99             : {
     100          36 :     return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64(), 0, SAL_MAX_UINT32 );
     101             : }
     102             : 
     103           0 : sal_Int64 AttributeConversion::decodeHyper( const OUString& rValue )
     104             : {
     105           0 :     return rValue.toInt64();
     106             : }
     107             : 
     108         527 : sal_Int32 AttributeConversion::decodeIntegerHex( const OUString& rValue )
     109             : {
     110             :     // It looks like all Office Open XML attributes containing hexadecimal
     111             :     // values are based on xsd:hexBinary and so use an unsigned representation:
     112         527 :     return static_cast< sal_Int32 >(rValue.toUInt32( 16 ));
     113             :         //TODO: Change this function to return sal_uInt32 and get rid of the
     114             :         // cast, but that will have a ripple effect
     115             : }
     116             : 
     117             : // ============================================================================
     118             : 
     119       36377 : AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) :
     120       36377 :     mxAttribs( rxAttribs )
     121             : {
     122             :     OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" );
     123       36377 : }
     124             : 
     125        8822 : bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const
     126             : {
     127        8822 :     return mxAttribs->hasAttribute( nAttrToken );
     128             : }
     129             : 
     130             : // optional return values -----------------------------------------------------
     131             : 
     132         941 : OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const
     133             : {
     134         941 :     sal_Int32 nToken = mxAttribs->getOptionalValueToken( nAttrToken, XML_TOKEN_INVALID );
     135         941 :     return OptValue< sal_Int32 >( nToken != XML_TOKEN_INVALID, nToken );
     136             : }
     137             : 
     138        5093 : OptValue< OUString > AttributeList::getString( sal_Int32 nAttrToken ) const
     139             : {
     140             :     // check if the attribute exists (empty string may be different to missing attribute)
     141        5093 :     if( mxAttribs->hasAttribute( nAttrToken ) )
     142        3553 :         return OptValue< OUString >( mxAttribs->getOptionalValue( nAttrToken ) );
     143        1540 :     return OptValue< OUString >();
     144             : }
     145             : 
     146         498 : OptValue< OUString > AttributeList::getXString( sal_Int32 nAttrToken ) const
     147             : {
     148             :     // check if the attribute exists (empty string may be different to missing attribute)
     149         498 :     if( mxAttribs->hasAttribute( nAttrToken ) )
     150         444 :         return OptValue< OUString >( AttributeConversion::decodeXString( mxAttribs->getOptionalValue( nAttrToken ) ) );
     151          54 :     return OptValue< OUString >();
     152             : }
     153             : 
     154         991 : OptValue< double > AttributeList::getDouble( sal_Int32 nAttrToken ) const
     155             : {
     156         991 :     OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
     157         991 :     bool bValid = !aValue.isEmpty();
     158         991 :     return OptValue< double >( bValid, bValid ? AttributeConversion::decodeDouble( aValue ) : 0.0 );
     159             : }
     160             : 
     161       15101 : OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nAttrToken ) const
     162             : {
     163       15101 :     OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
     164       15101 :     bool bValid = !aValue.isEmpty();
     165       15101 :     return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeInteger( aValue ) : 0 );
     166             : }
     167             : 
     168          36 : OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nAttrToken ) const
     169             : {
     170          36 :     OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
     171          36 :     bool bValid = !aValue.isEmpty();
     172          36 :     return OptValue< sal_uInt32 >( bValid, AttributeConversion::decodeUnsigned( aValue ) );
     173             : }
     174             : 
     175           0 : OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const
     176             : {
     177           0 :     OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
     178           0 :     bool bValid = !aValue.isEmpty();
     179           0 :     return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyper( aValue ) : 0 );
     180             : }
     181             : 
     182         527 : OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nAttrToken ) const
     183             : {
     184         527 :     OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
     185         527 :     bool bValid = !aValue.isEmpty();
     186         527 :     return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeIntegerHex( aValue ) : 0 );
     187             : }
     188             : 
     189        8482 : OptValue< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const
     190             : {
     191             :     // boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0"
     192        8482 :     switch( getToken( nAttrToken, XML_TOKEN_INVALID ) )
     193             :     {
     194           0 :         case XML_t:     return OptValue< bool >( true );  // used in VML
     195         596 :         case XML_true:  return OptValue< bool >( true );
     196           0 :         case XML_on:    return OptValue< bool >( true );
     197           0 :         case XML_f:     return OptValue< bool >( false ); // used in VML
     198        2089 :         case XML_false: return OptValue< bool >( false );
     199           0 :         case XML_off:   return OptValue< bool >( false );
     200             :     }
     201        5797 :     OptValue< sal_Int32 > onValue = getInteger( nAttrToken );
     202        5797 :     return OptValue< bool >( onValue.has(), onValue.get() != 0 );
     203             : }
     204             : 
     205           0 : OptValue< util::DateTime > AttributeList::getDateTime( sal_Int32 nAttrToken ) const
     206             : {
     207           0 :     OUString aValue = mxAttribs->getOptionalValue( nAttrToken );
     208           0 :     util::DateTime aDateTime;
     209           0 :     bool bValid = (aValue.getLength() == 19) && (aValue[ 4 ] == '-') && (aValue[ 7 ] == '-') &&
     210           0 :         (aValue[ 10 ] == 'T') && (aValue[ 13 ] == ':') && (aValue[ 16 ] == ':');
     211           0 :     if( bValid )
     212             :     {
     213           0 :         aDateTime.Year    = static_cast< sal_uInt16 >( aValue.copy( 0, 4 ).toInt32() );
     214           0 :         aDateTime.Month   = static_cast< sal_uInt16 >( aValue.copy( 5, 2 ).toInt32() );
     215           0 :         aDateTime.Day     = static_cast< sal_uInt16 >( aValue.copy( 8, 2 ).toInt32() );
     216           0 :         aDateTime.Hours   = static_cast< sal_uInt16 >( aValue.copy( 11, 2 ).toInt32() );
     217           0 :         aDateTime.Minutes = static_cast< sal_uInt16 >( aValue.copy( 14, 2 ).toInt32() );
     218           0 :         aDateTime.Seconds = static_cast< sal_uInt16 >( aValue.copy( 17, 2 ).toInt32() );
     219             :     }
     220           0 :     return OptValue< util::DateTime >( bValid, aDateTime );
     221             : }
     222             : 
     223             : // defaulted return values ----------------------------------------------------
     224             : 
     225       27343 : sal_Int32 AttributeList::getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
     226             : {
     227       27343 :     return mxAttribs->getOptionalValueToken( nAttrToken, nDefault );
     228             : }
     229             : 
     230        8793 : OUString AttributeList::getString( sal_Int32 nAttrToken, const OUString& rDefault ) const
     231             : {
     232             :     // try to avoid slow exception throw/catch if we can
     233        8793 :     if (rDefault.isEmpty())
     234        8762 :         return mxAttribs->getOptionalValue( nAttrToken );
     235             : 
     236             :     try
     237             :     {
     238          31 :         return mxAttribs->getValue( nAttrToken );
     239             :     }
     240          20 :     catch( Exception& )
     241             :     {
     242             :     }
     243          20 :     return rDefault;
     244             : }
     245             : 
     246         496 : OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const
     247             : {
     248         496 :     return getXString( nAttrToken ).get( rDefault );
     249             : }
     250             : 
     251         991 : double AttributeList::getDouble( sal_Int32 nAttrToken, double fDefault ) const
     252             : {
     253         991 :     return getDouble( nAttrToken ).get( fDefault );
     254             : }
     255             : 
     256        8557 : sal_Int32 AttributeList::getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
     257             : {
     258        8557 :     return getInteger( nAttrToken ).get( nDefault );
     259             : }
     260             : 
     261          36 : sal_uInt32 AttributeList::getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const
     262             : {
     263          36 :     return getUnsigned( nAttrToken ).get( nDefault );
     264             : }
     265             : 
     266           0 : sal_Int64 AttributeList::getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const
     267             : {
     268           0 :     return getHyper( nAttrToken ).get( nDefault );
     269             : }
     270             : 
     271         527 : sal_Int32 AttributeList::getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const
     272             : {
     273         527 :     return getIntegerHex( nAttrToken ).get( nDefault );
     274             : }
     275             : 
     276        8243 : bool AttributeList::getBool( sal_Int32 nAttrToken, bool bDefault ) const
     277             : {
     278        8243 :     return getBool( nAttrToken ).get( bDefault );
     279             : }
     280             : 
     281           0 : util::DateTime AttributeList::getDateTime( sal_Int32 nAttrToken, const util::DateTime& rDefault ) const
     282             : {
     283           0 :     return getDateTime( nAttrToken ).get( rDefault );
     284             : }
     285             : 
     286             : // ============================================================================
     287             : 
     288             : } // namespace oox
     289             : 
     290             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10