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

Generated by: LCOV version 1.11