LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/xmloff/source/transform - TransformerBase.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 432 710 60.8 %
Date: 2013-07-09 Functions: 31 39 79.5 %
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 <rtl/ref.hxx>
      21             : #include <rtl/ustrbuf.hxx>
      22             : #include <com/sun/star/i18n/CharacterClassification.hpp>
      23             : #include <com/sun/star/i18n/UnicodeType.hpp>
      24             : #include <com/sun/star/util/MeasureUnit.hpp>
      25             : #include <sax/tools/converter.hxx>
      26             : #include <comphelper/processfactory.hxx>
      27             : #include <xmloff/nmspmap.hxx>
      28             : #include "xmloff/xmlnmspe.hxx"
      29             : #include "IgnoreTContext.hxx"
      30             : #include "RenameElemTContext.hxx"
      31             : #include "ProcAttrTContext.hxx"
      32             : #include "ProcAddAttrTContext.hxx"
      33             : #include "MergeElemTContext.hxx"
      34             : #include "CreateElemTContext.hxx"
      35             : #include "MutableAttrList.hxx"
      36             : #include "TransformerActions.hxx"
      37             : #include "ElemTransformerAction.hxx"
      38             : #include "PropertyActionsOOo.hxx"
      39             : #include "TransformerTokenMap.hxx"
      40             : 
      41             : #include "TransformerBase.hxx"
      42             : #include "TContextVector.hxx"
      43             : 
      44             : using namespace ::osl;
      45             : using namespace ::xmloff::token;
      46             : using namespace ::com::sun::star;
      47             : using namespace ::com::sun::star::uno;
      48             : using namespace ::com::sun::star::beans;
      49             : using namespace ::com::sun::star::lang;
      50             : using namespace ::com::sun::star::i18n;
      51             : using namespace ::com::sun::star::xml::sax;
      52             : 
      53             : namespace
      54             : {
      55           6 : bool lcl_ConvertAttr( OUString & rOutAttribute, sal_Int32 nParam )
      56             : {
      57           6 :     bool bResult = false;
      58             :     enum XMLTokenEnum eTokenToRename =
      59           6 :         static_cast< enum XMLTokenEnum >( nParam & 0xffff );
      60          12 :     if( eTokenToRename != XML_TOKEN_INVALID &&
      61           6 :         IsXMLToken( rOutAttribute, eTokenToRename ))
      62             :     {
      63             :         enum XMLTokenEnum eReplacementToken =
      64           3 :             static_cast< enum XMLTokenEnum >( nParam >> 16 );
      65           3 :         rOutAttribute = GetXMLToken( eReplacementToken );
      66           3 :         bResult = true;
      67             :     }
      68           6 :     return bResult;
      69             : }
      70             : } // anonymous namespace
      71             : 
      72        7399 : XMLTransformerContext *XMLTransformerBase::CreateContext( sal_uInt16 nPrefix,
      73             :     const OUString& rLocalName, const OUString& rQName )
      74             : {
      75        7399 :     XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
      76             :     XMLTransformerActions::const_iterator aIter =
      77        7399 :         GetElemActions().find( aKey );
      78             : 
      79        7399 :     if( !(aIter == GetElemActions().end()) )
      80             :     {
      81        2250 :         sal_uInt32 nActionType = (*aIter).second.m_nActionType;
      82        2250 :         if( (nActionType & XML_ETACTION_USER_DEFINED) != 0 )
      83             :         {
      84             :             XMLTransformerContext *pContext =
      85        1300 :                 CreateUserDefinedContext( (*aIter).second,
      86        2600 :                                     rQName );
      87             :             OSL_ENSURE( pContext && !pContext->IsPersistent(),
      88             :                         "unknown or not persistent action" );
      89        1300 :             return pContext;
      90             :         }
      91             : 
      92         950 :         switch( nActionType )
      93             :         {
      94             :         case XML_ETACTION_COPY_CONTENT:
      95             :             return new XMLIgnoreTransformerContext( *this, rQName, sal_False,
      96           6 :                                                 sal_False );
      97             :         case XML_ETACTION_COPY:
      98           0 :             return new XMLTransformerContext( *this, rQName );
      99             :         case XML_ETACTION_RENAME_ELEM:
     100             :             return new XMLRenameElemTransformerContext( *this, rQName,
     101          56 :                     (*aIter).second.GetQNamePrefixFromParam1(),
     102          56 :                     (*aIter).second.GetQNameTokenFromParam1() );
     103             :         case XML_ETACTION_RENAME_ELEM_ADD_ATTR:
     104             :             return new XMLRenameElemTransformerContext( *this, rQName,
     105           0 :                     (*aIter).second.GetQNamePrefixFromParam1(),
     106           0 :                     (*aIter).second.GetQNameTokenFromParam1(),
     107           0 :                     (*aIter).second.GetQNamePrefixFromParam2(),
     108           0 :                     (*aIter).second.GetQNameTokenFromParam2(),
     109           0 :                        static_cast< XMLTokenEnum >( (*aIter).second.m_nParam3 ) );
     110             :         case XML_ETACTION_RENAME_ELEM_PROC_ATTRS:
     111             :             return new XMLProcAttrTransformerContext( *this, rQName,
     112         154 :                     (*aIter).second.GetQNamePrefixFromParam1(),
     113         154 :                     (*aIter).second.GetQNameTokenFromParam1(),
     114         308 :                        static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
     115             :         case XML_ETACTION_RENAME_ELEM_ADD_PROC_ATTR:
     116             :             return new XMLProcAddAttrTransformerContext( *this, rQName,
     117           8 :                     (*aIter).second.GetQNamePrefixFromParam1(),
     118           8 :                     (*aIter).second.GetQNameTokenFromParam1(),
     119             :                        static_cast< sal_uInt16 >(
     120           8 :                         (*aIter).second.m_nParam3  >> 16 ),
     121           8 :                     (*aIter).second.GetQNamePrefixFromParam2(),
     122           8 :                     (*aIter).second.GetQNameTokenFromParam2(),
     123             :                        static_cast< XMLTokenEnum >(
     124          40 :                         (*aIter).second.m_nParam3 & 0xffff ) );
     125             :         case XML_ETACTION_RENAME_ELEM_COND:
     126             :             {
     127           0 :                 const XMLTransformerContext *pCurrent = GetCurrentContext();
     128           0 :                 if( pCurrent->HasQName(
     129           0 :                             (*aIter).second.GetQNamePrefixFromParam2(),
     130           0 :                             (*aIter).second.GetQNameTokenFromParam2() ) )
     131             :                     return new XMLRenameElemTransformerContext( *this, rQName,
     132           0 :                             (*aIter).second.GetQNamePrefixFromParam1(),
     133           0 :                             (*aIter).second.GetQNameTokenFromParam1() );
     134             :             }
     135           0 :             break;
     136             :         case XML_ETACTION_RENAME_ELEM_PROC_ATTRS_COND:
     137             :             {
     138           0 :                 const XMLTransformerContext *pCurrent = GetCurrentContext();
     139           0 :                 if( pCurrent->HasQName(
     140           0 :                             (*aIter).second.GetQNamePrefixFromParam3(),
     141           0 :                             (*aIter).second.GetQNameTokenFromParam3() ) )
     142             :                     return new XMLProcAttrTransformerContext( *this, rQName,
     143           0 :                             (*aIter).second.GetQNamePrefixFromParam1(),
     144           0 :                             (*aIter).second.GetQNameTokenFromParam1(),
     145           0 :                             static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
     146             :                 else
     147             :                     return new XMLProcAttrTransformerContext( *this, rQName,
     148           0 :                             static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
     149             :             }
     150             :         case XML_ETACTION_PROC_ATTRS:
     151             :             return new XMLProcAttrTransformerContext( *this, rQName,
     152         699 :                        static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
     153             :         case XML_ETACTION_PROC_ATTRS_COND:
     154             :             {
     155          22 :                 const XMLTransformerContext *pCurrent = GetCurrentContext();
     156          22 :                 if( pCurrent->HasQName(
     157          22 :                             (*aIter).second.GetQNamePrefixFromParam1(),
     158          44 :                             (*aIter).second.GetQNameTokenFromParam1() ) )
     159             :                     return new XMLProcAttrTransformerContext( *this, rQName,
     160          22 :                             static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
     161             :             }
     162           0 :             break;
     163             :         case XML_ETACTION_MOVE_ATTRS_TO_ELEMS:
     164             :             return new XMLCreateElemTransformerContext( *this, rQName,
     165           5 :                        static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
     166             :         case XML_ETACTION_MOVE_ELEMS_TO_ATTRS:
     167             :             return new XMLMergeElemTransformerContext( *this, rQName,
     168           0 :                        static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
     169             :         default:
     170             :             OSL_ENSURE( !this, "unknown action" );
     171           0 :             break;
     172             :         }
     173             :     }
     174             : 
     175             :     // default is copying
     176        5149 :     return new XMLTransformerContext( *this, rQName );
     177             : }
     178             : 
     179           0 : XMLTransformerActions *XMLTransformerBase::GetUserDefinedActions( sal_uInt16 )
     180             : {
     181           0 :     return 0;
     182             : }
     183             : 
     184          98 : XMLTransformerBase::XMLTransformerBase( XMLTransformerActionInit *pInit,
     185             :                                     ::xmloff::token::XMLTokenEnum *pTKMapInit )
     186             :     throw () :
     187          98 :     m_pNamespaceMap( new SvXMLNamespaceMap ),
     188          98 :     m_pReplaceNamespaceMap( new SvXMLNamespaceMap ),
     189          98 :     m_pContexts( new XMLTransformerContextVector ),
     190          98 :     m_pElemActions( new XMLTransformerActions( pInit ) ),
     191         490 :     m_pTokenMap( new XMLTransformerTokenMap( pTKMapInit ) )
     192             : {
     193          98 :     GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
     194          98 :     GetNamespaceMap().Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
     195          98 :     GetNamespaceMap().Add( GetXMLToken(XML_NP_MATH), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
     196          98 :     GetNamespaceMap().Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
     197          98 :     GetNamespaceMap().Add( GetXMLToken(XML_NP_DOM), GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
     198          98 :     GetNamespaceMap().Add( GetXMLToken(XML_NP_OOOW), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
     199          98 :     GetNamespaceMap().Add( GetXMLToken(XML_NP_OOOC), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
     200          98 : }
     201             : 
     202         196 : XMLTransformerBase::~XMLTransformerBase() throw ()
     203             : {
     204          98 :     ResetTokens();
     205             : 
     206          98 :     delete m_pNamespaceMap;
     207          98 :     delete m_pReplaceNamespaceMap;
     208          98 :     delete m_pContexts;
     209          98 :     delete m_pElemActions;
     210          98 :     delete m_pTokenMap;
     211          98 : }
     212             : 
     213          77 : void SAL_CALL XMLTransformerBase::startDocument( void )
     214             :     throw( SAXException, RuntimeException )
     215             : {
     216          77 :     m_xHandler->startDocument();
     217          77 : }
     218             : 
     219          77 : void SAL_CALL XMLTransformerBase::endDocument( void )
     220             :     throw( SAXException, RuntimeException)
     221             : {
     222          77 :     m_xHandler->endDocument();
     223          77 : }
     224             : 
     225        8506 : void SAL_CALL XMLTransformerBase::startElement( const OUString& rName,
     226             :                                          const Reference< XAttributeList >& rAttrList )
     227             :     throw(SAXException, RuntimeException)
     228             : {
     229        8506 :     SvXMLNamespaceMap *pRewindMap = 0;
     230             : 
     231        8506 :     bool bRect = rName == "presentation:show-shape";
     232             :     (void)bRect;
     233             : 
     234             :     // Process namespace attributes. This must happen before creating the
     235             :     // context, because namespace decaration apply to the element name itself.
     236        8506 :     XMLMutableAttributeList *pMutableAttrList = 0;
     237        8506 :     Reference< XAttributeList > xAttrList( rAttrList );
     238        8506 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     239       24573 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     240             :     {
     241       16067 :         const OUString& rAttrName = xAttrList->getNameByIndex( i );
     242       48201 :         if( ( rAttrName.getLength() >= 5 ) &&
     243       18409 :             ( rAttrName.startsWith( GetXMLToken(XML_XMLNS) ) ) &&
     244        2342 :             ( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) )
     245             :         {
     246        1171 :             if( !pRewindMap )
     247             :             {
     248          78 :                 pRewindMap = m_pNamespaceMap;
     249          78 :                 m_pNamespaceMap = new SvXMLNamespaceMap( *m_pNamespaceMap );
     250             :             }
     251        1171 :             const OUString& rAttrValue = xAttrList->getValueByIndex( i );
     252             : 
     253        1171 :             OUString aPrefix( ( rAttrName.getLength() == 5 )
     254             :                                  ? OUString()
     255        2342 :                                  : rAttrName.copy( 6 ) );
     256             :             // Add namespace, but only if it is known.
     257        1171 :             sal_uInt16 nKey = m_pNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
     258             :             // If namespace is unknown, try to match a name with similar
     259             :             // TC Id an version
     260        1171 :             if( XML_NAMESPACE_UNKNOWN == nKey  )
     261             :             {
     262         307 :                 OUString aTestName( rAttrValue );
     263         307 :                 if( SvXMLNamespaceMap::NormalizeOasisURN( aTestName ) )
     264          57 :                     nKey = m_pNamespaceMap->AddIfKnown( aPrefix, aTestName );
     265             :             }
     266             :             // If that namespace is not known, too, add it as unknown
     267        1171 :             if( XML_NAMESPACE_UNKNOWN == nKey  )
     268         307 :                 nKey = m_pNamespaceMap->Add( aPrefix, rAttrValue );
     269             : 
     270        1171 :             const OUString& rRepName = m_pReplaceNamespaceMap->GetNameByKey( nKey );
     271        1171 :             if( !rRepName.isEmpty() )
     272             :             {
     273         594 :                 if( !pMutableAttrList )
     274             :                 {
     275          75 :                     pMutableAttrList = new XMLMutableAttributeList( xAttrList );
     276          75 :                     xAttrList = pMutableAttrList;
     277             :                 }
     278             : 
     279         594 :                 pMutableAttrList->SetValueByIndex( i, rRepName );
     280        1171 :             }
     281             :         }
     282       16067 :     }
     283             : 
     284             :     // Get element's namespace and local name.
     285       17012 :     OUString aLocalName;
     286             :     sal_uInt16 nPrefix =
     287        8506 :         m_pNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
     288             : 
     289             :     // If there are contexts already, call a CreateChildContext at the topmost
     290             :     // context. Otherwise, create a default context.
     291       17012 :     ::rtl::Reference < XMLTransformerContext > xContext;
     292        8506 :     if( !m_pContexts->empty() )
     293             :     {
     294       16858 :         xContext = m_pContexts->back()->CreateChildContext( nPrefix,
     295             :                                                           aLocalName,
     296             :                                                           rName,
     297       16858 :                                                           xAttrList );
     298             :     }
     299             :     else
     300             :     {
     301          77 :         xContext = CreateContext( nPrefix, aLocalName, rName );
     302             :     }
     303             : 
     304             :     OSL_ENSURE( xContext.is(), "XMLTransformerBase::startElement: missing context" );
     305        8506 :     if( !xContext.is() )
     306           0 :         xContext = new XMLTransformerContext( *this, rName );
     307             : 
     308             :     // Remember old namespace map.
     309        8506 :     if( pRewindMap )
     310          78 :         xContext->SetRewindMap( pRewindMap );
     311             : 
     312             :     // Push context on stack.
     313        8506 :     m_pContexts->push_back( xContext );
     314             : 
     315             :     // Call a startElement at the new context.
     316       17012 :     xContext->StartElement( xAttrList );
     317        8506 : }
     318             : 
     319        8506 : void SAL_CALL XMLTransformerBase::endElement( const OUString&
     320             : #if OSL_DEBUG_LEVEL > 0
     321             : rName
     322             : #endif
     323             : )
     324             :     throw(SAXException, RuntimeException)
     325             : {
     326        8506 :     if( !m_pContexts->empty() )
     327             :     {
     328             :         // Get topmost context
     329        8506 :         ::rtl::Reference< XMLTransformerContext > xContext = m_pContexts->back();
     330             : 
     331             : #if OSL_DEBUG_LEVEL > 0
     332             :         OSL_ENSURE( xContext->GetQName() == rName,
     333             :                 "XMLTransformerBase::endElement: popped context has wrong lname" );
     334             : #endif
     335             : 
     336             :         // Call a EndElement at the current context.
     337        8506 :         xContext->EndElement();
     338             : 
     339             :         // and remove it from the stack.
     340        8506 :         m_pContexts->pop_back();
     341             : 
     342             :         // Get a namespace map to rewind.
     343        8506 :         SvXMLNamespaceMap *pRewindMap = xContext->GetRewindMap();
     344             : 
     345             :         // Delete the current context.
     346        8506 :         xContext = 0;
     347             : 
     348             :         // Rewind a namespace map.
     349        8506 :         if( pRewindMap )
     350             :         {
     351          78 :             delete m_pNamespaceMap;
     352          78 :             m_pNamespaceMap = pRewindMap;
     353        8506 :         }
     354             :     }
     355        8506 : }
     356             : 
     357        5446 : void SAL_CALL XMLTransformerBase::characters( const OUString& rChars )
     358             :     throw(SAXException, RuntimeException)
     359             : {
     360        5446 :     if( !m_pContexts->empty() )
     361             :     {
     362        5371 :         m_pContexts->back()->Characters( rChars );
     363             :     }
     364        5446 : }
     365             : 
     366           6 : void SAL_CALL XMLTransformerBase::ignorableWhitespace( const OUString& rWhitespaces )
     367             :     throw(SAXException, RuntimeException)
     368             : {
     369           6 :     m_xHandler->ignorableWhitespace( rWhitespaces );
     370           6 : }
     371             : 
     372           0 : void SAL_CALL XMLTransformerBase::processingInstruction( const OUString& rTarget,
     373             :                                        const OUString& rData )
     374             :     throw(SAXException, RuntimeException)
     375             : {
     376           0 :     m_xHandler->processingInstruction( rTarget, rData );
     377           0 : }
     378             : 
     379          54 : void SAL_CALL XMLTransformerBase::setDocumentLocator( const Reference< XLocator >& rLocator )
     380             :     throw(SAXException, RuntimeException)
     381             : {
     382          54 :     m_xLocator = rLocator;
     383          54 : }
     384             : 
     385             : // XExtendedDocumentHandler
     386           0 : void SAL_CALL XMLTransformerBase::startCDATA( void ) throw(SAXException, RuntimeException)
     387             : {
     388           0 :     if( m_xExtHandler.is() )
     389           0 :         m_xExtHandler->startCDATA();
     390           0 : }
     391             : 
     392           0 : void SAL_CALL XMLTransformerBase::endCDATA( void ) throw(RuntimeException)
     393             : {
     394           0 :     if( m_xExtHandler.is() )
     395           0 :         m_xExtHandler->endCDATA();
     396           0 : }
     397             : 
     398          10 : void SAL_CALL XMLTransformerBase::comment( const OUString& rComment )
     399             :     throw(SAXException, RuntimeException)
     400             : {
     401          10 :     if( m_xExtHandler.is() )
     402           0 :         m_xExtHandler->comment( rComment );
     403          10 : }
     404             : 
     405           0 : void SAL_CALL XMLTransformerBase::allowLineBreak( void )
     406             :     throw(SAXException, RuntimeException)
     407             : {
     408           0 :     if( m_xExtHandler.is() )
     409           0 :         m_xExtHandler->allowLineBreak();
     410           0 : }
     411             : 
     412         337 : void SAL_CALL XMLTransformerBase::unknown( const OUString& rString )
     413             :     throw(SAXException, RuntimeException)
     414             : {
     415         337 :     if( m_xExtHandler.is() )
     416           0 :         m_xExtHandler->unknown( rString );
     417         337 : }
     418             : 
     419             : // XInitialize
     420         101 : void SAL_CALL XMLTransformerBase::initialize( const Sequence< Any >& aArguments )
     421             :     throw(Exception, RuntimeException)
     422             : {
     423         101 :     const sal_Int32 nAnyCount = aArguments.getLength();
     424         101 :     const Any* pAny = aArguments.getConstArray();
     425             : 
     426         408 :     for( sal_Int32 nIndex = 0; nIndex < nAnyCount; nIndex++, pAny++ )
     427             :     {
     428             :         // use isAssignableFrom instead of comparing the types to
     429             :         // allow XExtendedDocumentHandler instead of XDocumentHandler (used in
     430             :         // writeOasis2OOoLibraryElement in sfx2).
     431             :         // The Any shift operator can't be used to query the type because it
     432             :         // uses queryInterface, and the model also has a XPropertySet interface.
     433             : 
     434             :         // document handler
     435         307 :         if( ::getCppuType( (const Reference< XDocumentHandler >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
     436         101 :             m_xHandler.set( *pAny, UNO_QUERY );
     437             : 
     438             :         // property set to transport data across
     439         307 :         if( ::getCppuType( (const Reference< XPropertySet >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
     440          74 :             m_xPropSet.set( *pAny, UNO_QUERY );
     441             : 
     442             :         // xmodel
     443         307 :         if( ::getCppuType( (const Reference< ::com::sun::star::frame::XModel >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
     444          22 :             mxModel.set( *pAny, UNO_QUERY );
     445             :     }
     446             : 
     447         101 :     if( m_xPropSet.is() )
     448             :     {
     449          74 :         Any aAny;
     450         148 :         OUString sRelPath, sName;
     451             :         Reference< XPropertySetInfo > xPropSetInfo =
     452         148 :             m_xPropSet->getPropertySetInfo();
     453         148 :         OUString sPropName( "StreamRelPath"  );
     454          74 :         if( xPropSetInfo->hasPropertyByName(sPropName) )
     455             :         {
     456          72 :             aAny = m_xPropSet->getPropertyValue(sPropName);
     457          72 :             aAny >>= sRelPath;
     458             :         }
     459          74 :         sPropName = OUString( "StreamName"  );
     460          74 :         if( xPropSetInfo->hasPropertyByName(sPropName) )
     461             :         {
     462          72 :             aAny = m_xPropSet->getPropertyValue(sPropName);
     463          72 :             aAny >>= sName;
     464             :         }
     465          74 :         if( !sName.isEmpty() )
     466             :         {
     467          72 :             m_aExtPathPrefix = OUString( "../"  );
     468             : 
     469             :             // If there is a rel path within a package, then append
     470             :             // additional '../'. If the rel path contains an ':', then it is
     471             :             // an absolute URI (or invalid URI, because zip files don't
     472             :             // permit ':'), and it will be ignored.
     473          72 :             if( !sRelPath.isEmpty() )
     474             :             {
     475           0 :                 sal_Int32 nColPos = sRelPath.indexOf( ':' );
     476             :                 OSL_ENSURE( -1 == nColPos,
     477             :                             "StreamRelPath contains ':', absolute URI?" );
     478             : 
     479           0 :                 if( -1 == nColPos )
     480             :                 {
     481           0 :                     OUString sTmp = m_aExtPathPrefix;
     482           0 :                     sal_Int32 nPos = 0;
     483           0 :                     do
     484             :                     {
     485           0 :                         m_aExtPathPrefix += sTmp;
     486           0 :                         nPos = sRelPath.indexOf( '/', nPos + 1 );
     487             :                     }
     488           0 :                     while( -1 != nPos );
     489             :                 }
     490             :             }
     491             : 
     492          74 :         }
     493             :     }
     494         101 : }
     495             : 
     496         190 : static sal_Int16 lcl_getUnit( const OUString& rValue )
     497             : {
     498         190 :     if( rValue.endsWithIgnoreAsciiCase( "cm" ) )
     499         190 :         return util::MeasureUnit::CM;
     500           0 :     else if ( rValue.endsWithIgnoreAsciiCase( "mm" ) )
     501           0 :         return util::MeasureUnit::MM;
     502             :     else
     503           0 :         return util::MeasureUnit::INCH;
     504             : }
     505             : 
     506         974 : XMLMutableAttributeList *XMLTransformerBase::ProcessAttrList(
     507             :         Reference< XAttributeList >& rAttrList, sal_uInt16 nActionMap,
     508             :            sal_Bool bClone  )
     509             : {
     510         974 :     XMLMutableAttributeList *pMutableAttrList = 0;
     511         974 :     XMLTransformerActions *pActions = GetUserDefinedActions( nActionMap );
     512             :     OSL_ENSURE( pActions, "go no actions" );
     513         974 :     if( pActions )
     514             :     {
     515         974 :         sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
     516        3309 :         for( sal_Int16 i=0; i < nAttrCount; ++i )
     517             :         {
     518        2335 :             const OUString& rAttrName = rAttrList->getNameByIndex( i );
     519        4670 :             const OUString& rAttrValue = rAttrList->getValueByIndex( i );
     520        4670 :             OUString aLocalName;
     521        2335 :             sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName( rAttrName,
     522        2335 :                                                            &aLocalName );
     523             : 
     524        4670 :             XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
     525             :             XMLTransformerActions::const_iterator aIter =
     526        2335 :                     pActions->find( aKey );
     527        2335 :             if( !(aIter == pActions->end() ) )
     528             :             {
     529        1222 :                 if( !pMutableAttrList )
     530             :                 {
     531             :                     pMutableAttrList = new XMLMutableAttributeList( rAttrList,
     532         651 :                                                                     bClone );
     533         651 :                     rAttrList = pMutableAttrList;
     534             :                 }
     535             : 
     536        1222 :                 sal_uInt32 nAction = (*aIter).second.m_nActionType;
     537        1222 :                 sal_Bool bRename = sal_False;
     538        1222 :                 switch( nAction )
     539             :                 {
     540             :                 case XML_ATACTION_RENAME:
     541         304 :                     bRename = sal_True;
     542         304 :                     break;
     543             :                 case XML_ATACTION_COPY:
     544           0 :                     break;
     545             :                 case XML_ATACTION_REMOVE:
     546             :                 case XML_ATACTION_STYLE_DISPLAY_NAME:
     547           0 :                     pMutableAttrList->RemoveAttributeByIndex( i );
     548           0 :                     --i;
     549           0 :                     --nAttrCount;
     550           0 :                     break;
     551             :                 case XML_ATACTION_RENAME_IN2INCH:
     552           0 :                     bRename = sal_True;
     553             :                 case XML_ATACTION_IN2INCH:
     554             :                     {
     555          52 :                         OUString aAttrValue( rAttrValue );
     556          52 :                         if( ReplaceSingleInWithInch( aAttrValue ) )
     557           8 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     558             :                     }
     559          52 :                     break;
     560             :                 case XML_ATACTION_INS2INCHS:
     561             :                     {
     562           0 :                         OUString aAttrValue( rAttrValue );
     563           0 :                         if( ReplaceInWithInch( aAttrValue ) )
     564           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     565             :                     }
     566           0 :                     break;
     567             :                 case XML_ATACTION_RENAME_INCH2IN:
     568           0 :                     bRename = sal_True;
     569             :                 case XML_ATACTION_INCH2IN:
     570             :                     {
     571         203 :                         OUString aAttrValue( rAttrValue );
     572         203 :                         if( ReplaceSingleInchWithIn( aAttrValue ) )
     573           8 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     574             :                     }
     575         203 :                     break;
     576             :                 case XML_ATACTION_INCHS2INS:
     577             :                     {
     578           0 :                         OUString aAttrValue( rAttrValue );
     579           0 :                         if( ReplaceInchWithIn( aAttrValue ) )
     580           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     581             :                     }
     582           0 :                     break;
     583             :                 case XML_ATACTION_TWIPS2IN:
     584             :                     {
     585           0 :                         OUString aAttrValue( rAttrValue );
     586             : 
     587           0 :                         XMLTransformerBase::ReplaceSingleInchWithIn( aAttrValue );
     588           0 :                         if( isWriter() )
     589             :                         {
     590           0 :                             sal_Int16 const nDestUnit = lcl_getUnit(aAttrValue);
     591             : 
     592             :                             // convert twips value to inch
     593             :                             sal_Int32 nMeasure;
     594           0 :                             if (::sax::Converter::convertMeasure(nMeasure,
     595             :                                     aAttrValue, util::MeasureUnit::MM_100TH))
     596             :                             {
     597             : 
     598             :                                 // #i13778#,#i36248# apply correct twip-to-1/100mm
     599           0 :                                 nMeasure = (sal_Int32)( nMeasure >= 0
     600           0 :                                                         ? ((nMeasure*127+36)/72)
     601           0 :                                                         : ((nMeasure*127-36)/72) );
     602             : 
     603           0 :                                 OUStringBuffer aBuffer;
     604             :                                 ::sax::Converter::convertMeasure(aBuffer,
     605             :                                         nMeasure, util::MeasureUnit::MM_100TH,
     606           0 :                                         nDestUnit );
     607           0 :                                 aAttrValue = aBuffer.makeStringAndClear();
     608             :                             }
     609             :                         }
     610             : 
     611           0 :                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
     612             :                     }
     613           0 :                     break;
     614             :                 case XML_ATACTION_RENAME_DECODE_STYLE_NAME_REF:
     615           0 :                     bRename = sal_True;
     616             :                 case XML_ATACTION_DECODE_STYLE_NAME:
     617             :                 case XML_ATACTION_DECODE_STYLE_NAME_REF:
     618             :                     {
     619          60 :                         OUString aAttrValue( rAttrValue );
     620          60 :                         if( DecodeStyleName(aAttrValue) )
     621           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     622             :                     }
     623          60 :                     break;
     624             :                 case XML_ATACTION_ENCODE_STYLE_NAME:
     625             :                     {
     626          22 :                         OUString aAttrValue( rAttrValue );
     627          22 :                         if( EncodeStyleName(aAttrValue) )
     628             :                         {
     629           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     630             :                             OUString aNewAttrQName(
     631           0 :                                 GetNamespaceMap().GetQNameByKey(
     632             :                                     nPrefix,
     633             :                                 ::xmloff::token::GetXMLToken(
     634           0 :                                 XML_DISPLAY_NAME ) ) );
     635             :                             pMutableAttrList->AddAttribute( aNewAttrQName,
     636           0 :                                                             rAttrValue );
     637          22 :                         }
     638             :                     }
     639          22 :                     break;
     640             :                 case XML_ATACTION_RENAME_ENCODE_STYLE_NAME_REF:
     641          20 :                     bRename = sal_True;
     642             :                 case XML_ATACTION_ENCODE_STYLE_NAME_REF:
     643             :                     {
     644         304 :                         OUString aAttrValue( rAttrValue );
     645         304 :                         if( EncodeStyleName(aAttrValue) )
     646           2 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     647             :                     }
     648         304 :                     break;
     649             :                 case XML_ATACTION_RENAME_NEG_PERCENT:
     650           0 :                     bRename = sal_True;
     651             :                 case XML_ATACTION_NEG_PERCENT:
     652             :                     {
     653           0 :                         OUString aAttrValue( rAttrValue );
     654           0 :                         if( NegPercent( aAttrValue ) )
     655           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     656             :                     }
     657           0 :                     break;
     658             :                 case XML_ATACTION_RENAME_ADD_NAMESPACE_PREFIX:
     659          29 :                     bRename = sal_True;
     660             :                 case XML_ATACTION_ADD_NAMESPACE_PREFIX:
     661             :                     {
     662          51 :                         OUString aAttrValue( rAttrValue );
     663             :                         sal_uInt16 nValPrefix =
     664             :                             static_cast<sal_uInt16>(
     665          29 :                                     bRename ? (*aIter).second.m_nParam2
     666          80 :                                             : (*aIter).second.m_nParam1);
     667          51 :                         if( AddNamespacePrefix( aAttrValue, nValPrefix ) )
     668          51 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     669             :                     }
     670          51 :                     break;
     671             :                 case XML_ATACTION_ADD_APP_NAMESPACE_PREFIX:
     672             :                     {
     673           0 :                         OUString aAttrValue( rAttrValue );
     674             :                         sal_uInt16 nValPrefix =
     675           0 :                             static_cast<sal_uInt16>((*aIter).second.m_nParam1);
     676           0 :                         if( IsXMLToken( GetClass(), XML_SPREADSHEET  ) )
     677           0 :                             nValPrefix = XML_NAMESPACE_OOOC;
     678           0 :                         else if( IsXMLToken( GetClass(), XML_TEXT  ) )
     679           0 :                             nValPrefix = XML_NAMESPACE_OOOW;
     680           0 :                         if( AddNamespacePrefix( aAttrValue, nValPrefix ) )
     681           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     682             :                     }
     683           0 :                     break;
     684             :                 case XML_ATACTION_RENAME_REMOVE_NAMESPACE_PREFIX:
     685           0 :                     bRename = sal_True;
     686             :                 case XML_ATACTION_REMOVE_NAMESPACE_PREFIX:
     687             :                     {
     688          13 :                         OUString aAttrValue( rAttrValue );
     689             :                         sal_uInt16 nValPrefix =
     690             :                             static_cast<sal_uInt16>(
     691           0 :                                     bRename ? (*aIter).second.m_nParam2
     692          13 :                                             : (*aIter).second.m_nParam1);
     693          13 :                         if( RemoveNamespacePrefix( aAttrValue, nValPrefix ) )
     694          13 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     695             :                     }
     696          13 :                     break;
     697             :                 case XML_ATACTION_REMOVE_ANY_NAMESPACE_PREFIX:
     698             :                     {
     699           0 :                         OUString aAttrValue( rAttrValue );
     700           0 :                         if( RemoveNamespacePrefix( aAttrValue ) )
     701           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     702             :                     }
     703           0 :                     break;
     704             :                 case XML_ATACTION_URI_OOO:
     705             :                     {
     706          19 :                         OUString aAttrValue( rAttrValue );
     707          19 :                         if( ConvertURIToOASIS( aAttrValue,
     708          19 :                             static_cast< sal_Bool >((*aIter).second.m_nParam1)))
     709           5 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     710             :                     }
     711          19 :                     break;
     712             :                 case XML_ATACTION_URI_OASIS:
     713             :                     {
     714           0 :                         OUString aAttrValue( rAttrValue );
     715           0 :                         if( ConvertURIToOOo( aAttrValue,
     716           0 :                             static_cast< sal_Bool >((*aIter).second.m_nParam1)))
     717           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     718             :                     }
     719           0 :                     break;
     720             :                 case XML_ATACTION_RENAME_ATTRIBUTE:
     721             :                     {
     722           3 :                         OUString aAttrValue( rAttrValue );
     723             :                         RenameAttributeValue(
     724             :                             aAttrValue,
     725           3 :                             (*aIter).second.m_nParam1,
     726           3 :                             (*aIter).second.m_nParam2,
     727           9 :                             (*aIter).second.m_nParam3 );
     728           3 :                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
     729             :                     }
     730           3 :                     break;
     731             :                 case XML_ATACTION_RNG2ISO_DATETIME:
     732             :                     {
     733           1 :                         OUString aAttrValue( rAttrValue );
     734           1 :                         if( ConvertRNGDateTimeToISO( aAttrValue ))
     735           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     736             :                     }
     737           1 :                     break;
     738             :                 case XML_ATACTION_RENAME_RNG2ISO_DATETIME:
     739             :                     {
     740           0 :                         OUString aAttrValue( rAttrValue );
     741           0 :                         if( ConvertRNGDateTimeToISO( aAttrValue ))
     742           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     743           0 :                         bRename = sal_True;
     744             :                     }
     745           0 :                     break;
     746             :                 case XML_ATACTION_IN2TWIPS:
     747             :                     {
     748           0 :                         OUString aAttrValue( rAttrValue );
     749           0 :                         XMLTransformerBase::ReplaceSingleInWithInch( aAttrValue );
     750             : 
     751           0 :                         if( isWriter() )
     752             :                         {
     753           0 :                             sal_Int16 const nDestUnit = lcl_getUnit(aAttrValue);
     754             : 
     755             :                             // convert inch value to twips and export as faked inch
     756             :                             sal_Int32 nMeasure;
     757           0 :                             if (::sax::Converter::convertMeasure(nMeasure,
     758             :                                     aAttrValue, util::MeasureUnit::MM_100TH))
     759             :                             {
     760             : 
     761             :                                 // #i13778#,#i36248#/ apply correct 1/100mm-to-twip conversion
     762           0 :                                 nMeasure = (sal_Int32)( nMeasure >= 0
     763           0 :                                                         ? ((nMeasure*72+63)/127)
     764           0 :                                                         : ((nMeasure*72-63)/127) );
     765             : 
     766           0 :                                 OUStringBuffer aBuffer;
     767             :                                 ::sax::Converter::convertMeasure( aBuffer,
     768             :                                         nMeasure, util::MeasureUnit::MM_100TH,
     769           0 :                                         nDestUnit );
     770           0 :                                 aAttrValue = aBuffer.makeStringAndClear();
     771             :                             }
     772             :                         }
     773             : 
     774           0 :                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
     775             :                     }
     776           0 :                     break;
     777             :                 case XML_ATACTION_SVG_WIDTH_HEIGHT_OOO:
     778             :                     {
     779         146 :                         OUString aAttrValue( rAttrValue );
     780         146 :                         ReplaceSingleInchWithIn( aAttrValue );
     781             : 
     782         146 :                         sal_Int16 const nDestUnit = lcl_getUnit( aAttrValue );
     783             : 
     784             :                         sal_Int32 nMeasure;
     785         146 :                         if (::sax::Converter::convertMeasure(nMeasure,
     786             :                                     aAttrValue, util::MeasureUnit::MM_100TH))
     787             :                         {
     788             : 
     789         146 :                             if( nMeasure > 0 )
     790         140 :                                 nMeasure -= 1;
     791           6 :                             else if( nMeasure < 0 )
     792           6 :                                 nMeasure += 1;
     793             : 
     794             : 
     795         146 :                             OUStringBuffer aBuffer;
     796             :                             ::sax::Converter::convertMeasure(aBuffer, nMeasure,
     797         146 :                                    util::MeasureUnit::MM_100TH, nDestUnit);
     798         146 :                             aAttrValue = aBuffer.makeStringAndClear();
     799             :                         }
     800             : 
     801         146 :                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
     802             :                     }
     803         146 :                     break;
     804             :                 case XML_ATACTION_SVG_WIDTH_HEIGHT_OASIS:
     805             :                     {
     806          44 :                         OUString aAttrValue( rAttrValue );
     807          44 :                         ReplaceSingleInWithInch( aAttrValue );
     808             : 
     809          44 :                         sal_Int16 const nDestUnit = lcl_getUnit( aAttrValue );
     810             : 
     811             :                         sal_Int32 nMeasure;
     812          44 :                         if (::sax::Converter::convertMeasure(nMeasure,
     813             :                                 aAttrValue, util::MeasureUnit::MM_100TH))
     814             :                         {
     815             : 
     816          44 :                             if( nMeasure > 0 )
     817          38 :                                 nMeasure += 1;
     818           6 :                             else if( nMeasure < 0 )
     819           6 :                                 nMeasure -= 1;
     820             : 
     821             : 
     822          44 :                             OUStringBuffer aBuffer;
     823             :                             ::sax::Converter::convertMeasure(aBuffer, nMeasure,
     824          44 :                                     util::MeasureUnit::MM_100TH, nDestUnit );
     825          44 :                             aAttrValue = aBuffer.makeStringAndClear();
     826             :                         }
     827             : 
     828          44 :                         pMutableAttrList->SetValueByIndex( i, aAttrValue );
     829             :                     }
     830          44 :                     break;
     831             :                 case XML_ATACTION_DECODE_ID:
     832             :                     {
     833           0 :                         const sal_Int32 nLen = rAttrValue.getLength();
     834           0 :                         OUStringBuffer aBuffer;
     835             : 
     836             :                         sal_Int32 pos;
     837           0 :                         for( pos = 0; pos < nLen; pos++ )
     838             :                         {
     839           0 :                             sal_Unicode c = rAttrValue[pos];
     840           0 :                             if( (c >= '0') && (c <= '9') )
     841           0 :                                 aBuffer.append( c );
     842             :                             else
     843           0 :                                 aBuffer.append( (sal_Int32)c );
     844             :                         }
     845             : 
     846           0 :                         pMutableAttrList->SetValueByIndex( i, aBuffer.makeStringAndClear() );
     847             :                     }
     848           0 :                     break;
     849             :                 // #i50322# - special handling for the
     850             :                 // transparency of writer background graphics.
     851             :                 case XML_ATACTION_WRITER_BACK_GRAPHIC_TRANSPARENCY:
     852             :                     {
     853             :                         // determine, if it's the transparency of a document style
     854           0 :                         XMLTransformerContext* pFirstContext = (*m_pContexts)[0].get();
     855           0 :                         OUString aFirstContextLocalName;
     856             :                         /* sal_uInt16 nFirstContextPrefix = */
     857           0 :                             GetNamespaceMap().GetKeyByAttrName( pFirstContext->GetQName(),
     858           0 :                                                                 &aFirstContextLocalName );
     859             :                         bool bIsDocumentStyle(
     860             :                             ::xmloff::token::IsXMLToken( aFirstContextLocalName,
     861           0 :                                                          XML_DOCUMENT_STYLES ) );
     862             :                         // no conversion of transparency value for document
     863             :                         // styles, because former OpenOffice.org version writes
     864             :                         // writes always a transparency value of 100% and doesn't
     865             :                         // read the value. Thus, it's intepreted as 0%
     866           0 :                         if ( !bIsDocumentStyle )
     867             :                         {
     868           0 :                             OUString aAttrValue( rAttrValue );
     869           0 :                             NegPercent(aAttrValue);
     870           0 :                             pMutableAttrList->SetValueByIndex( i, aAttrValue );
     871             :                         }
     872           0 :                         bRename = sal_True;
     873             :                     }
     874           0 :                     break;
     875             :                 case XML_ATACTION_SHAPEID:
     876             :                 {
     877           0 :                     OUString sNewValue( "shape"  );
     878           0 :                     sNewValue += rAttrValue;
     879           0 :                     pMutableAttrList->SetValueByIndex( i, sNewValue );
     880           0 :                     break;
     881             :                 }
     882             : 
     883             :                 default:
     884             :                     OSL_ENSURE( !this, "unknown action" );
     885           0 :                     break;
     886             :                 }
     887             : 
     888        1222 :                 if( bRename )
     889             :                 {
     890             :                     OUString aNewAttrQName(
     891         353 :                         GetNamespaceMap().GetQNameByKey(
     892         353 :                             (*aIter).second.GetQNamePrefixFromParam1(),
     893             :                             ::xmloff::token::GetXMLToken(
     894        1059 :                                 (*aIter).second.GetQNameTokenFromParam1()) ) );
     895             :                     pMutableAttrList->RenameAttributeByIndex( i,
     896         353 :                                                               aNewAttrQName );
     897             :                 }
     898             :             }
     899        2335 :         }
     900             :     }
     901             : 
     902         974 :     return pMutableAttrList;
     903             : }
     904             : 
     905        1136 : sal_Bool XMLTransformerBase::ReplaceSingleInchWithIn( OUString& rValue )
     906             : {
     907        1136 :     sal_Bool bRet = sal_False;
     908        1136 :     sal_Int32 nPos = rValue.getLength();
     909        2272 :     while( nPos && rValue[nPos-1] <= ' ' )
     910           0 :         --nPos;
     911        2272 :     if( nPos > 2 &&
     912        2342 :         ('c'==rValue[nPos-2] || 'C'==rValue[nPos-2]) &&
     913        1768 :         ('h'==rValue[nPos-1] || 'H'==rValue[nPos-1]) )
     914             :     {
     915          70 :         rValue =rValue.copy( 0, nPos-2 );
     916          70 :         bRet = sal_True;
     917             :     }
     918             : 
     919        1136 :     return bRet;
     920             : }
     921             : 
     922          28 : sal_Bool XMLTransformerBase::ReplaceInchWithIn( OUString& rValue )
     923             : {
     924          28 :     sal_Bool bRet = sal_False;
     925          28 :     sal_Int32 nPos = 1;
     926         380 :     while( nPos < rValue.getLength()-3 )
     927             :     {
     928         324 :         sal_Unicode c = rValue[nPos];
     929         324 :         if( 'i'==c || 'I'==c )
     930             :         {
     931          12 :             c = rValue[nPos-1];
     932          12 :             if( (c >= '0' && c <= '9') || '.' == c )
     933             :             {
     934           0 :                 c = rValue[nPos+1];
     935           0 :                 if( 'n'==c || 'N'==c )
     936             :                 {
     937           0 :                     c = rValue[nPos+2];
     938           0 :                     if( 'c'==c || 'C'==c )
     939             :                     {
     940           0 :                         c = rValue[nPos+3];
     941           0 :                         if( 'h'==c || 'H'==c )
     942             :                         {
     943           0 :                             rValue = rValue.replaceAt( nPos,
     944           0 :                                 4, GetXMLToken(XML_UNIT_INCH) );
     945           0 :                             nPos += 2;
     946           0 :                             bRet = sal_True;
     947           0 :                             continue;
     948             :                         }
     949             :                     }
     950             :                 }
     951             :             }
     952             :         }
     953         324 :         ++nPos;
     954             :     }
     955             : 
     956          28 :     return bRet;
     957             : }
     958             : 
     959         680 : sal_Bool XMLTransformerBase::ReplaceSingleInWithInch( OUString& rValue )
     960             : {
     961         680 :     sal_Bool bRet = sal_False;
     962             : 
     963         680 :     sal_Int32 nPos = rValue.getLength();
     964        1360 :     while( nPos && rValue[nPos-1] <= ' ' )
     965           0 :         --nPos;
     966        1360 :     if( nPos > 2 &&
     967        1290 :         ('i'==rValue[nPos-2] ||
     968        1430 :             'I'==rValue[nPos-2]) &&
     969          70 :         ('n'==rValue[nPos-1] ||
     970           0 :             'N'==rValue[nPos-1]) )
     971             :     {
     972          70 :         nPos -= 2;
     973         140 :         rValue = rValue.replaceAt( nPos, rValue.getLength() - nPos,
     974         140 :                                            GetXMLToken(XML_INCH) );
     975          70 :         bRet = sal_True;
     976             :     }
     977             : 
     978         680 :     return bRet;
     979             : }
     980             : 
     981           9 : sal_Bool XMLTransformerBase::ReplaceInWithInch( OUString& rValue )
     982             : {
     983           9 :     sal_Bool bRet = sal_False;
     984           9 :     sal_Int32 nPos = 1;
     985          68 :     while( nPos < rValue.getLength()-1 )
     986             :     {
     987          50 :         sal_Unicode c = rValue[nPos];
     988          50 :         if( 'i'==c || 'I'==c )
     989             :         {
     990           2 :             c = rValue[nPos-1];
     991           2 :             if( (c >= '0' && c <= '9') || '.' == c )
     992             :             {
     993           0 :                 c = rValue[nPos+1];
     994           0 :                 if( 'n'==c || 'N'==c )
     995             :                 {
     996           0 :                     rValue = rValue.replaceAt( nPos,
     997           0 :                                     2, GetXMLToken(XML_INCH) );
     998           0 :                     nPos += 4;
     999           0 :                     bRet = sal_True;
    1000           0 :                     continue;
    1001             :                 }
    1002             :             }
    1003             :         }
    1004          50 :         ++nPos;
    1005             :     }
    1006             : 
    1007           9 :     return bRet;
    1008             : }
    1009             : 
    1010         783 : sal_Bool XMLTransformerBase::EncodeStyleName( OUString& rName ) const
    1011             : {
    1012             :     static sal_Char aHexTab[] = "0123456789abcdef";
    1013             : 
    1014         783 :     sal_Bool bEncoded = sal_False;
    1015             : 
    1016         783 :     sal_Int32 nLen = rName.getLength();
    1017         783 :     OUStringBuffer aBuffer( nLen );
    1018             : 
    1019        5269 :     for( sal_Int32 i = 0; i < nLen; i++ )
    1020             :     {
    1021        4486 :         sal_Unicode c = rName[i];
    1022        4486 :         sal_Bool bValidChar = sal_False;
    1023        4486 :         if( c < 0x00ffU )
    1024             :         {
    1025             :             bValidChar =
    1026        3740 :                 (c >= 0x0041 && c <= 0x005a) ||
    1027        3221 :                 (c >= 0x0061 && c <= 0x007a) ||
    1028           0 :                 (c >= 0x00c0 && c <= 0x00d6) ||
    1029           0 :                 (c >= 0x00d8 && c <= 0x00f6) ||
    1030        8875 :                 (c >= 0x00f8 && c <= 0x00ff) ||
    1031         746 :                 ( i > 0 && ( (c >= 0x0030 && c <= 0x0039) ||
    1032        4624 :                              c == 0x00b7 || c == '-' || c == '.') );
    1033             :         }
    1034             :         else
    1035             :         {
    1036           0 :             if( (c >= 0xf900U && c <= 0xfffeU) ||
    1037           0 :                  (c >= 0x20ddU && c <= 0x20e0U))
    1038             :             {
    1039           0 :                 bValidChar = sal_False;
    1040             :             }
    1041           0 :             else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 ||
    1042           0 :                      c == 0x06e5 || c == 0x06e6 )
    1043             :             {
    1044           0 :                 bValidChar = sal_True;
    1045             :             }
    1046           0 :             else if( c == 0x0387 )
    1047             :             {
    1048           0 :                 bValidChar = i > 0;
    1049             :             }
    1050             :             else
    1051             :             {
    1052           0 :                 if( !xCharClass.is() )
    1053             :                 {
    1054             :                     const_cast < XMLTransformerBase * >(this)
    1055           0 :                         ->xCharClass = CharacterClassification::create( comphelper::getProcessComponentContext() );
    1056             :                 }
    1057           0 :                 sal_Int16 nType = xCharClass->getType( rName, i );
    1058             : 
    1059           0 :                 switch( nType )
    1060             :                 {
    1061             :                 case UnicodeType::UPPERCASE_LETTER:     // Lu
    1062             :                 case UnicodeType::LOWERCASE_LETTER:     // Ll
    1063             :                 case UnicodeType::TITLECASE_LETTER:     // Lt
    1064             :                 case UnicodeType::OTHER_LETTER:         // Lo
    1065             :                 case UnicodeType::LETTER_NUMBER:        // Nl
    1066           0 :                     bValidChar = sal_True;
    1067           0 :                     break;
    1068             :                 case UnicodeType::NON_SPACING_MARK:     // Ms
    1069             :                 case UnicodeType::ENCLOSING_MARK:       // Me
    1070             :                 case UnicodeType::COMBINING_SPACING_MARK:   //Mc
    1071             :                 case UnicodeType::MODIFIER_LETTER:      // Lm
    1072             :                 case UnicodeType::DECIMAL_DIGIT_NUMBER: // Nd
    1073           0 :                     bValidChar = i > 0;
    1074           0 :                     break;
    1075             :                 }
    1076             :             }
    1077             :         }
    1078        4486 :         if( bValidChar )
    1079             :         {
    1080        4389 :             aBuffer.append( c );
    1081             :         }
    1082             :         else
    1083             :         {
    1084          97 :             aBuffer.append( static_cast< sal_Unicode >( '_' ) );
    1085          97 :             if( c > 0x0fff )
    1086             :                 aBuffer.append( static_cast< sal_Unicode >(
    1087           0 :                             aHexTab[ (c >> 12) & 0x0f ]  ) );
    1088          97 :             if( c > 0x00ff )
    1089             :                 aBuffer.append( static_cast< sal_Unicode >(
    1090           0 :                         aHexTab[ (c >> 8) & 0x0f ] ) );
    1091          97 :             if( c > 0x000f )
    1092             :                 aBuffer.append( static_cast< sal_Unicode >(
    1093          97 :                         aHexTab[ (c >> 4) & 0x0f ] ) );
    1094             :             aBuffer.append( static_cast< sal_Unicode >(
    1095          97 :                         aHexTab[ c & 0x0f ] ) );
    1096          97 :             aBuffer.append( static_cast< sal_Unicode >( '_' ) );
    1097          97 :             bEncoded = sal_True;
    1098             :         }
    1099             :     }
    1100             : 
    1101         783 :     if( aBuffer.getLength() > (1<<15)-1 )
    1102           0 :         bEncoded = sal_False;
    1103             : 
    1104         783 :     if( bEncoded )
    1105          75 :         rName = aBuffer.makeStringAndClear();
    1106         783 :     return bEncoded;
    1107             : }
    1108             : 
    1109         275 : sal_Bool XMLTransformerBase::DecodeStyleName( OUString& rName )
    1110             : {
    1111         275 :     sal_Bool bEncoded = sal_False;
    1112             : 
    1113         275 :     sal_Int32 nLen = rName.getLength();
    1114         275 :     OUStringBuffer aBuffer( nLen );
    1115             : 
    1116         275 :     sal_Bool bWithinHex = sal_False;
    1117         275 :     sal_Unicode cEnc = 0;
    1118        2508 :     for( sal_Int32 i = 0; i < nLen; i++ )
    1119             :     {
    1120        2233 :         sal_Unicode c = rName[i];
    1121        2233 :         if( '_' == c )
    1122             :         {
    1123          48 :             if( bWithinHex )
    1124             :             {
    1125          24 :                 aBuffer.append( cEnc );
    1126          24 :                 cEnc = 0;
    1127             :             }
    1128             :             else
    1129             :             {
    1130          24 :                 bEncoded = sal_True;
    1131             :             }
    1132          48 :             bWithinHex = !bWithinHex;
    1133             :         }
    1134        2185 :         else if( bWithinHex )
    1135             :         {
    1136             :             sal_Unicode cDigit;
    1137          48 :             if( c >= '0' && c <= '9' )
    1138             :             {
    1139          48 :                 cDigit = c - '0';
    1140             :             }
    1141           0 :             else if( c >= 'a' && c <= 'f' )
    1142             :             {
    1143           0 :                 cDigit = c - 'a' + 10;
    1144             :             }
    1145           0 :             else if( c >= 'A' && c <= 'F' )
    1146             :             {
    1147           0 :                 cDigit = c - 'A' + 10;
    1148             :             }
    1149             :             else
    1150             :             {
    1151             :                 // error
    1152           0 :                 bEncoded = sal_False;
    1153           0 :                 break;
    1154             :             }
    1155          48 :             cEnc = (cEnc << 4) + cDigit;
    1156             :         }
    1157             :         else
    1158             :         {
    1159        2137 :             aBuffer.append( c );
    1160             :         }
    1161             :     }
    1162             : 
    1163         275 :     if( bEncoded )
    1164           9 :         rName = aBuffer.makeStringAndClear();
    1165         275 :     return bEncoded;
    1166             : }
    1167             : 
    1168          17 : sal_Bool XMLTransformerBase::NegPercent( OUString& rValue )
    1169             : {
    1170          17 :     sal_Bool bRet = sal_False;
    1171          17 :     sal_Bool bNeg = sal_False;
    1172          17 :     double nVal = 0;
    1173             : 
    1174          17 :     sal_Int32 nPos = 0;
    1175          17 :     sal_Int32 nLen = rValue.getLength();
    1176             : 
    1177             :     // skip white space
    1178          34 :     while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
    1179           0 :         nPos++;
    1180             : 
    1181          17 :     if( nPos < nLen && sal_Unicode('-') == rValue[nPos] )
    1182             :     {
    1183           0 :         bNeg = sal_True;
    1184           0 :         nPos++;
    1185             :     }
    1186             : 
    1187             :     // get number
    1188         109 :     while( nPos < nLen &&
    1189          75 :            sal_Unicode('0') <= rValue[nPos] &&
    1190          29 :            sal_Unicode('9') >= rValue[nPos] )
    1191             :     {
    1192             :         // TODO: check overflow!
    1193          29 :         nVal *= 10;
    1194          29 :         nVal += (rValue[nPos] - sal_Unicode('0'));
    1195          29 :         nPos++;
    1196             :     }
    1197          17 :     double nDiv = 1.;
    1198          17 :     if( nPos < nLen && sal_Unicode('.') == rValue[nPos] )
    1199             :     {
    1200           0 :         nPos++;
    1201             : 
    1202           0 :         while( nPos < nLen &&
    1203           0 :                sal_Unicode('0') <= rValue[nPos] &&
    1204           0 :                sal_Unicode('9') >= rValue[nPos] )
    1205             :         {
    1206             :             // TODO: check overflow!
    1207           0 :             nDiv *= 10;
    1208           0 :             nVal += ( static_cast<double>(rValue[nPos] - sal_Unicode('0')) / nDiv );
    1209           0 :             nPos++;
    1210             :         }
    1211             :     }
    1212             : 
    1213             :     // skip white space
    1214          34 :     while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
    1215           0 :         nPos++;
    1216             : 
    1217          17 :     if( nPos < nLen &&  sal_Unicode('%') == rValue[nPos] )
    1218             :     {
    1219          17 :         if( bNeg )
    1220           0 :                nVal = -nVal;
    1221          17 :         nVal += .5;
    1222             : 
    1223          17 :         sal_Int32 nIntVal = 100 - static_cast<sal_Int32>( nVal );
    1224             : 
    1225          17 :         OUStringBuffer aNewValBuffer;
    1226          17 :         aNewValBuffer.append( nIntVal );
    1227          17 :         aNewValBuffer.append( sal_Unicode('%' ) );
    1228             : 
    1229          17 :         rValue = aNewValBuffer.makeStringAndClear();
    1230          17 :         bRet = sal_True;
    1231             :     }
    1232             : 
    1233          17 :     return bRet;
    1234             : }
    1235             : 
    1236          57 : sal_Bool XMLTransformerBase::AddNamespacePrefix( OUString& rName,
    1237             :                              sal_uInt16 nPrefix ) const
    1238             : {
    1239          57 :     rName = GetNamespaceMap().GetQNameByKey( nPrefix, rName, sal_False );
    1240          57 :     return sal_True;
    1241             : }
    1242             : 
    1243          13 : sal_Bool XMLTransformerBase::RemoveNamespacePrefix( OUString& rName,
    1244             :                             sal_uInt16 nPrefixOnly ) const
    1245             : {
    1246          13 :     OUString aLocalName;
    1247             :     sal_uInt16 nPrefix =
    1248          13 :         GetNamespaceMap()._GetKeyByAttrName( rName, &aLocalName, sal_False );
    1249          26 :     sal_Bool bRet = XML_NAMESPACE_UNKNOWN != nPrefix &&
    1250          26 :                     (USHRT_MAX == nPrefixOnly || nPrefix == nPrefixOnly);
    1251          13 :     if( bRet )
    1252          13 :         rName = aLocalName;
    1253             : 
    1254          13 :     return bRet;
    1255             : }
    1256             : 
    1257          25 : sal_Bool XMLTransformerBase::ConvertURIToOASIS( OUString& rURI,
    1258             :                                         sal_Bool bSupportPackage ) const
    1259             : {
    1260          25 :     sal_Bool bRet = sal_False;
    1261          25 :     if( !m_aExtPathPrefix.isEmpty() && !rURI.isEmpty() )
    1262             :     {
    1263          11 :         sal_Bool bRel = sal_False;
    1264          11 :         switch( rURI[0] )
    1265             :         {
    1266             :         case '#':
    1267             :             // no rel path, but
    1268             :             // for package URIs, the '#' has to be removed
    1269          11 :             if( bSupportPackage )
    1270             :             {
    1271          11 :                 rURI = rURI.copy( 1 );
    1272          11 :                 bRet = sal_True;
    1273             :             }
    1274          11 :             break;
    1275             :         case '/':
    1276             :             // no rel path; nothing to do
    1277           0 :             break;
    1278             :         case '.':
    1279             :             // a rel path; to keep URI simple, remove './', if there
    1280           0 :             bRel = sal_True;
    1281           0 :             if( rURI.getLength() > 1 && '/' == rURI[1] )
    1282             :             {
    1283           0 :                 rURI = rURI.copy( 2 );
    1284           0 :                 bRet = sal_True;
    1285             :             }
    1286           0 :             break;
    1287             :         default:
    1288             :             // check for a RFC2396 schema
    1289             :             {
    1290           0 :                 bRel = sal_True;
    1291           0 :                 sal_Int32 nPos = 1;
    1292           0 :                 sal_Int32 nLen = rURI.getLength();
    1293           0 :                 while( nPos < nLen )
    1294             :                 {
    1295           0 :                     switch( rURI[nPos] )
    1296             :                     {
    1297             :                     case '/':
    1298             :                         // a relative path segement
    1299           0 :                         nPos = nLen;    // leave loop
    1300           0 :                         break;
    1301             :                     case ':':
    1302             :                         // a schema
    1303           0 :                         bRel = sal_False;
    1304           0 :                         nPos = nLen;    // leave loop
    1305           0 :                         break;
    1306             :                     default:
    1307             :                         // we don't care about any other characters
    1308           0 :                         break;
    1309             :                     }
    1310           0 :                     ++nPos;
    1311             :                 }
    1312             :             }
    1313             :         }
    1314             : 
    1315          11 :         if( bRel )
    1316             :         {
    1317           0 :             OUString sTmp( m_aExtPathPrefix );
    1318           0 :             sTmp += rURI;
    1319           0 :             rURI = sTmp;
    1320           0 :             bRet = sal_True;
    1321             :         }
    1322             :     }
    1323             : 
    1324          25 :     return bRet;
    1325             : }
    1326             : 
    1327           0 : sal_Bool XMLTransformerBase::ConvertURIToOOo( OUString& rURI,
    1328             :                                         sal_Bool bSupportPackage ) const
    1329             : {
    1330           0 :     sal_Bool bRet = sal_False;
    1331           0 :     if( !rURI.isEmpty() )
    1332             :     {
    1333           0 :         sal_Bool bPackage = sal_False;
    1334           0 :         switch( rURI[0] )
    1335             :         {
    1336             :         case '/':
    1337             :             // no rel path; nothing to to
    1338           0 :             break;
    1339             :         case '.':
    1340             :             // a rel path
    1341           0 :             if( rURI.startsWith( m_aExtPathPrefix ) )
    1342             :             {
    1343             :                 // an external URI; remove '../'
    1344           0 :                 rURI = rURI.copy( m_aExtPathPrefix.getLength() );
    1345           0 :                 bRet = sal_True;
    1346             :             }
    1347             :             else
    1348             :             {
    1349           0 :                 bPackage = sal_True;
    1350             :             }
    1351           0 :             break;
    1352             :         default:
    1353             :             // check for a RFC2396 schema
    1354             :             {
    1355           0 :                 bPackage = sal_True;
    1356           0 :                 sal_Int32 nPos = 1;
    1357           0 :                 sal_Int32 nLen = rURI.getLength();
    1358           0 :                 while( nPos < nLen )
    1359             :                 {
    1360           0 :                     switch( rURI[nPos] )
    1361             :                     {
    1362             :                     case '/':
    1363             :                         // a relative path segement within the package
    1364           0 :                         nPos = nLen;    // leave loop
    1365           0 :                         break;
    1366             :                     case ':':
    1367             :                         // a schema
    1368           0 :                         bPackage = sal_False;
    1369           0 :                         nPos = nLen;    // leave loop
    1370           0 :                         break;
    1371             :                     default:
    1372             :                         // we don't care about any other characters
    1373           0 :                         break;
    1374             :                     }
    1375           0 :                     ++nPos;
    1376             :                 }
    1377             :             }
    1378             :         }
    1379             : 
    1380           0 :         if( bPackage && bSupportPackage )
    1381             :         {
    1382           0 :             OUString sTmp( OUString::valueOf( sal_Unicode( '#' ) ) );
    1383           0 :             if( rURI.startsWith( "./" ) )
    1384           0 :                 rURI = rURI.copy( 2 );
    1385           0 :             sTmp += rURI;
    1386           0 :             rURI = sTmp;
    1387           0 :             bRet = sal_True;
    1388             :         }
    1389             :     }
    1390             : 
    1391           0 :     return bRet;
    1392             : }
    1393             : 
    1394           3 : sal_Bool XMLTransformerBase::RenameAttributeValue(
    1395             :     OUString& rOutAttributeValue,
    1396             :     sal_Int32 nParam1,
    1397             :     sal_Int32 nParam2,
    1398             :     sal_Int32 nParam3 )
    1399             : {
    1400           6 :     return ( lcl_ConvertAttr( rOutAttributeValue, nParam1) ||
    1401           3 :              lcl_ConvertAttr( rOutAttributeValue, nParam2) ||
    1402           3 :              lcl_ConvertAttr( rOutAttributeValue, nParam3) );
    1403             : }
    1404             : 
    1405             : // static
    1406           1 : bool XMLTransformerBase::ConvertRNGDateTimeToISO( OUString& rDateTime )
    1407             : {
    1408           2 :     if( !rDateTime.isEmpty() &&
    1409           1 :         rDateTime.indexOf( sal_Unicode('.')) != -1 )
    1410             :     {
    1411           0 :         rDateTime = rDateTime.replace( sal_Unicode('.'), sal_Unicode(','));
    1412           0 :         return true;
    1413             :     }
    1414             : 
    1415           1 :     return false;
    1416             : }
    1417             : 
    1418          34 : XMLTokenEnum XMLTransformerBase::GetToken( const OUString& rStr ) const
    1419             : {
    1420             :     XMLTransformerTokenMap::const_iterator aIter =
    1421          34 :         m_pTokenMap->find( rStr );
    1422          34 :     if( aIter == m_pTokenMap->end() )
    1423           0 :         return XML_TOKEN_END;
    1424             :     else
    1425          34 :         return (*aIter).second;
    1426             : }
    1427             : 
    1428             : 
    1429             : 
    1430          22 : const XMLTransformerContext *XMLTransformerBase::GetCurrentContext() const
    1431             : {
    1432             :     OSL_ENSURE( !m_pContexts->empty(), "empty stack" );
    1433             : 
    1434             : 
    1435          22 :     return m_pContexts->empty() ? 0 : m_pContexts->back().get();
    1436             : }
    1437             : 
    1438           0 : const XMLTransformerContext *XMLTransformerBase::GetAncestorContext(
    1439             :                                                         sal_uInt32 n ) const
    1440             : {
    1441             :     XMLTransformerContextVector::size_type nSize =
    1442           0 :         m_pContexts->size();
    1443             :     XMLTransformerContextVector::size_type nPos =
    1444           0 :         static_cast<XMLTransformerContextVector::size_type>( n );
    1445             : 
    1446             :     OSL_ENSURE( nSize >nPos+2 , "invalid context" );
    1447             : 
    1448           0 :     return nSize > nPos+2 ? (*m_pContexts)[nSize-(nPos+2)].get() : 0;
    1449             : }
    1450             : 
    1451           7 : bool XMLTransformerBase::isWriter() const
    1452             : {
    1453           7 :     Reference< XServiceInfo > xSI( mxModel, UNO_QUERY );
    1454          22 :     return  xSI.is() &&
    1455          40 :         (   xSI->supportsService("com.sun.star.text.TextDocument") ||
    1456          31 :             xSI->supportsService("com.sun.star.text.WebDocument") ||
    1457          26 :             xSI->supportsService("com.sun.star.text.GlobalDocument") );
    1458             : }
    1459             : 
    1460             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10