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