20 #include <rtl/ref.hxx>
21 #include <rtl/ustrbuf.hxx>
23 #include <osl/diagnose.h>
24 #include <com/sun/star/i18n/CharacterClassification.hpp>
25 #include <com/sun/star/i18n/UnicodeType.hpp>
26 #include <com/sun/star/util/MeasureUnit.hpp>
46 using namespace ::
osl;
57 bool lcl_ConvertAttr( OUString & rOutAttribute, sal_Int32
nParam )
75 const OUString& rLocalName,
const OUString& rQName )
77 XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
78 XMLTransformerActions::const_iterator aIter =
83 sal_uInt32 nActionType = (*aIter).second.m_nActionType;
90 "unknown or not persistent action" );
103 (*aIter).second.GetQNamePrefixFromParam1(),
104 (*aIter).second.GetQNameTokenFromParam1() );
107 (*aIter).second.GetQNamePrefixFromParam1(),
108 (*aIter).second.GetQNameTokenFromParam1(),
109 (*aIter).second.GetQNamePrefixFromParam2(),
110 (*aIter).second.GetQNameTokenFromParam2(),
111 static_cast< XMLTokenEnum >( (*aIter).second.m_nParam3 ) );
114 (*aIter).second.GetQNamePrefixFromParam1(),
115 (*aIter).second.GetQNameTokenFromParam1(),
116 static_cast< sal_uInt16
>( (*aIter).second.m_nParam2 ) );
119 (*aIter).second.GetQNamePrefixFromParam1(),
120 (*aIter).second.GetQNameTokenFromParam1(),
121 static_cast< sal_uInt16
>(
122 (*aIter).second.m_nParam3 >> 16 ),
123 (*aIter).second.GetQNamePrefixFromParam2(),
124 (*aIter).second.GetQNameTokenFromParam2(),
126 (*aIter).second.m_nParam3 & 0xffff ) );
131 (*aIter).second.GetQNamePrefixFromParam3(),
132 (*aIter).second.GetQNameTokenFromParam3() ) )
134 (*aIter).second.GetQNamePrefixFromParam1(),
135 (*aIter).second.GetQNameTokenFromParam1(),
136 static_cast< sal_uInt16
>( (*aIter).second.m_nParam2 ) );
139 static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
143 static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
148 (*aIter).second.GetQNamePrefixFromParam1(),
149 (*aIter).second.GetQNameTokenFromParam1() ) )
151 static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
156 static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
159 static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
161 OSL_ENSURE(
false,
"unknown action" );
179 m_ElemActions( pInit ),
180 m_TokenMap( pTKMapInit )
206 const Reference< XAttributeList >& rAttrList )
208 std::unique_ptr<SvXMLNamespaceMap> pRewindMap;
213 Reference< XAttributeList > xAttrList( rAttrList );
214 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
215 for( sal_Int16
i=0;
i < nAttrCount;
i++ )
217 const OUString& rAttrName = xAttrList->getNameByIndex(
i );
218 if( ( rAttrName.getLength() >= 5 ) &&
219 ( rAttrName.startsWith(
GetXMLToken(XML_XMLNS) ) ) &&
220 ( rAttrName.getLength() == 5 ||
':' == rAttrName[5] ) )
227 const OUString& rAttrValue = xAttrList->getValueByIndex(
i );
229 OUString aPrefix( ( rAttrName.getLength() == 5 )
231 : rAttrName.copy( 6 ) );
238 OUString aTestName( rAttrValue );
247 if( !rRepName.isEmpty() )
249 if( !pMutableAttrList )
252 xAttrList = pMutableAttrList;
270 xContext =
m_vContexts.back()->CreateChildContext( nPrefix,
280 OSL_ENSURE( xContext.is(),
"XMLTransformerBase::startElement: missing context" );
286 xContext->PutRewindMap( std::move(pRewindMap) );
292 xContext->StartElement( xAttrList );
296 #
if OSL_DEBUG_LEVEL > 0
307 #if OSL_DEBUG_LEVEL > 0
308 OSL_ENSURE( xContext->GetQName() == rName,
309 "XMLTransformerBase::endElement: popped context has wrong lname" );
313 xContext->EndElement();
319 std::unique_ptr<SvXMLNamespaceMap> pRewindMap = xContext->TakeRewindMap();
341 m_xHandler->ignorableWhitespace( rWhitespaces );
345 const OUString& rData )
347 m_xHandler->processingInstruction( rTarget, rData );
378 for(
const auto& rArgument : aArguments )
386 css::uno::Reference< XFastDocumentHandler > xFastHandler;
387 if( (rArgument >>= xFastHandler) && xFastHandler )
403 mxModel.set( rArgument, UNO_QUERY );
409 OUString sRelPath,
sName;
410 Reference< XPropertySetInfo > xPropSetInfo =
412 OUString sPropName(
"StreamRelPath" );
413 if( xPropSetInfo->hasPropertyByName(sPropName) )
415 aAny =
m_xPropSet->getPropertyValue(sPropName);
418 sPropName =
"StreamName";
419 if( xPropSetInfo->hasPropertyByName(sPropName) )
421 aAny =
m_xPropSet->getPropertyValue(sPropName);
424 if( !sName.isEmpty() )
432 if( !sRelPath.isEmpty() )
434 sal_Int32 nColPos = sRelPath.indexOf(
':' );
435 OSL_ENSURE( -1 == nColPos,
436 "StreamRelPath contains ':', absolute URI?" );
445 nPos = sRelPath.indexOf(
'/', nPos + 1 );
459 if( rValue.endsWithIgnoreAsciiCase(
"cm" ) )
460 return util::MeasureUnit::CM;
461 else if ( rValue.endsWithIgnoreAsciiCase(
"mm" ) )
462 return util::MeasureUnit::MM;
464 return util::MeasureUnit::INCH;
468 Reference< XAttributeList >& rAttrList, sal_uInt16 nActionMap,
473 OSL_ENSURE( pActions,
"go no actions" );
476 sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
477 for( sal_Int16
i=0;
i < nAttrCount; ++
i )
479 const OUString& rAttrName = rAttrList->getNameByIndex(
i );
480 const OUString& rAttrValue = rAttrList->getValueByIndex(
i );
485 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
486 XMLTransformerActions::const_iterator aIter =
487 pActions->find( aKey );
488 if( aIter != pActions->end() )
490 if( !pMutableAttrList )
494 rAttrList = pMutableAttrList;
497 sal_uInt32 nAction = (*aIter).second.m_nActionType;
498 bool bRename =
false;
517 OUString aAttrValue( rAttrValue );
524 OUString aAttrValue( rAttrValue );
534 OUString aAttrValue( rAttrValue );
541 OUString aAttrValue( rAttrValue );
548 OUString aAttrValue( rAttrValue );
553 sal_Int16
const nDestUnit =
lcl_getUnit(aAttrValue);
562 nMeasure =
static_cast<sal_Int32
>( nMeasure >= 0
563 ? ((nMeasure*127+36)/72)
564 : ((nMeasure*127-36)/72) );
568 nMeasure, util::MeasureUnit::MM_100TH,
570 aAttrValue = aBuffer.makeStringAndClear();
583 OUString aAttrValue( rAttrValue );
590 OUString aAttrValue( rAttrValue );
594 OUString aNewAttrQName(
609 OUString aAttrValue( rAttrValue );
619 OUString aAttrValue( rAttrValue );
629 OUString aAttrValue( rAttrValue );
630 sal_uInt16 nValPrefix =
631 static_cast<sal_uInt16
>(
632 bRename ? (*aIter).second.m_nParam2
633 : (*aIter).second.m_nParam1);
640 OUString aAttrValue( rAttrValue );
641 sal_uInt16 nValPrefix =
642 static_cast<sal_uInt16
>((*aIter).second.m_nParam1);
656 OUString aAttrValue( rAttrValue );
657 sal_uInt16 nValPrefix =
658 static_cast<sal_uInt16
>(
659 bRename ? (*aIter).second.m_nParam2
660 : (*aIter).second.m_nParam1);
667 OUString aAttrValue( rAttrValue );
674 OUString aAttrValue( rAttrValue );
676 static_cast< bool >((*aIter).second.m_nParam1)))
682 OUString aAttrValue( rAttrValue );
684 static_cast< bool >((*aIter).second.m_nParam1)))
690 OUString aAttrValue( rAttrValue );
693 (*aIter).second.m_nParam1,
694 (*aIter).second.m_nParam2,
695 (*aIter).second.m_nParam3 );
701 OUString aAttrValue( rAttrValue );
708 OUString aAttrValue( rAttrValue );
716 OUString aAttrValue( rAttrValue );
721 sal_Int16
const nDestUnit =
lcl_getUnit(aAttrValue);
730 nMeasure =
static_cast<sal_Int32
>( nMeasure >= 0
731 ? ((nMeasure*72+63)/127)
732 : ((nMeasure*72-63)/127) );
736 nMeasure, util::MeasureUnit::MM_100TH,
738 aAttrValue = aBuffer.makeStringAndClear();
747 OUString aAttrValue( rAttrValue );
750 sal_Int16
const nDestUnit =
lcl_getUnit( aAttrValue );
759 else if( nMeasure < 0 )
765 util::MeasureUnit::MM_100TH, nDestUnit);
766 aAttrValue = aBuffer.makeStringAndClear();
774 OUString aAttrValue( rAttrValue );
777 sal_Int16
const nDestUnit =
lcl_getUnit( aAttrValue );
786 else if( nMeasure < 0 )
792 util::MeasureUnit::MM_100TH, nDestUnit );
793 aAttrValue = aBuffer.makeStringAndClear();
801 const sal_Int32 nLen = rAttrValue.getLength();
805 for( pos = 0; pos < nLen; pos++ )
808 if( (c >=
'0') && (c <=
'9') )
811 aBuffer.append( static_cast<sal_Int32>(c) );
823 OUString aFirstContextLocalName;
826 &aFirstContextLocalName );
827 bool bIsDocumentStyle(
834 if ( !bIsDocumentStyle )
836 OUString aAttrValue( rAttrValue );
845 OUString sNewValue =
"shape" + rAttrValue;
851 OSL_ENSURE(
false,
"unknown action" );
857 OUString aNewAttrQName(
859 (*aIter).second.GetQNamePrefixFromParam1(),
861 (*aIter).second.GetQNameTokenFromParam1()) ) );
869 return pMutableAttrList;
875 sal_Int32
nPos = rValue.getLength();
876 while( nPos && rValue[nPos-1] <=
' ' )
879 (
'c'==rValue[nPos-2] ||
'C'==rValue[nPos-2]) &&
880 (
'h'==rValue[nPos-1] ||
'H'==rValue[nPos-1]) )
882 rValue =rValue.copy( 0, nPos-2 );
893 while( nPos < rValue.getLength()-3 )
896 if(
'i'==c ||
'I'==c )
899 if( (c >=
'0' && c <=
'9') ||
'.' == c )
902 if(
'n'==c ||
'N'==c )
905 if(
'c'==c ||
'C'==c )
908 if(
'h'==c ||
'H'==c )
910 rValue = rValue.replaceAt( nPos,
930 sal_Int32
nPos = rValue.getLength();
931 while( nPos && rValue[nPos-1] <=
' ' )
934 (
'i'==rValue[nPos-2] ||
935 'I'==rValue[nPos-2]) &&
936 (
'n'==rValue[nPos-1] ||
937 'N'==rValue[nPos-1]) )
940 rValue = rValue.replaceAt( nPos, rValue.getLength() - nPos,
952 while( nPos < rValue.getLength()-1 )
955 if(
'i'==c ||
'I'==c )
958 if( (c >=
'0' && c <=
'9') ||
'.' == c )
961 if(
'n'==c ||
'N'==c )
963 rValue = rValue.replaceAt( nPos,
979 static const char aHexTab[] =
"0123456789abcdef";
981 bool bEncoded =
false;
983 sal_Int32 nLen = rName.getLength();
984 OUStringBuffer
aBuffer( nLen );
986 for( sal_Int32
i = 0;
i < nLen;
i++ )
989 bool bValidChar =
false;
993 (c >= 0x0041 && c <= 0x005a) ||
994 (c >= 0x0061 && c <= 0x007a) ||
995 (c >= 0x00c0 && c <= 0x00d6) ||
996 (c >= 0x00d8 && c <= 0x00f6) ||
997 (c >= 0x00f8 && c <= 0x00ff) ||
998 (
i > 0 && ( (c >= 0x0030 && c <= 0x0039) ||
999 c == 0x00b7 || c ==
'-' || c ==
'.') );
1003 if( (c >= 0xf900U && c <= 0xfffeU) ||
1004 (c >= 0x20ddU && c <= 0x20e0U))
1008 else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 ||
1009 c == 0x06e5 || c == 0x06e6 )
1013 else if( c == 0x0387 )
1028 case UnicodeType::UPPERCASE_LETTER:
1029 case UnicodeType::LOWERCASE_LETTER:
1030 case UnicodeType::TITLECASE_LETTER:
1031 case UnicodeType::OTHER_LETTER:
1032 case UnicodeType::LETTER_NUMBER:
1035 case UnicodeType::NON_SPACING_MARK:
1036 case UnicodeType::ENCLOSING_MARK:
1037 case UnicodeType::COMBINING_SPACING_MARK:
1038 case UnicodeType::MODIFIER_LETTER:
1039 case UnicodeType::DECIMAL_DIGIT_NUMBER:
1047 aBuffer.append( c );
1051 aBuffer.append(
'_' );
1053 aBuffer.append( static_cast< sal_Unicode >(
1054 aHexTab[ (c >> 12) & 0x0f ] ) );
1056 aBuffer.append( static_cast< sal_Unicode >(
1057 aHexTab[ (c >> 8) & 0x0f ] ) );
1059 aBuffer.append( static_cast< sal_Unicode >(
1060 aHexTab[ (c >> 4) & 0x0f ] ) );
1061 aBuffer.append( static_cast< sal_Unicode >(
1062 aHexTab[ c & 0x0f ] ) );
1063 aBuffer.append(
'_' );
1068 if( aBuffer.getLength() > (1<<15)-1 )
1072 rName = aBuffer.makeStringAndClear();
1078 bool bEncoded =
false;
1080 sal_Int32 nLen = rName.getLength();
1081 OUStringBuffer
aBuffer( nLen );
1083 bool bWithinHex =
false;
1085 for( sal_Int32
i = 0;
i < nLen;
i++ )
1092 aBuffer.append( cEnc );
1099 bWithinHex = !bWithinHex;
1101 else if( bWithinHex )
1104 if( c >=
'0' && c <=
'9' )
1108 else if( c >=
'a' && c <=
'f' )
1110 cDigit = c -
'a' + 10;
1112 else if( c >=
'A' && c <=
'F' )
1114 cDigit = c -
'A' + 10;
1122 cEnc = (cEnc << 4) + cDigit;
1126 aBuffer.append( c );
1131 rName = aBuffer.makeStringAndClear();
1142 sal_Int32 nLen = rValue.getLength();
1145 while( nPos < nLen &&
' ' == rValue[nPos] )
1148 if( nPos < nLen &&
'-' == rValue[nPos] )
1155 while( nPos < nLen &&
1156 '0' <= rValue[nPos] &&
1157 '9' >= rValue[nPos] )
1161 nVal += (rValue[nPos] -
'0');
1164 if( nPos < nLen &&
'.' == rValue[nPos] )
1169 while( nPos < nLen &&
1170 '0' <= rValue[nPos] &&
1171 '9' >= rValue[nPos] )
1175 nVal += (
static_cast<double>(rValue[nPos] -
'0') / nDiv );
1181 while( nPos < nLen &&
' ' == rValue[nPos] )
1184 if( nPos < nLen &&
'%' == rValue[nPos] )
1190 sal_Int32 nIntVal = 100 -
static_cast<sal_Int32
>( nVal );
1192 rValue = OUString::number(nIntVal) +
"%";
1201 sal_uInt16 nPrefix )
const
1207 sal_uInt16 nPrefixOnly )
const
1209 OUString aLocalName;
1210 sal_uInt16 nPrefix =
1213 (
USHRT_MAX == nPrefixOnly || nPrefix == nPrefixOnly);
1221 bool bSupportPackage )
const
1232 if( bSupportPackage )
1234 rURI = rURI.copy( 1 );
1244 if( rURI.getLength() > 1 &&
'/' == rURI[1] )
1246 rURI = rURI.copy( 2 );
1255 sal_Int32 nLen = rURI.getLength();
1256 while( nPos < nLen )
1258 switch( rURI[nPos] )
1289 bool bSupportPackage )
const
1292 if( !rURI.isEmpty() )
1294 bool bPackage =
false;
1318 sal_Int32 nLen = rURI.getLength();
1319 while( nPos < nLen )
1321 switch( rURI[nPos] )
1341 if( bPackage && bSupportPackage )
1343 OUString sTmp(
'#' );
1344 if( rURI.startsWith(
"./" ) )
1345 rURI = rURI.copy( 2 );
1356 OUString& rOutAttributeValue,
1361 return ( lcl_ConvertAttr( rOutAttributeValue, nParam1) ||
1362 lcl_ConvertAttr( rOutAttributeValue, nParam2) ||
1363 lcl_ConvertAttr( rOutAttributeValue, nParam3) );
1369 if( !rDateTime.isEmpty() &&
1370 rDateTime.indexOf(
'.' ) != -1 )
1372 rDateTime = rDateTime.replace(
'.',
',');
1381 XMLTransformerTokenMap::const_iterator aIter =
1386 return (*aIter).second;
1392 OSL_ENSURE( !
m_vContexts.empty(),
"empty stack" );
1399 sal_uInt32 n )
const
1403 OSL_ENSURE( nSize > n + 2 ,
"invalid context" );
1405 return nSize > n + 2 ?
m_vContexts[nSize - (n + 2)].
get() :
nullptr;
1410 Reference< XServiceInfo > xSI(
mxModel, UNO_QUERY );
1412 ( xSI->supportsService(
"com.sun.star.text.TextDocument") ||
1413 xSI->supportsService(
"com.sun.star.text.WebDocument") ||
1414 xSI->supportsService(
"com.sun.star.text.GlobalDocument") );
constexpr sal_uInt16 XML_NAMESPACE_MATH
constexpr sal_uInt16 XML_NAMESPACE_OOOC
constexpr sal_uInt16 XML_NAMESPACE_XLINK
constexpr sal_uInt16 XML_NAMESPACE_OOO
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
compare eToken to the string
constexpr sal_uInt16 XML_NAMESPACE_DOM
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
const sal_uInt16 XML_NAMESPACE_UNKNOWN
css::uno::Any const & rValue
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
bool isAssignableFrom(const Type &_rAssignable, const Type &_rFrom)
sal_uInt16 GetKeyByAttrValueQName(const OUString &rAttrName, OUString *pLocalName) const
XMLTokenEnum
The enumeration of all XML tokens.
bool HasQName(sal_uInt16 nPrefix,::xmloff::token::XMLTokenEnum eToken) const
void SetValueByIndex(sal_Int16 i, const OUString &rValue)
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)
void RemoveAttributeByIndex(sal_Int16 i)
void AddAttribute(const OUString &sName, const OUString &sValue)
void RenameAttributeByIndex(sal_Int16 i, const OUString &rNewName)
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
constexpr sal_uInt16 XML_NAMESPACE_DC
enumrange< T >::Iterator end(enumrange< T >)
const OUString & GetNameByKey(sal_uInt16 nKey) const
static bool NormalizeOasisURN(OUString &rName)
std::unique_ptr< char[]> aBuffer
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Handling of tokens in XML:
Reference< XComponentContext > getProcessComponentContext()
virtual bool IsPersistent() const
const OUString & GetQName() const
constexpr sal_uInt16 XML_NAMESPACE_OOOW