LCOV - code coverage report
Current view: top level - xmloff/source/core - nmspmap.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 214 249 85.9 %
Date: 2015-06-13 12:38:46 Functions: 26 32 81.2 %
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 <sal/config.h>
      21             : 
      22             : #include <rtl/ustring.hxx>
      23             : #include <rtl/ustrbuf.hxx>
      24             : 
      25             : #include <xmloff/xmltoken.hxx>
      26             : #include <xmloff/nmspmap.hxx>
      27             : 
      28             : #include <xmloff/xmlnmspe.hxx>
      29             : 
      30             : 
      31             : using namespace ::xmloff::token;
      32             : 
      33             : /* The basic idea of this class is that we have two two ways to search our
      34             :  * data...by prefix and by key. We use an unordered_map for fast prefix
      35             :  * searching and an STL map for fast key searching.
      36             :  *
      37             :  * The references to an 'Index' refer to an earlier implementation of the
      38             :  * name space map and remain to support code which uses these interfaces.
      39             :  *
      40             :  * In this implementation, key and index should always be the same number.
      41             :  *
      42             :  * All references to Indices are now deprecated and the corresponding
      43             :  * 'Key' methods should be used instead
      44             :  *
      45             :  * Martin 13/06/01
      46             :  */
      47             : 
      48       13052 : SvXMLNamespaceMap::SvXMLNamespaceMap()
      49       13052 : : sXMLNS( GetXMLToken ( XML_XMLNS ) )
      50             : {
      51       13052 : }
      52             : 
      53        8026 : SvXMLNamespaceMap::SvXMLNamespaceMap( const SvXMLNamespaceMap& rMap )
      54        8026 : : sXMLNS( GetXMLToken ( XML_XMLNS ) )
      55             : {
      56        8026 :     aNameHash = rMap.aNameHash;
      57        8026 :     aNameMap  = rMap.aNameMap;
      58        8026 : }
      59             : 
      60           0 : void SvXMLNamespaceMap::operator=( const SvXMLNamespaceMap& rMap )
      61             : {
      62           0 :     aNameHash = rMap.aNameHash;
      63           0 :     aNameMap = rMap.aNameMap;
      64           0 : }
      65             : 
      66       20872 : SvXMLNamespaceMap::~SvXMLNamespaceMap()
      67             : {
      68       20872 : }
      69             : 
      70        6931 : bool SvXMLNamespaceMap::operator ==( const SvXMLNamespaceMap& rCmp ) const
      71             : {
      72        6931 :     return aNameHash == rCmp.aNameHash;
      73             : }
      74             : 
      75      195476 : sal_uInt16 SvXMLNamespaceMap::_Add( const OUString& rPrefix, const OUString &rName, sal_uInt16 nKey )
      76             : {
      77      195476 :     if( XML_NAMESPACE_UNKNOWN == nKey )
      78             :     {
      79             :         // create a new unique key with UNKNOWN flag set
      80        4036 :         nKey = XML_NAMESPACE_UNKNOWN_FLAG;
      81             :         do
      82             :         {
      83       11438 :             NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
      84       11438 :             if( aIter == aNameMap.end() )
      85        4036 :                 break;
      86        7402 :             nKey++;
      87             :         }
      88        7402 :         while ( true );
      89             :     }
      90      195476 :     ::rtl::Reference<NameSpaceEntry> pEntry(new NameSpaceEntry);
      91      195476 :     pEntry->sName   = rName;
      92      195476 :     pEntry->nKey    = nKey;
      93      195476 :     pEntry->sPrefix = rPrefix;
      94      195476 :     aNameHash[ rPrefix ] = pEntry;
      95      195476 :     aNameMap [ nKey ]    = pEntry;
      96      195476 :     return nKey;
      97             : }
      98             : 
      99      155662 : sal_uInt16 SvXMLNamespaceMap::Add( const OUString& rPrefix, const OUString& rName,
     100             :                                sal_uInt16 nKey )
     101             : {
     102      155662 :     if( XML_NAMESPACE_UNKNOWN == nKey )
     103        4043 :         nKey = GetKeyByName( rName );
     104             : 
     105             : #ifdef NDEBUG
     106      155662 :     if( XML_NAMESPACE_NONE == nKey )
     107           0 :         return USHRT_MAX;
     108             : #else
     109             :     assert(XML_NAMESPACE_NONE != nKey);
     110             : #endif
     111             : 
     112      155662 :     if ( aNameHash.find ( rPrefix ) == aNameHash.end() )
     113      153038 :         nKey = _Add( rPrefix, rName, nKey );
     114             : 
     115      155662 :     return nKey;
     116             : }
     117             : 
     118       48853 : sal_uInt16 SvXMLNamespaceMap::AddIfKnown( const OUString& rPrefix, const OUString& rName )
     119             : {
     120       48853 :     sal_uInt16 nKey = GetKeyByName( rName );
     121             : 
     122             : #ifdef NDEBUG
     123       48853 :     if( XML_NAMESPACE_NONE == nKey )
     124           0 :         return XML_NAMESPACE_UNKNOWN;
     125             : #else
     126             :     assert(nKey != XML_NAMESPACE_NONE);
     127             : #endif
     128             : 
     129       48853 :     if( XML_NAMESPACE_UNKNOWN != nKey )
     130             :     {
     131       44471 :         NameSpaceHash::const_iterator aIter = aNameHash.find( rPrefix );
     132       44471 :         if( aIter == aNameHash.end() || (*aIter).second->sName != rName )
     133       42437 :             nKey = _Add( rPrefix, rName, nKey );
     134             :     }
     135             : 
     136       48853 :     return nKey;
     137             : }
     138             : 
     139             : 
     140          17 : sal_uInt16 SvXMLNamespaceMap::GetKeyByPrefix( const OUString& rPrefix ) const
     141             : {
     142          17 :     NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix);
     143          17 :     return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX;
     144             : }
     145             : 
     146       52921 : sal_uInt16 SvXMLNamespaceMap::GetKeyByName( const OUString& rName ) const
     147             : {
     148       52921 :     sal_uInt16 nKey = XML_NAMESPACE_UNKNOWN;
     149       52921 :     NameSpaceHash::const_iterator aIter = aNameHash.begin(), aEnd = aNameHash.end();
     150     1683634 :     while (aIter != aEnd )
     151             :     {
     152     1622271 :         if ((*aIter).second->sName == rName)
     153             :         {
     154       44479 :             nKey = (*aIter).second->nKey;
     155       44479 :             break;
     156             :         }
     157     1577792 :         ++aIter;
     158             :     }
     159       52921 :     return nKey;
     160             : }
     161             : 
     162          14 : const OUString& SvXMLNamespaceMap::GetPrefixByKey( sal_uInt16 nKey ) const
     163             : {
     164          14 :     NameSpaceMap::const_iterator aIter = aNameMap.find (nKey);
     165          14 :     return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty;
     166             : }
     167             : 
     168       37844 : const OUString& SvXMLNamespaceMap::GetNameByKey( sal_uInt16 nKey ) const
     169             : {
     170       37844 :     NameSpaceMap::const_iterator aIter = aNameMap.find (nKey);
     171       37844 :     return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty;
     172             : }
     173             : 
     174       49471 : OUString SvXMLNamespaceMap::GetAttrNameByKey( sal_uInt16 nKey ) const
     175             : {
     176       49471 :     OUStringBuffer sAttrName;
     177       49471 :     NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
     178       49471 :     if (aIter != aNameMap.end())
     179             :     {
     180       49471 :         sAttrName.append( sXMLNS  );
     181       49471 :         const OUString & prefix( (*aIter).second->sPrefix );
     182       49471 :         if (!prefix.isEmpty()) // not default namespace
     183             :         {
     184       48910 :             sAttrName.append( ':' );
     185       48910 :             sAttrName.append( prefix );
     186             :         }
     187             :     }
     188       49471 :     return sAttrName.makeStringAndClear();
     189             : }
     190             : 
     191      379956 : OUString SvXMLNamespaceMap::GetQNameByKey( sal_uInt16 nKey,
     192             :                             const OUString& rLocalName,
     193             :                             bool bCache) const
     194             : {
     195             :     // We always want to return at least the rLocalName...
     196             : 
     197      379956 :     switch ( nKey )
     198             :     {
     199             :         case XML_NAMESPACE_UNKNOWN:
     200             :             // ...if it's a completely unknown namespace, assert and return the local name
     201             :             SAL_WARN("xmloff.core", "unknown namespace, probable missing xmlns: declaration");
     202             :         case XML_NAMESPACE_NONE:
     203             :             // ...if there isn't one, return the local name
     204          37 :             return rLocalName;
     205             :         case XML_NAMESPACE_XMLNS:
     206             :         {
     207             :             // ...if it's in the xmlns namespace, make the prefix
     208             :             // don't bother caching this, it rarely happens
     209           0 :             OUStringBuffer sQName;
     210           0 :             sQName.append ( sXMLNS );
     211           0 :             if (!rLocalName.isEmpty()) // not default namespace
     212             :             {
     213           0 :                 sQName.append ( ':' );
     214           0 :                 sQName.append ( rLocalName );
     215             :             }
     216           0 :             return sQName.makeStringAndClear();
     217             :         }
     218             :         case XML_NAMESPACE_XML:
     219             :         {
     220             :             // this namespace is reserved, and needs not to be declared
     221          59 :             OUStringBuffer sQName;
     222          59 :             sQName.append ( GetXMLToken(XML_XML) );
     223          59 :             sQName.append ( ':' );
     224          59 :             sQName.append ( rLocalName );
     225          59 :             return sQName.makeStringAndClear();
     226             :         }
     227             :         default:
     228             :         {
     229      379860 :             QNameCache::const_iterator aQCacheIter;
     230      379860 :             if (bCache)
     231      379803 :                 aQCacheIter = aQNameCache.find ( QNamePair ( nKey, rLocalName ) );
     232             :             else
     233          57 :                 aQCacheIter = aQNameCache.end();
     234      379860 :             if ( aQCacheIter != aQNameCache.end() )
     235      306568 :                 return (*aQCacheIter).second;
     236             :             else
     237             :             {
     238       73292 :                 NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
     239       73292 :                 if ( aIter != aNameMap.end() )
     240             :                 {
     241       73292 :                     OUStringBuffer sQName;
     242             :                     // ...if it's in our map, make the prefix
     243       73292 :                     const OUString & prefix( (*aIter).second->sPrefix );
     244       73292 :                     if (!prefix.isEmpty()) // not default namespace
     245             :                     {
     246       67612 :                         sQName.append( prefix );
     247       67612 :                         sQName.append( ':' );
     248             :                     }
     249       73292 :                     sQName.append ( rLocalName );
     250       73292 :                     if (bCache)
     251             :                     {
     252       73235 :                         OUString sString(sQName.makeStringAndClear());
     253             :                         aQNameCache.insert(
     254             :                             QNameCache::value_type(
     255       73235 :                                 QNamePair(nKey, rLocalName), sString));
     256       73235 :                         return sString;
     257             :                     }
     258             :                     else
     259          57 :                         return sQName.makeStringAndClear();
     260             :                 }
     261             :                 else
     262             :                 {
     263             :                     // ... if it isn't, this is a Bad Thing, assert and return the local name
     264             :                     assert(false);
     265           0 :                     return rLocalName;
     266             :                 }
     267             :             }
     268             :         }
     269             :     }
     270             : }
     271             : 
     272          20 : sal_uInt16 SvXMLNamespaceMap::_GetKeyByAttrName(
     273             :                             const OUString& rAttrName,
     274             :                             OUString *pLocalName,
     275             :                             bool bCache) const
     276             : {
     277          20 :     return _GetKeyByAttrName( rAttrName, 0, pLocalName, 0, bCache );
     278             : }
     279             : 
     280      946755 : sal_uInt16 SvXMLNamespaceMap::_GetKeyByAttrName( const OUString& rAttrName,
     281             :                                             OUString *pPrefix,
     282             :                                             OUString *pLocalName,
     283             :                                             OUString *pNamespace,
     284             :                                             bool bCache) const
     285             : {
     286      946755 :     sal_uInt16 nKey = XML_NAMESPACE_UNKNOWN;
     287             : 
     288      946755 :     NameSpaceHash::const_iterator it;
     289      946755 :     if (bCache)
     290      945084 :         it = aNameCache.find ( rAttrName );
     291             :     else
     292        1671 :         it = aNameCache.end();
     293      946755 :     if ( it != aNameCache.end() )
     294             :     {
     295      822284 :         const NameSpaceEntry &rEntry = *((*it).second);
     296      822284 :         if ( pPrefix )
     297       86653 :             *pPrefix = rEntry.sPrefix;
     298      822284 :         if ( pLocalName )
     299      822281 :             *pLocalName = rEntry.sName;
     300      822284 :         nKey = rEntry.nKey;
     301      822284 :         if ( pNamespace )
     302             :         {
     303       86653 :             NameSpaceMap::const_iterator aMapIter = aNameMap.find (nKey);
     304       86653 :             *pNamespace = aMapIter != aNameMap.end() ? (*aMapIter).second->sName : sEmpty;
     305             :         }
     306             :     }
     307             :     else
     308             :     {
     309      124471 :     rtl::Reference<NameSpaceEntry> xEntry(new NameSpaceEntry());
     310             : 
     311      124471 :         sal_Int32 nColonPos = rAttrName.indexOf( ':' );
     312      124471 :         if( -1L == nColonPos )
     313             :         {
     314             :             // case: no ':' found -> default namespace
     315         469 :             (xEntry->sPrefix).clear();
     316         469 :             xEntry->sName = rAttrName;
     317             :         }
     318             :         else
     319             :         {
     320             :             // normal case: ':' found -> get prefix/suffix
     321      124002 :             xEntry->sPrefix = rAttrName.copy( 0L, nColonPos );
     322      124002 :             xEntry->sName = rAttrName.copy( nColonPos + 1L );
     323             :         }
     324             : 
     325      124471 :         if( pPrefix )
     326       42114 :             *pPrefix = xEntry->sPrefix;
     327      124471 :         if( pLocalName )
     328      124471 :             *pLocalName = xEntry->sName;
     329             : 
     330      124471 :         NameSpaceHash::const_iterator aIter = aNameHash.find( xEntry->sPrefix );
     331      124471 :         if ( aIter != aNameHash.end() )
     332             :         {
     333             :             // found: retrieve namespace key
     334      123785 :             nKey = xEntry->nKey = (*aIter).second->nKey;
     335      123785 :             if ( pNamespace )
     336       43648 :                 *pNamespace = (*aIter).second->sName;
     337             :         }
     338         686 :         else if ( xEntry->sPrefix == sXMLNS )
     339             :             // not found, but xmlns prefix: return xmlns 'namespace'
     340         568 :             nKey = xEntry->nKey = XML_NAMESPACE_XMLNS;
     341         118 :         else if( nColonPos == -1L )
     342             :             // not found, and no namespace: 'namespace' none
     343          96 :             nKey = xEntry->nKey = XML_NAMESPACE_NONE;
     344             : 
     345      124471 :         if (bCache)
     346             :         {
     347      122800 :             aNameCache.insert(NameSpaceHash::value_type(rAttrName, xEntry));
     348      124471 :         }
     349             :     }
     350             : 
     351      946755 :     return nKey;
     352             : }
     353             : 
     354        4831 : sal_uInt16 SvXMLNamespaceMap::GetFirstKey() const
     355             : {
     356        4831 :     return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey;
     357             : }
     358             : 
     359       46185 : sal_uInt16 SvXMLNamespaceMap::GetNextKey( sal_uInt16 nLastKey ) const
     360             : {
     361       46185 :     NameSpaceMap::const_iterator aIter = aNameMap.find ( nLastKey );
     362       46185 :     return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey;
     363             : }
     364             : 
     365             : 
     366             : // All methods after this are deprecated...
     367             : 
     368           0 : sal_uInt16 SvXMLNamespaceMap::GetIndexByKey( sal_uInt16 nKey )
     369             : {
     370           0 :     return nKey;
     371             : }
     372           0 : sal_uInt16 SvXMLNamespaceMap::GetFirstIndex() const
     373             : {
     374           0 :     return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey;
     375             : }
     376             : 
     377           0 : sal_uInt16 SvXMLNamespaceMap::GetNextIndex( sal_uInt16 nOldIdx ) const
     378             : {
     379           0 :     NameSpaceMap::const_iterator aIter = aNameMap.find ( nOldIdx );
     380           0 :     return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey;
     381             : }
     382             : 
     383           1 : bool SvXMLNamespaceMap::AddAtIndex( sal_uInt16 /*nIdx*/, const OUString& rPrefix,
     384             :                                     const OUString& rName, sal_uInt16 nKey )
     385             : {
     386           1 :     bool bRet = false;
     387             : 
     388           1 :     if( XML_NAMESPACE_UNKNOWN == nKey )
     389           0 :         nKey = GetKeyByName( rName );
     390             : 
     391             :     assert(XML_NAMESPACE_NONE != nKey);
     392           1 :     if( XML_NAMESPACE_NONE != nKey && ! ( aNameHash.count ( rPrefix ) ) )
     393             :     {
     394           1 :         _Add( rPrefix, rName, nKey );
     395           1 :         bRet = true;
     396             :     }
     397           1 :     return bRet;
     398             : }
     399             : 
     400           0 : OUString SvXMLNamespaceMap::GetAttrNameByIndex( sal_uInt16 nIdx ) const
     401             : {
     402           0 :     return GetAttrNameByKey( nIdx );
     403             : }
     404             : 
     405         132 : OUString SvXMLNamespaceMap::GetQNameByIndex( sal_uInt16 nIdx,
     406             :                                            const OUString& rLocalName ) const
     407             : {
     408         132 :     return GetQNameByKey( nIdx, rLocalName );
     409             : }
     410             : 
     411          21 : const OUString& SvXMLNamespaceMap::GetPrefixByIndex( sal_uInt16 nIdx ) const
     412             : {
     413          21 :     NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx);
     414          21 :     return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty;
     415             : }
     416             : 
     417           7 : const OUString& SvXMLNamespaceMap::GetNameByIndex( sal_uInt16 nIdx ) const
     418             : {
     419           7 :     NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx);
     420           7 :     return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty;
     421             : }
     422             : 
     423           0 : sal_uInt16 SvXMLNamespaceMap::GetIndexByPrefix( const OUString& rPrefix ) const
     424             : {
     425           0 :     NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix);
     426           0 :     return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX;
     427             : }
     428      816317 : sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName(
     429             :                             const OUString& rAttrName,
     430             :                             OUString *pLocalName,
     431             :                             sal_uInt16 /*nIdxGuess*/) const
     432             : {
     433      816317 :     return _GetKeyByAttrName( rAttrName, 0, pLocalName, 0 );
     434             : }
     435             : 
     436      128706 : sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName( const OUString& rAttrName,
     437             :                                             OUString *pPrefix,
     438             :                                             OUString *pLocalName,
     439             :                                             OUString *pNamespace,
     440             :                                             sal_uInt16 /*nIdxGuess*/ ) const
     441             : {
     442      128706 :     return _GetKeyByAttrName ( rAttrName, pPrefix, pLocalName, pNamespace );
     443             : }
     444             : 
     445        4096 : bool SvXMLNamespaceMap::NormalizeURI( OUString& rName )
     446             : {
     447             :     // try OASIS + W3 URI normalization
     448        4096 :     bool bSuccess = NormalizeOasisURN( rName );
     449        4096 :     if( ! bSuccess )
     450        3740 :         bSuccess = NormalizeW3URI( rName );
     451        4096 :     return bSuccess;
     452             : }
     453             : 
     454        3740 : bool SvXMLNamespaceMap::NormalizeW3URI( OUString& rName )
     455             : {
     456             :     // check if URI matches:
     457             :     // http://www.w3.org/[0-9]*/[:letter:]*
     458             :     //                   (year)/(WG name)
     459             :     // For the following WG/standards names:
     460             :     // - xforms
     461             : 
     462        3740 :     bool bSuccess = false;
     463        3740 :     const OUString sURIPrefix = GetXMLToken( XML_URI_W3_PREFIX );
     464        3740 :     if( rName.startsWith( sURIPrefix ) )
     465             :     {
     466        1779 :         const OUString sURISuffix = GetXMLToken( XML_URI_XFORMS_SUFFIX );
     467        1779 :         sal_Int32 nCompareFrom = rName.getLength() - sURISuffix.getLength();
     468        1779 :         if( rName.copy( nCompareFrom ).equals( sURISuffix ) )
     469             :         {
     470             :             // found W3 prefix, and xforms suffix
     471           0 :             rName = GetXMLToken( XML_N_XFORMS_1_0 );
     472           0 :             bSuccess = true;
     473        1779 :         }
     474             :     }
     475        3740 :     return bSuccess;
     476             : }
     477             : 
     478        4159 : bool SvXMLNamespaceMap::NormalizeOasisURN( OUString& rName )
     479             : {
     480             :     // #i38644#
     481             :     // we exported the wrong namespace for smil, so we correct this here on load
     482             :     // for older documents
     483        4159 :     if( IsXMLToken( rName, ::xmloff::token::XML_N_SVG ) )
     484             :     {
     485         191 :         rName = GetXMLToken( ::xmloff::token::XML_N_SVG_COMPAT );
     486         191 :         return true;
     487             :     }
     488        3968 :     else if( IsXMLToken( rName, ::xmloff::token::XML_N_FO ) )
     489             :     {
     490          80 :         rName = GetXMLToken( ::xmloff::token::XML_N_FO_COMPAT );
     491          80 :         return true;
     492             :     }
     493        7776 :     else if( IsXMLToken( rName, ::xmloff::token::XML_N_SMIL ) ||
     494        3888 :                IsXMLToken( rName, ::xmloff::token::XML_N_SMIL_OLD )  )
     495             :     {
     496           6 :         rName = GetXMLToken( ::xmloff::token::XML_N_SMIL_COMPAT );
     497           6 :         return true;
     498             :     }
     499             : 
     500             : 
     501             :     // Check if URN matches
     502             :     // :urn:oasis:names:tc:[^:]*:xmlns:[^:]*:1.[^:]*
     503             :     //                     |---|       |---| |-----|
     504             :     //                     TC-Id      Sub-Id Version
     505             : 
     506        3882 :     sal_Int32 nNameLen = rName.getLength();
     507             :     // :urn:oasis:names:tc.*
     508        3882 :     const OUString& rOasisURN = GetXMLToken( XML_URN_OASIS_NAMES_TC );
     509        3882 :     if( !rName.startsWith( rOasisURN ) )
     510        3796 :         return false;
     511             : 
     512             :     // :urn:oasis:names:tc:.*
     513          86 :     sal_Int32 nPos = rOasisURN.getLength();
     514          86 :     if( nPos >= nNameLen || rName[nPos] != ':' )
     515           0 :         return false;
     516             : 
     517             :     // :urn:oasis:names:tc:[^:]:.*
     518          86 :     sal_Int32 nTCIdStart = nPos+1;
     519          86 :     sal_Int32 nTCIdEnd = rName.indexOf( ':', nTCIdStart );
     520          86 :     if( -1 == nTCIdEnd )
     521           0 :         return false;
     522             : 
     523             :     // :urn:oasis:names:tc:[^:]:xmlns.*
     524          86 :     nPos = nTCIdEnd + 1;
     525          86 :     OUString sTmp( rName.copy( nPos ) );
     526          86 :     const OUString& rXMLNS = GetXMLToken( XML_XMLNS );
     527          86 :     if( !sTmp.startsWith( rXMLNS ) )
     528           0 :         return false;
     529             : 
     530             :     // :urn:oasis:names:tc:[^:]:xmlns:.*
     531          86 :     nPos += rXMLNS.getLength();
     532          86 :     if( nPos >= nNameLen || rName[nPos] != ':' )
     533           0 :         return false;
     534             : 
     535             :     // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:.*
     536          86 :     nPos = rName.indexOf( ':', nPos+1 );
     537          86 :     if( -1 == nPos )
     538           0 :         return false;
     539             : 
     540             :     // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:[^:][^:][^:][^:]*
     541          86 :     sal_Int32 nVersionStart = nPos+1;
     542         172 :     if( nVersionStart+2 >= nNameLen ||
     543          86 :         -1 != rName.indexOf( ':', nVersionStart ) )
     544           0 :         return false;
     545             : 
     546             :     // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:1\.[^:][^:]*
     547          86 :     if( rName[nVersionStart] != '1' || rName[nVersionStart+1] != '.' )
     548           0 :         return false;
     549             : 
     550             :     // replace [tcid] with current TCID and version with current version.
     551             : 
     552         344 :     rName = rName.copy( 0, nTCIdStart ) +
     553         344 :             GetXMLToken( XML_OPENDOCUMENT ) +
     554         344 :             rName.copy( nTCIdEnd, nVersionStart-nTCIdEnd ) +
     555         172 :             GetXMLToken( XML_1_0 );
     556             : 
     557          86 :     return true;
     558             : }
     559             : 
     560             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11