Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "sal/config.h"
30 : :
31 : : #include <tools/debug.hxx>
32 : : #include <rtl/ustring.hxx>
33 : : #include <rtl/ustrbuf.hxx>
34 : :
35 : : #include <xmloff/xmltoken.hxx>
36 : : #include <xmloff/nmspmap.hxx>
37 : :
38 : : #include "xmloff/xmlnmspe.hxx"
39 : :
40 : :
41 : : using ::rtl::OUString;
42 : : using ::rtl::OUStringBuffer;
43 : : using namespace ::xmloff::token;
44 : :
45 : : /* The basic idea of this class is that we have two two ways to search our
46 : : * data...by prefix and by key. We use an STL boost::unordered_map for fast prefix
47 : : * searching and an STL map for fast key searching.
48 : : *
49 : : * The references to an 'Index' refer to an earlier implementation of the
50 : : * name space map and remain to support code which uses these interfaces.
51 : : *
52 : : * In this implementation, key and index should always be the same number.
53 : : *
54 : : * All references to Indices are now deprecated and the corresponding
55 : : * 'Key' methods should be used instead
56 : : *
57 : : * Martin 13/06/01
58 : : */
59 : :
60 : 11500 : SvXMLNamespaceMap::SvXMLNamespaceMap()
61 [ + - ][ + - ]: 11500 : : sXMLNS( GetXMLToken ( XML_XMLNS ) )
[ + - ][ + - ]
62 : : {
63 : 11500 : }
64 : :
65 : 6598 : SvXMLNamespaceMap::SvXMLNamespaceMap( const SvXMLNamespaceMap& rMap )
66 [ + - ][ + - ]: 6598 : : sXMLNS( GetXMLToken ( XML_XMLNS ) )
[ + - ][ + - ]
67 : : {
68 [ + - ]: 6598 : aNameHash = rMap.aNameHash;
69 [ + - ]: 6598 : aNameMap = rMap.aNameMap;
70 : 6598 : }
71 : :
72 : 0 : void SvXMLNamespaceMap::operator=( const SvXMLNamespaceMap& rMap )
73 : : {
74 : 0 : aNameHash = rMap.aNameHash;
75 : 0 : aNameMap = rMap.aNameMap;
76 : 0 : }
77 : :
78 [ + - ][ + - ]: 17503 : SvXMLNamespaceMap::~SvXMLNamespaceMap()
[ + - ]
79 : : {
80 : 17503 : }
81 : :
82 : 7557 : int SvXMLNamespaceMap::operator ==( const SvXMLNamespaceMap& rCmp ) const
83 : : {
84 : 7557 : return static_cast < int > (aNameHash == rCmp.aNameHash);
85 : : }
86 : :
87 : 118388 : sal_uInt16 SvXMLNamespaceMap::_Add( const OUString& rPrefix, const OUString &rName, sal_uInt16 nKey )
88 : : {
89 [ + + ]: 118388 : if( XML_NAMESPACE_UNKNOWN == nKey )
90 : : {
91 : : // create a new unique key with UNKNOWN flag set
92 : 5624 : nKey = XML_NAMESPACE_UNKNOWN_FLAG;
93 : 31407 : do
94 : : {
95 [ + - ]: 31407 : NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
96 [ + + ]: 31407 : if( aIter == aNameMap.end() )
97 : : break;
98 : 25783 : nKey++;
99 : : }
100 : : while ( sal_True );
101 : : }
102 [ + - ]: 118388 : ::rtl::Reference<NameSpaceEntry> pEntry(new NameSpaceEntry);
103 : 118388 : pEntry->sName = rName;
104 : 118388 : pEntry->nKey = nKey;
105 : 118388 : pEntry->sPrefix = rPrefix;
106 [ + - ][ + - ]: 118388 : aNameHash[ rPrefix ] = pEntry;
107 [ + - ][ + - ]: 118388 : aNameMap [ nKey ] = pEntry;
108 : 118388 : return nKey;
109 : : }
110 : :
111 : 105195 : sal_uInt16 SvXMLNamespaceMap::Add( const OUString& rPrefix, const OUString& rName,
112 : : sal_uInt16 nKey )
113 : : {
114 [ + + ]: 105195 : if( XML_NAMESPACE_UNKNOWN == nKey )
115 : 5628 : nKey = GetKeyByName( rName );
116 : :
117 : : DBG_ASSERT( XML_NAMESPACE_NONE != nKey,
118 : : "SvXMLNamespaceMap::Add: invalid namespace key" );
119 : :
120 [ - + ]: 105195 : if( XML_NAMESPACE_NONE == nKey )
121 : 0 : return USHRT_MAX;
122 : :
123 [ + - ][ + + ]: 105195 : if ( aNameHash.find ( rPrefix ) == aNameHash.end() )
124 : 101654 : nKey = _Add( rPrefix, rName, nKey );
125 : :
126 : 105195 : return nKey;
127 : : }
128 : :
129 : 25237 : sal_uInt16 SvXMLNamespaceMap::AddIfKnown( const OUString& rPrefix, const OUString& rName )
130 : : {
131 : 25237 : sal_uInt16 nKey = GetKeyByName( rName );
132 : :
133 : : DBG_ASSERT( XML_NAMESPACE_NONE != nKey,
134 : : "SvXMLNamespaceMap::AddIfKnown: invalid namespace key" );
135 : :
136 [ - + ]: 25237 : if( XML_NAMESPACE_NONE == nKey )
137 : 0 : return XML_NAMESPACE_UNKNOWN;
138 : :
139 [ + + ]: 25237 : if( XML_NAMESPACE_UNKNOWN != nKey )
140 : : {
141 [ + - ]: 18770 : NameSpaceHash::const_iterator aIter = aNameHash.find( rPrefix );
142 [ + + ][ + - ]: 18770 : if( aIter == aNameHash.end() || (*aIter).second->sName != rName )
[ - + ][ + - ]
[ + - ][ + +
# # # # ]
[ + - ]
143 [ + - ]: 18770 : nKey = _Add( rPrefix, rName, nKey );
144 : : }
145 : :
146 : 25237 : return nKey;
147 : : }
148 : :
149 : :
150 : 34 : sal_uInt16 SvXMLNamespaceMap::GetKeyByPrefix( const OUString& rPrefix ) const
151 : : {
152 [ + - ]: 34 : NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix);
153 [ + - ][ - + ]: 34 : return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX;
[ # # ]
154 : : }
155 : :
156 : 30915 : sal_uInt16 SvXMLNamespaceMap::GetKeyByName( const OUString& rName ) const
157 : : {
158 : 30915 : sal_uInt16 nKey = XML_NAMESPACE_UNKNOWN;
159 [ + - ][ + - ]: 30915 : NameSpaceHash::const_iterator aIter = aNameHash.begin(), aEnd = aNameHash.end();
160 [ + + ]: 780685 : while (aIter != aEnd )
161 : : {
162 [ + - ][ + + ]: 768556 : if ((*aIter).second->sName == rName)
163 : : {
164 [ + - ]: 18786 : nKey = (*aIter).second->nKey;
165 : 18786 : break;
166 : : }
167 : 749770 : ++aIter;
168 : : }
169 : 30915 : return nKey;
170 : : }
171 : :
172 : 20 : const OUString& SvXMLNamespaceMap::GetPrefixByKey( sal_uInt16 nKey ) const
173 : : {
174 [ + - ]: 20 : NameSpaceMap::const_iterator aIter = aNameMap.find (nKey);
175 [ + - ]: 20 : return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty;
176 : : }
177 : :
178 : 19207 : const OUString& SvXMLNamespaceMap::GetNameByKey( sal_uInt16 nKey ) const
179 : : {
180 [ + - ]: 19207 : NameSpaceMap::const_iterator aIter = aNameMap.find (nKey);
181 [ + + ]: 19207 : return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty;
182 : : }
183 : :
184 : 21335 : OUString SvXMLNamespaceMap::GetAttrNameByKey( sal_uInt16 nKey ) const
185 : : {
186 : 21335 : OUStringBuffer sAttrName;
187 [ + - ]: 21335 : NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
188 [ + - ]: 21335 : if (aIter != aNameMap.end())
189 : : {
190 [ + - ]: 21335 : sAttrName.append( sXMLNS );
191 : 21335 : const ::rtl::OUString & prefix( (*aIter).second->sPrefix );
192 [ + + ]: 21335 : if (!prefix.isEmpty()) // not default namespace
193 : : {
194 [ + - ]: 20243 : sAttrName.append( sal_Unicode(':') );
195 [ + - ]: 20243 : sAttrName.append( prefix );
196 : : }
197 : : }
198 [ + - ]: 21335 : return sAttrName.makeStringAndClear();
199 : : }
200 : :
201 : 298886 : OUString SvXMLNamespaceMap::GetQNameByKey( sal_uInt16 nKey,
202 : : const OUString& rLocalName,
203 : : sal_Bool bCache) const
204 : : {
205 : : // We always want to return at least the rLocalName...
206 : :
207 [ + - + + ]: 298886 : switch ( nKey )
208 : : {
209 : : case XML_NAMESPACE_UNKNOWN:
210 : : // ...if it's a completely unknown namespace, assert and return the local name
211 : : DBG_ASSERT( sal_False, "SvXMLNamespaceMap::GetQNameByKey: invalid namespace key" );
212 : : case XML_NAMESPACE_NONE:
213 : : // ...if there isn't one, return the local name
214 : 74 : return rLocalName;
215 : : case XML_NAMESPACE_XMLNS:
216 : : {
217 : : // ...if it's in the xmlns namespace, make the prefix
218 : : // don't bother caching this, it rarely happens
219 : 0 : OUStringBuffer sQName;
220 [ # # ]: 0 : sQName.append ( sXMLNS );
221 [ # # ]: 0 : if (!rLocalName.isEmpty()) // not default namespace
222 : : {
223 [ # # ]: 0 : sQName.append ( sal_Unicode(':') );
224 [ # # ]: 0 : sQName.append ( rLocalName );
225 : : }
226 [ # # ]: 0 : return sQName.makeStringAndClear();
227 : : }
228 : : case XML_NAMESPACE_XML:
229 : : {
230 : : // this namespace is reserved, and needs not to be declared
231 : 112 : OUStringBuffer sQName;
232 [ + - ][ + - ]: 112 : sQName.append ( GetXMLToken(XML_XML) );
233 [ + - ]: 112 : sQName.append ( sal_Unicode(':') );
234 [ + - ]: 112 : sQName.append ( rLocalName );
235 [ + - ]: 112 : return sQName.makeStringAndClear();
236 : : }
237 : : default:
238 : : {
239 : 298700 : QNameCache::const_iterator aQCacheIter;
240 [ + + ]: 298700 : if (bCache)
241 [ + - ][ + - ]: 298619 : aQCacheIter = aQNameCache.find ( QNamePair ( nKey, rLocalName ) );
242 : : else
243 [ + - ]: 81 : aQCacheIter = aQNameCache.end();
244 [ + - ][ + + ]: 298700 : if ( aQCacheIter != aQNameCache.end() )
245 [ + - ]: 262307 : return (*aQCacheIter).second;
246 : : else
247 : : {
248 [ + - ]: 36393 : NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
249 [ + - ]: 36393 : if ( aIter != aNameMap.end() )
250 : : {
251 : 36393 : OUStringBuffer sQName;
252 : : // ...if it's in our map, make the prefix
253 : 36393 : const OUString & prefix( (*aIter).second->sPrefix );
254 [ + + ]: 36393 : if (!prefix.isEmpty()) // not default namespace
255 : : {
256 [ + - ]: 25033 : sQName.append( prefix );
257 [ + - ]: 25033 : sQName.append( sal_Unicode(':') );
258 : : }
259 [ + - ]: 36393 : sQName.append ( rLocalName );
260 [ + + ]: 36393 : if (bCache)
261 : : {
262 [ + - ]: 36312 : OUString sString(sQName.makeStringAndClear());
263 : : aQNameCache.insert(
264 : : QNameCache::value_type(
265 [ + - ][ + - ]: 36312 : QNamePair(nKey, rLocalName), sString));
[ + - ]
266 : 36312 : return sString;
267 : : }
268 : : else
269 [ + - ]: 36393 : return sQName.makeStringAndClear();
270 : : }
271 : : else
272 : : {
273 : : // ... if it isn't, this is a Bad Thing, assert and return the local name
274 : : DBG_ASSERT( sal_False, "SvXMLNamespaceMap::GetQNameByKey: invalid namespace key" );
275 : 298886 : return rLocalName;
276 : : }
277 : : }
278 : : }
279 : : }
280 : : }
281 : :
282 : 31 : sal_uInt16 SvXMLNamespaceMap::_GetKeyByAttrName(
283 : : const OUString& rAttrName,
284 : : OUString *pLocalName,
285 : : sal_Bool bCache) const
286 : : {
287 : 31 : return _GetKeyByAttrName( rAttrName, 0, pLocalName, 0, bCache );
288 : : }
289 : :
290 : 434077 : sal_uInt16 SvXMLNamespaceMap::_GetKeyByAttrName( const OUString& rAttrName,
291 : : OUString *pPrefix,
292 : : OUString *pLocalName,
293 : : OUString *pNamespace,
294 : : sal_Bool bCache) const
295 : : {
296 : 434077 : sal_uInt16 nKey = XML_NAMESPACE_UNKNOWN;
297 : :
298 : 434077 : NameSpaceHash::const_iterator it;
299 [ + + ]: 434077 : if (bCache)
300 [ + - ]: 432092 : it = aNameCache.find ( rAttrName );
301 : : else
302 [ + - ]: 1985 : it = aNameCache.end();
303 [ + - ][ + + ]: 434077 : if ( it != aNameCache.end() )
304 : : {
305 [ + - ]: 380791 : const NameSpaceEntry &rEntry = *((*it).second);
306 [ + + ]: 380791 : if ( pPrefix )
307 : 17900 : *pPrefix = rEntry.sPrefix;
308 [ + + ]: 380791 : if ( pLocalName )
309 : 380785 : *pLocalName = rEntry.sName;
310 : 380791 : nKey = rEntry.nKey;
311 [ + + ]: 380791 : if ( pNamespace )
312 : : {
313 [ + - ]: 17900 : NameSpaceMap::const_iterator aMapIter = aNameMap.find (nKey);
314 [ + - ]: 17900 : *pNamespace = aMapIter != aNameMap.end() ? (*aMapIter).second->sName : sEmpty;
315 : : }
316 : : }
317 : : else
318 : : {
319 [ + - ]: 53286 : rtl::Reference<NameSpaceEntry> xEntry(new NameSpaceEntry());
320 : :
321 : 53286 : sal_Int32 nColonPos = rAttrName.indexOf( sal_Unicode(':') );
322 [ + + ]: 53286 : if( -1L == nColonPos )
323 : : {
324 : : // case: no ':' found -> default namespace
325 : 197 : xEntry->sPrefix = OUString();
326 : 197 : xEntry->sName = rAttrName;
327 : : }
328 : : else
329 : : {
330 : : // normal case: ':' found -> get prefix/suffix
331 : 53089 : xEntry->sPrefix = rAttrName.copy( 0L, nColonPos );
332 : 53089 : xEntry->sName = rAttrName.copy( nColonPos + 1L );
333 : : }
334 : :
335 [ + + ]: 53286 : if( pPrefix )
336 : 12453 : *pPrefix = xEntry->sPrefix;
337 [ + - ]: 53286 : if( pLocalName )
338 : 53286 : *pLocalName = xEntry->sName;
339 : :
340 [ + - ]: 53286 : NameSpaceHash::const_iterator aIter = aNameHash.find( xEntry->sPrefix );
341 [ + - ][ + + ]: 53286 : if ( aIter != aNameHash.end() )
342 : : {
343 : : // found: retrieve namespace key
344 [ + - ]: 51279 : nKey = xEntry->nKey = (*aIter).second->nKey;
345 [ + + ]: 51279 : if ( pNamespace )
346 [ + - ]: 14212 : *pNamespace = (*aIter).second->sName;
347 : : }
348 [ + + ]: 2007 : else if ( xEntry->sPrefix == sXMLNS )
349 : : // not found, but xmlns prefix: return xmlns 'namespace'
350 : 1810 : nKey = xEntry->nKey = XML_NAMESPACE_XMLNS;
351 [ + + ]: 197 : else if( nColonPos == -1L )
352 : : // not found, and no namespace: 'namespace' none
353 : 157 : nKey = xEntry->nKey = XML_NAMESPACE_NONE;
354 : :
355 [ + + ]: 53286 : if (bCache)
356 : : {
357 [ + - ][ + - ]: 51301 : aNameCache.insert(NameSpaceHash::value_type(rAttrName, xEntry));
[ + - ]
358 : 53286 : }
359 : : }
360 : :
361 : 434077 : return nKey;
362 : : }
363 : :
364 : 2146 : sal_uInt16 SvXMLNamespaceMap::GetFirstKey() const
365 : : {
366 [ - + ][ + - ]: 2146 : return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey;
367 : : }
368 : :
369 : 19421 : sal_uInt16 SvXMLNamespaceMap::GetNextKey( sal_uInt16 nLastKey ) const
370 : : {
371 [ + - ]: 19421 : NameSpaceMap::const_iterator aIter = aNameMap.find ( nLastKey );
372 [ + + ]: 19421 : return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey;
373 : : }
374 : :
375 : :
376 : : // All methods after this are deprecated...
377 : :
378 : 0 : sal_uInt16 SvXMLNamespaceMap::GetIndexByKey( sal_uInt16 nKey ) const
379 : : {
380 : 0 : return nKey;
381 : : }
382 : 0 : sal_uInt16 SvXMLNamespaceMap::GetFirstIndex() const
383 : : {
384 [ # # ][ # # ]: 0 : return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey;
385 : : }
386 : :
387 : 0 : sal_uInt16 SvXMLNamespaceMap::GetNextIndex( sal_uInt16 nOldIdx ) const
388 : : {
389 [ # # ]: 0 : NameSpaceMap::const_iterator aIter = aNameMap.find ( nOldIdx );
390 [ # # ]: 0 : return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey;
391 : : }
392 : :
393 : 0 : sal_Bool SvXMLNamespaceMap::AddAtIndex( sal_uInt16 /*nIdx*/, const OUString& rPrefix,
394 : : const OUString& rName, sal_uInt16 nKey )
395 : : {
396 : 0 : sal_Bool bRet = sal_False;
397 : :
398 [ # # ]: 0 : if( XML_NAMESPACE_UNKNOWN == nKey )
399 : 0 : nKey = GetKeyByName( rName );
400 : :
401 : : DBG_ASSERT( XML_NAMESPACE_NONE != nKey,
402 : : "SvXMLNamespaceMap::AddAtIndex: invalid namespace key" );
403 [ # # ][ # # ]: 0 : if( XML_NAMESPACE_NONE != nKey && ! ( aNameHash.count ( rPrefix ) ) )
[ # # ]
404 : : {
405 : 0 : _Add( rPrefix, rName, nKey );
406 : 0 : bRet = sal_True;
407 : : }
408 : 0 : return bRet;
409 : : }
410 : :
411 : 0 : OUString SvXMLNamespaceMap::GetAttrNameByIndex( sal_uInt16 nIdx ) const
412 : : {
413 : 0 : return GetAttrNameByKey( nIdx );
414 : : }
415 : :
416 : 92 : OUString SvXMLNamespaceMap::GetQNameByIndex( sal_uInt16 nIdx,
417 : : const OUString& rLocalName ) const
418 : : {
419 : 92 : return GetQNameByKey( nIdx, rLocalName );
420 : : }
421 : :
422 : 45 : const OUString& SvXMLNamespaceMap::GetPrefixByIndex( sal_uInt16 nIdx ) const
423 : : {
424 [ + - ]: 45 : NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx);
425 [ + - ]: 45 : return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty;
426 : : }
427 : :
428 : 15 : const OUString& SvXMLNamespaceMap::GetNameByIndex( sal_uInt16 nIdx ) const
429 : : {
430 [ + - ]: 15 : NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx);
431 [ + - ]: 15 : return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty;
432 : : }
433 : :
434 : 0 : sal_uInt16 SvXMLNamespaceMap::GetIndexByPrefix( const OUString& rPrefix ) const
435 : : {
436 [ # # ]: 0 : NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix);
437 [ # # ][ # # ]: 0 : return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX;
[ # # ]
438 : : }
439 : 401739 : sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName(
440 : : const OUString& rAttrName,
441 : : OUString *pLocalName,
442 : : sal_uInt16 /*nIdxGuess*/) const
443 : : {
444 : 401739 : return _GetKeyByAttrName( rAttrName, 0, pLocalName, 0 );
445 : : }
446 : :
447 : 30231 : sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName( const OUString& rAttrName,
448 : : OUString *pPrefix,
449 : : OUString *pLocalName,
450 : : OUString *pNamespace,
451 : : sal_uInt16 /*nIdxGuess*/ ) const
452 : : {
453 : 30231 : return _GetKeyByAttrName ( rAttrName, pPrefix, pLocalName, pNamespace );
454 : : }
455 : :
456 : 5104 : sal_Bool SvXMLNamespaceMap::NormalizeURI( ::rtl::OUString& rName )
457 : : {
458 : : // try OASIS + W3 URI normalization
459 : 5104 : sal_Bool bSuccess = NormalizeOasisURN( rName );
460 [ + + ]: 5104 : if( ! bSuccess )
461 : 4329 : bSuccess = NormalizeW3URI( rName );
462 : 5104 : return bSuccess;
463 : : }
464 : :
465 : 4329 : sal_Bool SvXMLNamespaceMap::NormalizeW3URI( ::rtl::OUString& rName )
466 : : {
467 : : // check if URI matches:
468 : : // http://www.w3.org/[0-9]*/[:letter:]*
469 : : // (year)/(WG name)
470 : : // For the following WG/standards names:
471 : : // - xforms
472 : :
473 : 4329 : sal_Bool bSuccess = sal_False;
474 [ + - ]: 4329 : const OUString sURIPrefix = GetXMLToken( XML_URI_W3_PREFIX );
475 [ + + ]: 4329 : if( rName.compareTo( sURIPrefix, sURIPrefix.getLength() ) == 0 )
476 : : {
477 [ + - ]: 975 : const OUString sURISuffix = GetXMLToken( XML_URI_XFORMS_SUFFIX );
478 : 975 : sal_Int32 nCompareFrom = rName.getLength() - sURISuffix.getLength();
479 [ - + ]: 975 : if( rName.copy( nCompareFrom ).equals( sURISuffix ) )
480 : : {
481 : : // found W3 prefix, and xforms suffix
482 [ # # ]: 0 : rName = GetXMLToken( XML_N_XFORMS_1_0 );
483 : 0 : bSuccess = sal_True;
484 : 975 : }
485 : : }
486 : 4329 : return bSuccess;
487 : : }
488 : :
489 : 5721 : sal_Bool SvXMLNamespaceMap::NormalizeOasisURN( ::rtl::OUString& rName )
490 : : {
491 : : // #i38644#
492 : : // we exported the wrong namespace for smil, so we correct this here on load
493 : : // for older documents
494 [ + - ][ + + ]: 5721 : if( IsXMLToken( rName, ::xmloff::token::XML_N_SVG ) )
495 : : {
496 [ + - ]: 375 : rName = GetXMLToken( ::xmloff::token::XML_N_SVG_COMPAT );
497 : 375 : return sal_True;
498 : : }
499 [ + - ][ + + ]: 5346 : else if( IsXMLToken( rName, ::xmloff::token::XML_N_FO ) )
500 : : {
501 [ + - ]: 284 : rName = GetXMLToken( ::xmloff::token::XML_N_FO_COMPAT );
502 : 284 : return sal_True;
503 : : }
504 [ + - ][ + - ]: 10124 : else if( IsXMLToken( rName, ::xmloff::token::XML_N_SMIL ) ||
[ + + ][ + + ]
505 [ + - ]: 5062 : IsXMLToken( rName, ::xmloff::token::XML_N_SMIL_OLD ) )
506 : : {
507 [ + - ]: 4 : rName = GetXMLToken( ::xmloff::token::XML_N_SMIL_COMPAT );
508 : 4 : return sal_True;
509 : : }
510 : :
511 : : //
512 : : // Check if URN matches
513 : : // :urn:oasis:names:tc:[^:]*:xmlns:[^:]*:1.[^:]*
514 : : // |---| |---| |-----|
515 : : // TC-Id Sub-Id Version
516 : :
517 : 5058 : sal_Int32 nNameLen = rName.getLength();
518 : : // :urn:oasis:names:tc.*
519 [ + - ]: 5058 : const OUString& rOasisURN = GetXMLToken( XML_URN_OASIS_NAMES_TC );
520 [ + + ]: 5058 : if( 0 != rName.compareTo( rOasisURN, rOasisURN.getLength() ) )
521 : 4832 : return sal_False;
522 : :
523 : : // :urn:oasis:names:tc:.*
524 : 226 : sal_Int32 nPos = rOasisURN.getLength();
525 [ - + ][ - + ]: 226 : if( nPos >= nNameLen || rName[nPos] != ':' )
[ + - ]
526 : 0 : return sal_False;
527 : :
528 : : // :urn:oasis:names:tc:[^:]:.*
529 : 226 : sal_Int32 nTCIdStart = nPos+1;
530 : 226 : sal_Int32 nTCIdEnd = rName.indexOf( ':', nTCIdStart );
531 [ - + ]: 226 : if( -1 == nTCIdEnd )
532 : 0 : return sal_False;
533 : :
534 : : // :urn:oasis:names:tc:[^:]:xmlns.*
535 : 226 : nPos = nTCIdEnd + 1;
536 : 226 : OUString sTmp( rName.copy( nPos ) );
537 [ + - ]: 226 : const OUString& rXMLNS = GetXMLToken( XML_XMLNS );
538 [ - + ]: 226 : if( 0!= sTmp.compareTo( rXMLNS, rXMLNS.getLength() ) )
539 : 0 : return sal_False;
540 : :
541 : : // :urn:oasis:names:tc:[^:]:xmlns:.*
542 : 226 : nPos += rXMLNS.getLength();
543 [ - + ][ - + ]: 226 : if( nPos >= nNameLen || rName[nPos] != ':' )
[ + - ]
544 : 0 : return sal_False;
545 : :
546 : : // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:.*
547 : 226 : nPos = rName.indexOf( ':', nPos+1 );
548 [ - + ]: 226 : if( -1 == nPos )
549 : 0 : return sal_False;
550 : :
551 : : // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:[^:][^:][^:][^:]*
552 : 226 : sal_Int32 nVersionStart = nPos+1;
553 [ + - - + ]: 452 : if( nVersionStart+2 >= nNameLen ||
[ - + ]
554 : 226 : -1 != rName.indexOf( ':', nVersionStart ) )
555 : 0 : return sal_False;
556 : :
557 : : // :urn:oasis:names:tc:[^:]:xmlns:[^:]*:1\.[^:][^:]*
558 [ + - ][ - + ]: 226 : if( rName[nVersionStart] != '1' || rName[nVersionStart+1] != '.' )
[ - + ]
559 : 0 : return sal_False;
560 : :
561 : : // replace [tcid] with current TCID and version with current version.
562 : 226 : OUStringBuffer aNewName( nNameLen +20 );
563 [ + - ]: 226 : aNewName.append( rName.copy( 0, nTCIdStart ) );
564 [ + - ][ + - ]: 226 : aNewName.append( GetXMLToken( XML_OPENDOCUMENT ) );
565 [ + - ]: 226 : aNewName.append( rName.copy( nTCIdEnd, nVersionStart-nTCIdEnd ) );
566 [ + - ][ + - ]: 226 : aNewName.append( GetXMLToken( XML_1_0 ) );
567 : :
568 [ + - ]: 226 : rName = aNewName.makeStringAndClear();
569 : :
570 : 5721 : return sal_True;
571 : : }
572 : :
573 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|