1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir #include <string.h> 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp> 30*cdf0e10cSrcweir #include <com/sun/star/util/XCloneable.hpp> 31*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> 32*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XParser.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/xml/sax/SAXParseException.hpp> 34*cdf0e10cSrcweir #include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSource.hpp> 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <cppuhelper/factory.hxx> 39*cdf0e10cSrcweir #include <cppuhelper/weak.hxx> 40*cdf0e10cSrcweir #include <cppuhelper/implbase3.hxx> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <rtl/strbuf.hxx> 43*cdf0e10cSrcweir #include <rtl/byteseq.hxx> 44*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir using namespace ::rtl; 47*cdf0e10cSrcweir using namespace ::std; 48*cdf0e10cSrcweir using namespace ::osl; 49*cdf0e10cSrcweir using namespace ::cppu; 50*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 51*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 52*cdf0e10cSrcweir using namespace ::com::sun::star::registry; 53*cdf0e10cSrcweir using namespace ::com::sun::star::xml::sax; 54*cdf0e10cSrcweir using namespace ::com::sun::star::util; 55*cdf0e10cSrcweir using namespace ::com::sun::star::io; 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir #include "factory.hxx" 58*cdf0e10cSrcweir #include "xml2utf.hxx" 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir #define LINEFEED 10 61*cdf0e10cSrcweir #define SEQUENCESIZE 1024 62*cdf0e10cSrcweir #define MAXCOLUMNCOUNT 72 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir /****** 65*cdf0e10cSrcweir * 66*cdf0e10cSrcweir * 67*cdf0e10cSrcweir * Character conversion functions 68*cdf0e10cSrcweir * 69*cdf0e10cSrcweir * 70*cdf0e10cSrcweir *****/ 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir namespace sax_expatwrap { 73*cdf0e10cSrcweir /***** 74*cdf0e10cSrcweir * 75*cdf0e10cSrcweir * Calculates the length of the sequence after conversion, but the conversion is not done. 76*cdf0e10cSrcweir * .g. &<>"' plus some more are 77*cdf0e10cSrcweir * special characters in XML that need to be transformed 78*cdf0e10cSrcweir * 79*cdf0e10cSrcweir * @param bConvertAll For Attributes it is necessary to convert every symbol (including line feed and tab) 80*cdf0e10cSrcweir * Set this to true, if you want to perform this special conversion 81*cdf0e10cSrcweir * @return The returned value is equal to the length of the incoming sequence, when no 82*cdf0e10cSrcweir + conversion is necessary, otherwise it is larger than the length of the sequence. 83*cdf0e10cSrcweir ****/ 84*cdf0e10cSrcweir // inline sal_Int32 CalcXMLLen( const Sequence<sal_Int8> & seq , sal_Bool bConvertAll ) throw() 85*cdf0e10cSrcweir // { 86*cdf0e10cSrcweir // sal_Int32 nLen = 0; 87*cdf0e10cSrcweir // const sal_Int8 *pArray = seq.getConstArray(); 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir // for( int i = 0 ; i < seq.getLength() ; i ++ ) { 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir // sal_Int8 c = pArray[i]; 92*cdf0e10cSrcweir // switch( c ) 93*cdf0e10cSrcweir // { 94*cdf0e10cSrcweir // case '&': // resemble to & 95*cdf0e10cSrcweir // nLen +=5; 96*cdf0e10cSrcweir // break; 97*cdf0e10cSrcweir // case '<': // < 98*cdf0e10cSrcweir // case '>': // > 99*cdf0e10cSrcweir // nLen +=4; 100*cdf0e10cSrcweir // break; 101*cdf0e10cSrcweir // case 39: // 39 == ''', ' 102*cdf0e10cSrcweir // case '"': // " 103*cdf0e10cSrcweir // case 13: // 
 104*cdf0e10cSrcweir // nLen += 6; 105*cdf0e10cSrcweir // break; 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir // case 10: // 
 108*cdf0e10cSrcweir // case 9: // 	 109*cdf0e10cSrcweir // if( bConvertAll ) 110*cdf0e10cSrcweir // { 111*cdf0e10cSrcweir // nLen += 6; // 112*cdf0e10cSrcweir // } 113*cdf0e10cSrcweir // break; 114*cdf0e10cSrcweir // default: 115*cdf0e10cSrcweir // nLen ++; 116*cdf0e10cSrcweir // } 117*cdf0e10cSrcweir // } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir // return nLen; 120*cdf0e10cSrcweir // } 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir enum SaxInvalidCharacterError 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir SAX_NONE, 125*cdf0e10cSrcweir SAX_WARNING, 126*cdf0e10cSrcweir SAX_ERROR 127*cdf0e10cSrcweir }; 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir class SaxWriterHelper 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir Reference< XOutputStream > m_out; 132*cdf0e10cSrcweir Sequence < sal_Int8 > m_Sequence; 133*cdf0e10cSrcweir sal_Int8* mp_Sequence; 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir sal_Int32 nLastLineFeedPos; // is negative after writing a sequence 136*cdf0e10cSrcweir sal_uInt32 nCurrentPos; 137*cdf0e10cSrcweir sal_Bool m_bStartElementFinished; 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir inline sal_uInt32 writeSequence() throw( SAXException ); 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir // use only if to insert the bytes more space in the sequence is needed and 143*cdf0e10cSrcweir // so the sequence has to write out and reset rPos to 0 144*cdf0e10cSrcweir // writes sequence only on overflow, sequence could be full on the end (rPos == SEQUENCESIZE) 145*cdf0e10cSrcweir inline void AddBytes(sal_Int8* pTarget, sal_uInt32& rPos, 146*cdf0e10cSrcweir const sal_Int8* pBytes, sal_uInt32 nBytesCount) throw( SAXException ); 147*cdf0e10cSrcweir inline sal_Bool convertToXML(const sal_Unicode * pStr, 148*cdf0e10cSrcweir sal_Int32 nStrLen, 149*cdf0e10cSrcweir sal_Bool bDoNormalization, 150*cdf0e10cSrcweir sal_Bool bNormalizeWhitespace, 151*cdf0e10cSrcweir sal_Int8 *pTarget, 152*cdf0e10cSrcweir sal_uInt32& rPos) throw( SAXException ); 153*cdf0e10cSrcweir inline void FinishStartElement() throw( SAXException ); 154*cdf0e10cSrcweir public: 155*cdf0e10cSrcweir SaxWriterHelper(Reference< XOutputStream > m_TempOut) : 156*cdf0e10cSrcweir m_out(m_TempOut), 157*cdf0e10cSrcweir m_Sequence(SEQUENCESIZE), 158*cdf0e10cSrcweir mp_Sequence(NULL), 159*cdf0e10cSrcweir nLastLineFeedPos(0), 160*cdf0e10cSrcweir nCurrentPos(0), 161*cdf0e10cSrcweir m_bStartElementFinished(sal_True) 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir OSL_ENSURE(SEQUENCESIZE > 50, "Sequence cache size to small"); 164*cdf0e10cSrcweir mp_Sequence = m_Sequence.getArray(); 165*cdf0e10cSrcweir } 166*cdf0e10cSrcweir ~SaxWriterHelper() 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir OSL_ENSURE(!nCurrentPos, "cached Sequence not written"); 169*cdf0e10cSrcweir OSL_ENSURE(m_bStartElementFinished, "StartElement not complettly written"); 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir inline void insertIndentation(sal_uInt32 m_nLevel) throw( SAXException ); 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir // returns whether it works correct or invalid characters were in the string 175*cdf0e10cSrcweir // If there are invalid characters in the string it returns sal_False. 176*cdf0e10cSrcweir // Than the calling method has to throw the needed Exception. 177*cdf0e10cSrcweir inline sal_Bool writeString(const rtl::OUString& rWriteOutString, 178*cdf0e10cSrcweir sal_Bool bDoNormalization, 179*cdf0e10cSrcweir sal_Bool bNormalizeWhitespace) throw( SAXException ); 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir sal_uInt32 GetLastColumnCount() { return (sal_uInt32)(nCurrentPos - nLastLineFeedPos); } 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir inline void startDocument() throw( SAXException ); 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir // returns whether it works correct or invalid characters were in the strings 186*cdf0e10cSrcweir // If there are invalid characters in one of the strings it returns sal_False. 187*cdf0e10cSrcweir // Than the calling method has to throw the needed Exception. 188*cdf0e10cSrcweir inline SaxInvalidCharacterError startElement(const rtl::OUString& rName, const Reference< XAttributeList >& xAttribs) throw( SAXException ); 189*cdf0e10cSrcweir inline sal_Bool FinishEmptyElement() throw( SAXException ); 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir // returns whether it works correct or invalid characters were in the string 192*cdf0e10cSrcweir // If there are invalid characters in the string it returns sal_False. 193*cdf0e10cSrcweir // Than the calling method has to throw the needed Exception. 194*cdf0e10cSrcweir inline sal_Bool endElement(const rtl::OUString& rName) throw( SAXException ); 195*cdf0e10cSrcweir inline void endDocument() throw( SAXException ); 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir // returns whether it works correct or invalid characters were in the strings 198*cdf0e10cSrcweir // If there are invalid characters in the string it returns sal_False. 199*cdf0e10cSrcweir // Than the calling method has to throw the needed Exception. 200*cdf0e10cSrcweir inline sal_Bool processingInstruction(const rtl::OUString& rTarget, const rtl::OUString& rData) throw( SAXException ); 201*cdf0e10cSrcweir inline void startCDATA() throw( SAXException ); 202*cdf0e10cSrcweir inline void endCDATA() throw( SAXException ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir // returns whether it works correct or invalid characters were in the strings 205*cdf0e10cSrcweir // If there are invalid characters in the string it returns sal_False. 206*cdf0e10cSrcweir // Than the calling method has to throw the needed Exception. 207*cdf0e10cSrcweir inline sal_Bool comment(const rtl::OUString& rComment) throw( SAXException ); 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir inline void clearBuffer() throw( SAXException ); 210*cdf0e10cSrcweir }; 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir const sal_Bool g_bValidCharsBelow32[32] = 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir // 0 1 2 3 4 5 6 7 215*cdf0e10cSrcweir 0,0,0,0,0,0,0,0, //0 216*cdf0e10cSrcweir 0,1,1,0,0,1,0,0, //8 217*cdf0e10cSrcweir 0,0,0,0,0,0,0,0, //16 218*cdf0e10cSrcweir 0,0,0,0,0,0,0,0 219*cdf0e10cSrcweir }; 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir inline sal_Bool IsInvalidChar(const sal_Unicode aChar) 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir sal_Bool bRet(sal_False); 224*cdf0e10cSrcweir // check first for the most common characters 225*cdf0e10cSrcweir if( aChar < 32 || aChar >= 0xd800 ) 226*cdf0e10cSrcweir bRet = ( (aChar < 32 && ! g_bValidCharsBelow32[aChar]) || 227*cdf0e10cSrcweir aChar == 0xffff || 228*cdf0e10cSrcweir aChar == 0xfffe ); 229*cdf0e10cSrcweir return bRet; 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir /******** 233*cdf0e10cSrcweir * write through to the output stream 234*cdf0e10cSrcweir * 235*cdf0e10cSrcweir *****/ 236*cdf0e10cSrcweir inline sal_uInt32 SaxWriterHelper::writeSequence() throw( SAXException ) 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir try 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir m_out->writeBytes( m_Sequence ); 241*cdf0e10cSrcweir } 242*cdf0e10cSrcweir catch( IOException & e ) 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir Any a; 245*cdf0e10cSrcweir a <<= e; 246*cdf0e10cSrcweir throw SAXException( 247*cdf0e10cSrcweir OUString::createFromAscii( "io exception during writing" ), 248*cdf0e10cSrcweir Reference< XInterface > (), 249*cdf0e10cSrcweir a ); 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir nLastLineFeedPos -= SEQUENCESIZE; 252*cdf0e10cSrcweir return 0; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir inline void SaxWriterHelper::AddBytes(sal_Int8* pTarget, sal_uInt32& rPos, 256*cdf0e10cSrcweir const sal_Int8* pBytes, sal_uInt32 nBytesCount) throw( SAXException ) 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir OSL_ENSURE((rPos + nBytesCount) > SEQUENCESIZE, "wrong use of AddBytesMethod"); 259*cdf0e10cSrcweir sal_uInt32 nCount(SEQUENCESIZE - rPos); 260*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , pBytes, nCount); 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir OSL_ENSURE(rPos + nCount == SEQUENCESIZE, "the position should be the at the end"); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir rPos = writeSequence(); 265*cdf0e10cSrcweir sal_uInt32 nRestCount(nBytesCount - nCount); 266*cdf0e10cSrcweir if ((rPos + nRestCount) <= SEQUENCESIZE) 267*cdf0e10cSrcweir { 268*cdf0e10cSrcweir memcpy( &(pTarget[rPos]), &pBytes[nCount], nRestCount); 269*cdf0e10cSrcweir rPos += nRestCount; 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir else 272*cdf0e10cSrcweir AddBytes(pTarget, rPos, &pBytes[nCount], nRestCount); 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir /** Converts an UTF16 string to UTF8 and does XML normalization 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir @param pTarget 278*cdf0e10cSrcweir Pointer to a piece of memory, to where the output should be written. The caller 279*cdf0e10cSrcweir must call calcXMLByteLength on the same string, to ensure, 280*cdf0e10cSrcweir that there is enough memory for converting. 281*cdf0e10cSrcweir */ 282*cdf0e10cSrcweir inline sal_Bool SaxWriterHelper::convertToXML( const sal_Unicode * pStr, 283*cdf0e10cSrcweir sal_Int32 nStrLen, 284*cdf0e10cSrcweir sal_Bool bDoNormalization, 285*cdf0e10cSrcweir sal_Bool bNormalizeWhitespace, 286*cdf0e10cSrcweir sal_Int8 *pTarget, 287*cdf0e10cSrcweir sal_uInt32& rPos ) throw( SAXException ) 288*cdf0e10cSrcweir { 289*cdf0e10cSrcweir sal_Bool bRet(sal_True); 290*cdf0e10cSrcweir sal_uInt32 nSurrogate = 0; 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir for( sal_Int32 i = 0 ; i < nStrLen ; i ++ ) 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir sal_uInt16 c = pStr[i]; 295*cdf0e10cSrcweir if (IsInvalidChar(c)) 296*cdf0e10cSrcweir bRet = sal_False; 297*cdf0e10cSrcweir else if( (c >= 0x0001) && (c <= 0x007F) ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir if( bDoNormalization ) 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir switch( c ) 302*cdf0e10cSrcweir { 303*cdf0e10cSrcweir case '&': // resemble to & 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir if ((rPos + 5) > SEQUENCESIZE) 306*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"&", 5); 307*cdf0e10cSrcweir else 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "&", 5 ); 310*cdf0e10cSrcweir rPos += 5; 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir break; 314*cdf0e10cSrcweir case '<': 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir if ((rPos + 4) > SEQUENCESIZE) 317*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"<", 4); 318*cdf0e10cSrcweir else 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "<" , 4 ); 321*cdf0e10cSrcweir rPos += 4; // < 322*cdf0e10cSrcweir } 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir break; 325*cdf0e10cSrcweir case '>': 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir if ((rPos + 4) > SEQUENCESIZE) 328*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)">", 4); 329*cdf0e10cSrcweir else 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , ">" , 4 ); 332*cdf0e10cSrcweir rPos += 4; // > 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir break; 336*cdf0e10cSrcweir case 39: // 39 == ''' 337*cdf0e10cSrcweir { 338*cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE) 339*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"'", 6); 340*cdf0e10cSrcweir else 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "'" , 6 ); 343*cdf0e10cSrcweir rPos += 6; // ' 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir break; 347*cdf0e10cSrcweir case '"': 348*cdf0e10cSrcweir { 349*cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE) 350*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)""", 6); 351*cdf0e10cSrcweir else 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , """ , 6 ); 354*cdf0e10cSrcweir rPos += 6; // " 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir break; 358*cdf0e10cSrcweir case 13: 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE) 361*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"
", 6); 362*cdf0e10cSrcweir else 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "
" , 6 ); 365*cdf0e10cSrcweir rPos += 6; 366*cdf0e10cSrcweir } 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir break; 369*cdf0e10cSrcweir case LINEFEED: 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir if( bNormalizeWhitespace ) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE) 374*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"
" , 6); 375*cdf0e10cSrcweir else 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "
" , 6 ); 378*cdf0e10cSrcweir rPos += 6; 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir else 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir pTarget[rPos] = LINEFEED; 384*cdf0e10cSrcweir nLastLineFeedPos = rPos; 385*cdf0e10cSrcweir rPos ++; 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir break; 389*cdf0e10cSrcweir case 9: 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir if( bNormalizeWhitespace ) 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE) 394*cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"	" , 6); 395*cdf0e10cSrcweir else 396*cdf0e10cSrcweir { 397*cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "	" , 6 ); 398*cdf0e10cSrcweir rPos += 6; 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir } 401*cdf0e10cSrcweir else 402*cdf0e10cSrcweir { 403*cdf0e10cSrcweir pTarget[rPos] = 9; 404*cdf0e10cSrcweir rPos ++; 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir break; 408*cdf0e10cSrcweir default: 409*cdf0e10cSrcweir { 410*cdf0e10cSrcweir pTarget[rPos] = (sal_Int8)c; 411*cdf0e10cSrcweir rPos ++; 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir break; 414*cdf0e10cSrcweir } 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir else 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir pTarget[rPos] = (sal_Int8)c; 419*cdf0e10cSrcweir if ((sal_Int8)c == LINEFEED) 420*cdf0e10cSrcweir nLastLineFeedPos = rPos; 421*cdf0e10cSrcweir rPos ++; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir else if( c >= 0xd800 && c < 0xdc00 ) 425*cdf0e10cSrcweir { 426*cdf0e10cSrcweir // 1. surrogate: save (until 2. surrogate) 427*cdf0e10cSrcweir OSL_ENSURE( nSurrogate == 0, "left-over Unicode surrogate" ); 428*cdf0e10cSrcweir nSurrogate = ( ( c & 0x03ff ) + 0x0040 ); 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir else if( c >= 0xdc00 && c < 0xe000 ) 431*cdf0e10cSrcweir { 432*cdf0e10cSrcweir // 2. surrogate: write as UTF-8 433*cdf0e10cSrcweir OSL_ENSURE( nSurrogate != 0, "lone 2nd Unicode surrogate" ); 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir nSurrogate = ( nSurrogate << 10 ) | ( c & 0x03ff ); 436*cdf0e10cSrcweir if( nSurrogate >= 0x00010000 && nSurrogate <= 0x0010FFFF ) 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir sal_Int8 aBytes[] = { sal_Int8(0xF0 | ((nSurrogate >> 18) & 0x0F)), 439*cdf0e10cSrcweir sal_Int8(0x80 | ((nSurrogate >> 12) & 0x3F)), 440*cdf0e10cSrcweir sal_Int8(0x80 | ((nSurrogate >> 6) & 0x3F)), 441*cdf0e10cSrcweir sal_Int8(0x80 | ((nSurrogate >> 0) & 0x3F)) }; 442*cdf0e10cSrcweir if ((rPos + 4) > SEQUENCESIZE) 443*cdf0e10cSrcweir AddBytes(pTarget, rPos, aBytes, 4); 444*cdf0e10cSrcweir else 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir pTarget[rPos] = aBytes[0]; 447*cdf0e10cSrcweir rPos ++; 448*cdf0e10cSrcweir pTarget[rPos] = aBytes[1]; 449*cdf0e10cSrcweir rPos ++; 450*cdf0e10cSrcweir pTarget[rPos] = aBytes[2]; 451*cdf0e10cSrcweir rPos ++; 452*cdf0e10cSrcweir pTarget[rPos] = aBytes[3]; 453*cdf0e10cSrcweir rPos ++; 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir } 456*cdf0e10cSrcweir else 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir OSL_ENSURE( false, "illegal Unicode character" ); 459*cdf0e10cSrcweir bRet = sal_False; 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir // reset surrogate 463*cdf0e10cSrcweir nSurrogate = 0; 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir else if( c > 0x07FF ) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir sal_Int8 aBytes[] = { sal_Int8(0xE0 | ((c >> 12) & 0x0F)), 468*cdf0e10cSrcweir sal_Int8(0x80 | ((c >> 6) & 0x3F)), 469*cdf0e10cSrcweir sal_Int8(0x80 | ((c >> 0) & 0x3F)) }; 470*cdf0e10cSrcweir if ((rPos + 3) > SEQUENCESIZE) 471*cdf0e10cSrcweir AddBytes(pTarget, rPos, aBytes, 3); 472*cdf0e10cSrcweir else 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir pTarget[rPos] = aBytes[0]; 475*cdf0e10cSrcweir rPos ++; 476*cdf0e10cSrcweir pTarget[rPos] = aBytes[1]; 477*cdf0e10cSrcweir rPos ++; 478*cdf0e10cSrcweir pTarget[rPos] = aBytes[2]; 479*cdf0e10cSrcweir rPos ++; 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir else 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir sal_Int8 aBytes[] = { sal_Int8(0xC0 | ((c >> 6) & 0x1F)), 485*cdf0e10cSrcweir sal_Int8(0x80 | ((c >> 0) & 0x3F)) }; 486*cdf0e10cSrcweir if ((rPos + 2) > SEQUENCESIZE) 487*cdf0e10cSrcweir AddBytes(pTarget, rPos, aBytes, 2); 488*cdf0e10cSrcweir else 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir pTarget[rPos] = aBytes[0]; 491*cdf0e10cSrcweir rPos ++; 492*cdf0e10cSrcweir pTarget[rPos] = aBytes[1]; 493*cdf0e10cSrcweir rPos ++; 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir } 496*cdf0e10cSrcweir OSL_ENSURE(rPos <= SEQUENCESIZE, "not reset current position"); 497*cdf0e10cSrcweir if (rPos == SEQUENCESIZE) 498*cdf0e10cSrcweir rPos = writeSequence(); 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir // reset left-over surrogate 501*cdf0e10cSrcweir if( ( nSurrogate != 0 ) && !( c >= 0xd800 && c < 0xdc00 ) ) 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir OSL_ENSURE( nSurrogate != 0, "left-over Unicode surrogate" ); 504*cdf0e10cSrcweir nSurrogate = 0; 505*cdf0e10cSrcweir bRet = sal_False; 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir return bRet; 509*cdf0e10cSrcweir } 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir inline void SaxWriterHelper::FinishStartElement() throw( SAXException ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir if (!m_bStartElementFinished) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '>'; 516*cdf0e10cSrcweir nCurrentPos++; 517*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 518*cdf0e10cSrcweir nCurrentPos = writeSequence(); 519*cdf0e10cSrcweir m_bStartElementFinished = sal_True; 520*cdf0e10cSrcweir } 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir inline void SaxWriterHelper::insertIndentation(sal_uInt32 m_nLevel) throw( SAXException ) 524*cdf0e10cSrcweir { 525*cdf0e10cSrcweir FinishStartElement(); 526*cdf0e10cSrcweir if (m_nLevel > 0) 527*cdf0e10cSrcweir { 528*cdf0e10cSrcweir if ((nCurrentPos + m_nLevel + 1) <= SEQUENCESIZE) 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = LINEFEED; 531*cdf0e10cSrcweir nLastLineFeedPos = nCurrentPos; 532*cdf0e10cSrcweir nCurrentPos++; 533*cdf0e10cSrcweir memset( &(mp_Sequence[nCurrentPos]) , 32 , m_nLevel ); 534*cdf0e10cSrcweir nCurrentPos += m_nLevel; 535*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 536*cdf0e10cSrcweir nCurrentPos = writeSequence(); 537*cdf0e10cSrcweir } 538*cdf0e10cSrcweir else 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir sal_uInt32 nCount(m_nLevel + 1); 541*cdf0e10cSrcweir sal_Int8* pBytes = new sal_Int8[nCount]; 542*cdf0e10cSrcweir pBytes[0] = LINEFEED; 543*cdf0e10cSrcweir memset( &(pBytes[1]), 32, m_nLevel ); 544*cdf0e10cSrcweir AddBytes(mp_Sequence, nCurrentPos, pBytes, nCount); 545*cdf0e10cSrcweir delete[] pBytes; 546*cdf0e10cSrcweir nLastLineFeedPos = nCurrentPos - nCount; 547*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 548*cdf0e10cSrcweir nCurrentPos = writeSequence(); 549*cdf0e10cSrcweir } 550*cdf0e10cSrcweir } 551*cdf0e10cSrcweir else 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = LINEFEED; 554*cdf0e10cSrcweir nLastLineFeedPos = nCurrentPos; 555*cdf0e10cSrcweir nCurrentPos++; 556*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 557*cdf0e10cSrcweir nCurrentPos = writeSequence(); 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir inline sal_Bool SaxWriterHelper::writeString( const rtl::OUString& rWriteOutString, 562*cdf0e10cSrcweir sal_Bool bDoNormalization, 563*cdf0e10cSrcweir sal_Bool bNormalizeWhitespace ) throw( SAXException ) 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir FinishStartElement(); 566*cdf0e10cSrcweir return convertToXML(rWriteOutString.getStr(), 567*cdf0e10cSrcweir rWriteOutString.getLength(), 568*cdf0e10cSrcweir bDoNormalization, 569*cdf0e10cSrcweir bNormalizeWhitespace, 570*cdf0e10cSrcweir mp_Sequence, 571*cdf0e10cSrcweir nCurrentPos); 572*cdf0e10cSrcweir } 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir inline void SaxWriterHelper::startDocument() throw( SAXException ) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir const char pc[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 577*cdf0e10cSrcweir const int nLen = strlen( pc ); 578*cdf0e10cSrcweir if ((nCurrentPos + nLen) <= SEQUENCESIZE) 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir memcpy( mp_Sequence, pc , nLen ); 581*cdf0e10cSrcweir nCurrentPos += nLen; 582*cdf0e10cSrcweir } 583*cdf0e10cSrcweir else 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)pc, nLen); 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir OSL_ENSURE(nCurrentPos <= SEQUENCESIZE, "not reset current position"); 588*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 589*cdf0e10cSrcweir nCurrentPos = writeSequence(); 590*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = LINEFEED; 591*cdf0e10cSrcweir nCurrentPos++; 592*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 593*cdf0e10cSrcweir nCurrentPos = writeSequence(); 594*cdf0e10cSrcweir } 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir inline SaxInvalidCharacterError SaxWriterHelper::startElement(const rtl::OUString& rName, const Reference< XAttributeList >& xAttribs) throw( SAXException ) 597*cdf0e10cSrcweir { 598*cdf0e10cSrcweir FinishStartElement(); 599*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '<'; 600*cdf0e10cSrcweir nCurrentPos++; 601*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 602*cdf0e10cSrcweir nCurrentPos = writeSequence(); 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir SaxInvalidCharacterError eRet(SAX_NONE); 605*cdf0e10cSrcweir if (!writeString(rName, sal_False, sal_False)) 606*cdf0e10cSrcweir eRet = SAX_ERROR; 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir sal_Int16 nAttribCount = xAttribs.is() ? static_cast<sal_Int16>(xAttribs->getLength()) : 0; 609*cdf0e10cSrcweir for(sal_Int16 i = 0 ; i < nAttribCount ; i++ ) 610*cdf0e10cSrcweir { 611*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = ' '; 612*cdf0e10cSrcweir nCurrentPos++; 613*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 614*cdf0e10cSrcweir nCurrentPos = writeSequence(); 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir if (!writeString(xAttribs->getNameByIndex( i ), sal_False, sal_False)) 617*cdf0e10cSrcweir eRet = SAX_ERROR; 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '='; 620*cdf0e10cSrcweir nCurrentPos++; 621*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 622*cdf0e10cSrcweir nCurrentPos = writeSequence(); 623*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '"'; 624*cdf0e10cSrcweir nCurrentPos++; 625*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 626*cdf0e10cSrcweir nCurrentPos = writeSequence(); 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir if (!writeString(xAttribs->getValueByIndex( i ), sal_True, sal_True) && 629*cdf0e10cSrcweir !(eRet == SAX_ERROR)) 630*cdf0e10cSrcweir eRet = SAX_WARNING; 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '"'; 633*cdf0e10cSrcweir nCurrentPos++; 634*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 635*cdf0e10cSrcweir nCurrentPos = writeSequence(); 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir m_bStartElementFinished = sal_False; // because the '>' character is not added, 639*cdf0e10cSrcweir // because it is possible, that the "/>" 640*cdf0e10cSrcweir // characters have to add 641*cdf0e10cSrcweir return eRet; 642*cdf0e10cSrcweir } 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir inline sal_Bool SaxWriterHelper::FinishEmptyElement() throw( SAXException ) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir if (m_bStartElementFinished) 647*cdf0e10cSrcweir return sal_False; 648*cdf0e10cSrcweir 649*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '/'; 650*cdf0e10cSrcweir nCurrentPos++; 651*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 652*cdf0e10cSrcweir nCurrentPos = writeSequence(); 653*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '>'; 654*cdf0e10cSrcweir nCurrentPos++; 655*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 656*cdf0e10cSrcweir nCurrentPos = writeSequence(); 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir m_bStartElementFinished = sal_True; 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir return sal_True; 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir 663*cdf0e10cSrcweir inline sal_Bool SaxWriterHelper::endElement(const rtl::OUString& rName) throw( SAXException ) 664*cdf0e10cSrcweir { 665*cdf0e10cSrcweir FinishStartElement(); 666*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '<'; 667*cdf0e10cSrcweir nCurrentPos++; 668*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 669*cdf0e10cSrcweir nCurrentPos = writeSequence(); 670*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '/'; 671*cdf0e10cSrcweir nCurrentPos++; 672*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 673*cdf0e10cSrcweir nCurrentPos = writeSequence(); 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir sal_Bool bRet(writeString( rName, sal_False, sal_False)); 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '>'; 678*cdf0e10cSrcweir nCurrentPos++; 679*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 680*cdf0e10cSrcweir nCurrentPos = writeSequence(); 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir return bRet; 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir inline void SaxWriterHelper::endDocument() throw( SAXException ) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir if (nCurrentPos > 0) 688*cdf0e10cSrcweir { 689*cdf0e10cSrcweir m_Sequence.realloc(nCurrentPos); 690*cdf0e10cSrcweir nCurrentPos = writeSequence(); 691*cdf0e10cSrcweir //m_Sequence.realloc(SEQUENCESIZE); 692*cdf0e10cSrcweir } 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir inline void SaxWriterHelper::clearBuffer() throw( SAXException ) 696*cdf0e10cSrcweir { 697*cdf0e10cSrcweir FinishStartElement(); 698*cdf0e10cSrcweir if (nCurrentPos > 0) 699*cdf0e10cSrcweir { 700*cdf0e10cSrcweir m_Sequence.realloc(nCurrentPos); 701*cdf0e10cSrcweir nCurrentPos = writeSequence(); 702*cdf0e10cSrcweir m_Sequence.realloc(SEQUENCESIZE); 703*cdf0e10cSrcweir // Be sure to update the array pointer after the reallocation. 704*cdf0e10cSrcweir mp_Sequence = m_Sequence.getArray(); 705*cdf0e10cSrcweir } 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir inline sal_Bool SaxWriterHelper::processingInstruction(const rtl::OUString& rTarget, const rtl::OUString& rData) throw( SAXException ) 709*cdf0e10cSrcweir { 710*cdf0e10cSrcweir FinishStartElement(); 711*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '<'; 712*cdf0e10cSrcweir nCurrentPos++; 713*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 714*cdf0e10cSrcweir nCurrentPos = writeSequence(); 715*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '?'; 716*cdf0e10cSrcweir nCurrentPos++; 717*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 718*cdf0e10cSrcweir nCurrentPos = writeSequence(); 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir sal_Bool bRet(writeString( rTarget, sal_False, sal_False )); 721*cdf0e10cSrcweir 722*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = ' '; 723*cdf0e10cSrcweir nCurrentPos++; 724*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 725*cdf0e10cSrcweir nCurrentPos = writeSequence(); 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir if (!writeString( rData, sal_False, sal_False )) 728*cdf0e10cSrcweir bRet = sal_False; 729*cdf0e10cSrcweir 730*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '?'; 731*cdf0e10cSrcweir nCurrentPos++; 732*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 733*cdf0e10cSrcweir nCurrentPos = writeSequence(); 734*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '>'; 735*cdf0e10cSrcweir nCurrentPos++; 736*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 737*cdf0e10cSrcweir nCurrentPos = writeSequence(); 738*cdf0e10cSrcweir 739*cdf0e10cSrcweir return bRet; 740*cdf0e10cSrcweir } 741*cdf0e10cSrcweir 742*cdf0e10cSrcweir inline void SaxWriterHelper::startCDATA() throw( SAXException ) 743*cdf0e10cSrcweir { 744*cdf0e10cSrcweir FinishStartElement(); 745*cdf0e10cSrcweir if ((nCurrentPos + 9) <= SEQUENCESIZE) 746*cdf0e10cSrcweir { 747*cdf0e10cSrcweir memcpy( &(mp_Sequence[nCurrentPos]), "<![CDATA[" , 9 ); 748*cdf0e10cSrcweir nCurrentPos += 9; 749*cdf0e10cSrcweir } 750*cdf0e10cSrcweir else 751*cdf0e10cSrcweir AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)"<![CDATA[" , 9); 752*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 753*cdf0e10cSrcweir nCurrentPos = writeSequence(); 754*cdf0e10cSrcweir } 755*cdf0e10cSrcweir 756*cdf0e10cSrcweir inline void SaxWriterHelper::endCDATA() throw( SAXException ) 757*cdf0e10cSrcweir { 758*cdf0e10cSrcweir FinishStartElement(); 759*cdf0e10cSrcweir if ((nCurrentPos + 3) <= SEQUENCESIZE) 760*cdf0e10cSrcweir { 761*cdf0e10cSrcweir memcpy( &(mp_Sequence[nCurrentPos]), "]]>" , 3 ); 762*cdf0e10cSrcweir nCurrentPos += 3; 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir else 765*cdf0e10cSrcweir AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)"]]>" , 3); 766*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 767*cdf0e10cSrcweir nCurrentPos = writeSequence(); 768*cdf0e10cSrcweir } 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir inline sal_Bool SaxWriterHelper::comment(const rtl::OUString& rComment) throw( SAXException ) 771*cdf0e10cSrcweir { 772*cdf0e10cSrcweir FinishStartElement(); 773*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '<'; 774*cdf0e10cSrcweir nCurrentPos++; 775*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 776*cdf0e10cSrcweir nCurrentPos = writeSequence(); 777*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '!'; 778*cdf0e10cSrcweir nCurrentPos++; 779*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 780*cdf0e10cSrcweir nCurrentPos = writeSequence(); 781*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '-'; 782*cdf0e10cSrcweir nCurrentPos++; 783*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 784*cdf0e10cSrcweir nCurrentPos = writeSequence(); 785*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '-'; 786*cdf0e10cSrcweir nCurrentPos++; 787*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 788*cdf0e10cSrcweir nCurrentPos = writeSequence(); 789*cdf0e10cSrcweir 790*cdf0e10cSrcweir sal_Bool bRet(writeString( rComment, sal_False, sal_False)); 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '-'; 793*cdf0e10cSrcweir nCurrentPos++; 794*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 795*cdf0e10cSrcweir nCurrentPos = writeSequence(); 796*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '-'; 797*cdf0e10cSrcweir nCurrentPos++; 798*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 799*cdf0e10cSrcweir nCurrentPos = writeSequence(); 800*cdf0e10cSrcweir mp_Sequence[nCurrentPos] = '>'; 801*cdf0e10cSrcweir nCurrentPos++; 802*cdf0e10cSrcweir if (nCurrentPos == SEQUENCESIZE) 803*cdf0e10cSrcweir nCurrentPos = writeSequence(); 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir return bRet; 806*cdf0e10cSrcweir } 807*cdf0e10cSrcweir 808*cdf0e10cSrcweir inline sal_Int32 calcXMLByteLength( const sal_Unicode *pStr, sal_Int32 nStrLen, 809*cdf0e10cSrcweir sal_Bool bDoNormalization, 810*cdf0e10cSrcweir sal_Bool bNormalizeWhitespace ) 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir sal_Int32 nOutputLength = 0; 813*cdf0e10cSrcweir sal_uInt32 nSurrogate = 0; 814*cdf0e10cSrcweir 815*cdf0e10cSrcweir for( sal_Int32 i = 0 ; i < nStrLen ; i++ ) 816*cdf0e10cSrcweir { 817*cdf0e10cSrcweir sal_uInt16 c = pStr[i]; 818*cdf0e10cSrcweir if( !IsInvalidChar(c) && (c >= 0x0001) && (c <= 0x007F) ) 819*cdf0e10cSrcweir { 820*cdf0e10cSrcweir if( bDoNormalization ) 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir switch( c ) 823*cdf0e10cSrcweir { 824*cdf0e10cSrcweir case '&': // resemble to & 825*cdf0e10cSrcweir nOutputLength +=5; 826*cdf0e10cSrcweir break; 827*cdf0e10cSrcweir case '<': // < 828*cdf0e10cSrcweir case '>': // > 829*cdf0e10cSrcweir nOutputLength +=4; 830*cdf0e10cSrcweir break; 831*cdf0e10cSrcweir case 39: // 39 == ''', ' 832*cdf0e10cSrcweir case '"': // " 833*cdf0e10cSrcweir case 13: // 
 834*cdf0e10cSrcweir nOutputLength += 6; 835*cdf0e10cSrcweir break; 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir case 10: // 
 838*cdf0e10cSrcweir case 9: // 	 839*cdf0e10cSrcweir if( bNormalizeWhitespace ) 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir nOutputLength += 6; // 842*cdf0e10cSrcweir } 843*cdf0e10cSrcweir else 844*cdf0e10cSrcweir { 845*cdf0e10cSrcweir nOutputLength ++; 846*cdf0e10cSrcweir } 847*cdf0e10cSrcweir break; 848*cdf0e10cSrcweir default: 849*cdf0e10cSrcweir nOutputLength ++; 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir } 852*cdf0e10cSrcweir else 853*cdf0e10cSrcweir { 854*cdf0e10cSrcweir nOutputLength ++; 855*cdf0e10cSrcweir } 856*cdf0e10cSrcweir } 857*cdf0e10cSrcweir else if( c >= 0xd800 && c < 0xdc00 ) 858*cdf0e10cSrcweir { 859*cdf0e10cSrcweir // save surrogate 860*cdf0e10cSrcweir nSurrogate = ( ( c & 0x03ff ) + 0x0040 ); 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir else if( c >= 0xdc00 && c < 0xe000 ) 863*cdf0e10cSrcweir { 864*cdf0e10cSrcweir // 2. surrogate: write as UTF-8 (if range is OK 865*cdf0e10cSrcweir nSurrogate = ( nSurrogate << 10 ) | ( c & 0x03ff ); 866*cdf0e10cSrcweir if( nSurrogate >= 0x00010000 && nSurrogate <= 0x0010FFFF ) 867*cdf0e10cSrcweir nOutputLength += 4; 868*cdf0e10cSrcweir nSurrogate = 0; 869*cdf0e10cSrcweir } 870*cdf0e10cSrcweir else if( c > 0x07FF ) 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir nOutputLength += 3; 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir else 875*cdf0e10cSrcweir { 876*cdf0e10cSrcweir nOutputLength += 2; 877*cdf0e10cSrcweir } 878*cdf0e10cSrcweir 879*cdf0e10cSrcweir // surrogate processing 880*cdf0e10cSrcweir if( ( nSurrogate != 0 ) && !( c >= 0xd800 && c < 0xdc00 ) ) 881*cdf0e10cSrcweir nSurrogate = 0; 882*cdf0e10cSrcweir } 883*cdf0e10cSrcweir 884*cdf0e10cSrcweir return nOutputLength; 885*cdf0e10cSrcweir } 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir /** returns position of first ascii 10 within the string, -1 when no 10 in string. 888*cdf0e10cSrcweir */ 889*cdf0e10cSrcweir static inline sal_Int32 getFirstLineBreak( const OUString & str ) throw () 890*cdf0e10cSrcweir { 891*cdf0e10cSrcweir const sal_Unicode *pSource = str.getStr(); 892*cdf0e10cSrcweir sal_Int32 nLen = str.getLength(); 893*cdf0e10cSrcweir 894*cdf0e10cSrcweir for( int n = 0; n < nLen ; n ++ ) 895*cdf0e10cSrcweir { 896*cdf0e10cSrcweir if( LINEFEED == pSource[n] ) { 897*cdf0e10cSrcweir return n; 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir } 900*cdf0e10cSrcweir return -1; 901*cdf0e10cSrcweir } 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir /** returns position of last ascii 10 within sequence, -1 when no 10 in string. 904*cdf0e10cSrcweir */ 905*cdf0e10cSrcweir static inline sal_Int32 getLastLineBreak( const Sequence<sal_Int8> & seq) throw () 906*cdf0e10cSrcweir { 907*cdf0e10cSrcweir const sal_Int8 *pSource = seq.getConstArray(); 908*cdf0e10cSrcweir sal_Int32 nLen = seq.getLength(); 909*cdf0e10cSrcweir 910*cdf0e10cSrcweir for( int n = nLen-1; n >= 0 ; n -- ) 911*cdf0e10cSrcweir { 912*cdf0e10cSrcweir if( LINEFEED == pSource[n] ) { 913*cdf0e10cSrcweir return n; 914*cdf0e10cSrcweir } 915*cdf0e10cSrcweir } 916*cdf0e10cSrcweir return -1; 917*cdf0e10cSrcweir } 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir 920*cdf0e10cSrcweir class SAXWriter : 921*cdf0e10cSrcweir public WeakImplHelper3< 922*cdf0e10cSrcweir XActiveDataSource, 923*cdf0e10cSrcweir XExtendedDocumentHandler, 924*cdf0e10cSrcweir XServiceInfo > 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir public: 927*cdf0e10cSrcweir SAXWriter( ) : 928*cdf0e10cSrcweir m_seqStartElement(), 929*cdf0e10cSrcweir mp_SaxWriterHelper( NULL ), 930*cdf0e10cSrcweir m_bForceLineBreak(sal_False), 931*cdf0e10cSrcweir m_bAllowLineBreak(sal_False) 932*cdf0e10cSrcweir {} 933*cdf0e10cSrcweir ~SAXWriter() 934*cdf0e10cSrcweir { 935*cdf0e10cSrcweir delete mp_SaxWriterHelper; 936*cdf0e10cSrcweir } 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir public: // XActiveDataSource 939*cdf0e10cSrcweir virtual void SAL_CALL setOutputStream(const Reference< XOutputStream > & aStream) 940*cdf0e10cSrcweir throw (RuntimeException) 941*cdf0e10cSrcweir { 942*cdf0e10cSrcweir // temporary: set same stream again to clear buffer 943*cdf0e10cSrcweir if ( m_out == aStream && mp_SaxWriterHelper && m_bDocStarted ) 944*cdf0e10cSrcweir mp_SaxWriterHelper->clearBuffer(); 945*cdf0e10cSrcweir else 946*cdf0e10cSrcweir { 947*cdf0e10cSrcweir 948*cdf0e10cSrcweir m_out = aStream; 949*cdf0e10cSrcweir delete mp_SaxWriterHelper; 950*cdf0e10cSrcweir mp_SaxWriterHelper = new SaxWriterHelper(m_out); 951*cdf0e10cSrcweir m_bDocStarted = sal_False; 952*cdf0e10cSrcweir m_nLevel = 0; 953*cdf0e10cSrcweir m_bIsCDATA = sal_False; 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir } 956*cdf0e10cSrcweir } 957*cdf0e10cSrcweir virtual Reference< XOutputStream > SAL_CALL getOutputStream(void) 958*cdf0e10cSrcweir throw(RuntimeException) 959*cdf0e10cSrcweir { return m_out; } 960*cdf0e10cSrcweir 961*cdf0e10cSrcweir public: // XDocumentHandler 962*cdf0e10cSrcweir virtual void SAL_CALL startDocument(void) 963*cdf0e10cSrcweir throw(SAXException, RuntimeException); 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir virtual void SAL_CALL endDocument(void) 966*cdf0e10cSrcweir throw(SAXException, RuntimeException); 967*cdf0e10cSrcweir 968*cdf0e10cSrcweir virtual void SAL_CALL startElement(const OUString& aName, 969*cdf0e10cSrcweir const Reference< XAttributeList > & xAttribs) 970*cdf0e10cSrcweir throw (SAXException, RuntimeException); 971*cdf0e10cSrcweir 972*cdf0e10cSrcweir virtual void SAL_CALL endElement(const OUString& aName) 973*cdf0e10cSrcweir throw(SAXException, RuntimeException); 974*cdf0e10cSrcweir 975*cdf0e10cSrcweir virtual void SAL_CALL characters(const OUString& aChars) 976*cdf0e10cSrcweir throw(SAXException, RuntimeException); 977*cdf0e10cSrcweir 978*cdf0e10cSrcweir virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) 979*cdf0e10cSrcweir throw(SAXException, RuntimeException); 980*cdf0e10cSrcweir virtual void SAL_CALL processingInstruction(const OUString& aTarget, 981*cdf0e10cSrcweir const OUString& aData) 982*cdf0e10cSrcweir throw(SAXException, RuntimeException); 983*cdf0e10cSrcweir virtual void SAL_CALL setDocumentLocator(const Reference< XLocator > & xLocator) 984*cdf0e10cSrcweir throw(SAXException, RuntimeException); 985*cdf0e10cSrcweir 986*cdf0e10cSrcweir public: // XExtendedDocumentHandler 987*cdf0e10cSrcweir virtual void SAL_CALL startCDATA(void) throw(SAXException, RuntimeException); 988*cdf0e10cSrcweir virtual void SAL_CALL endCDATA(void) throw(RuntimeException); 989*cdf0e10cSrcweir virtual void SAL_CALL comment(const OUString& sComment) 990*cdf0e10cSrcweir throw(SAXException, RuntimeException); 991*cdf0e10cSrcweir virtual void SAL_CALL unknown(const OUString& sString) 992*cdf0e10cSrcweir throw(SAXException, RuntimeException); 993*cdf0e10cSrcweir virtual void SAL_CALL allowLineBreak(void) 994*cdf0e10cSrcweir throw(SAXException,RuntimeException); 995*cdf0e10cSrcweir 996*cdf0e10cSrcweir public: // XServiceInfo 997*cdf0e10cSrcweir OUString SAL_CALL getImplementationName() throw(); 998*cdf0e10cSrcweir Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(); 999*cdf0e10cSrcweir sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(); 1000*cdf0e10cSrcweir 1001*cdf0e10cSrcweir private: 1002*cdf0e10cSrcweir 1003*cdf0e10cSrcweir void writeSequence( const Sequence<sal_Int8> & seq ); 1004*cdf0e10cSrcweir sal_Int32 getIndentPrefixLength( sal_Int32 nFirstLineBreakOccurence ) throw(); 1005*cdf0e10cSrcweir 1006*cdf0e10cSrcweir Reference< XOutputStream > m_out; 1007*cdf0e10cSrcweir Sequence < sal_Int8 > m_seqStartElement; 1008*cdf0e10cSrcweir SaxWriterHelper* mp_SaxWriterHelper; 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir // Status information 1011*cdf0e10cSrcweir sal_Bool m_bDocStarted : 1; 1012*cdf0e10cSrcweir sal_Bool m_bIsCDATA : 1; 1013*cdf0e10cSrcweir sal_Bool m_bForceLineBreak : 1; 1014*cdf0e10cSrcweir sal_Bool m_bAllowLineBreak : 1; 1015*cdf0e10cSrcweir sal_Int32 m_nLevel; 1016*cdf0e10cSrcweir }; 1017*cdf0e10cSrcweir 1018*cdf0e10cSrcweir 1019*cdf0e10cSrcweir //-------------------------------------- 1020*cdf0e10cSrcweir // the extern interface 1021*cdf0e10cSrcweir //--------------------------------------- 1022*cdf0e10cSrcweir Reference < XInterface > SAL_CALL SaxWriter_CreateInstance( 1023*cdf0e10cSrcweir const Reference < XMultiServiceFactory > & ) 1024*cdf0e10cSrcweir throw (Exception) 1025*cdf0e10cSrcweir { 1026*cdf0e10cSrcweir SAXWriter *p = new SAXWriter; 1027*cdf0e10cSrcweir return Reference< XInterface > ( SAL_STATIC_CAST(OWeakObject *, p ) ); 1028*cdf0e10cSrcweir } 1029*cdf0e10cSrcweir 1030*cdf0e10cSrcweir OUString SaxWriter_getServiceName() throw() 1031*cdf0e10cSrcweir { 1032*cdf0e10cSrcweir return OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ); 1033*cdf0e10cSrcweir } 1034*cdf0e10cSrcweir 1035*cdf0e10cSrcweir OUString SaxWriter_getImplementationName() throw() 1036*cdf0e10cSrcweir { 1037*cdf0e10cSrcweir return OUString::createFromAscii( "com.sun.star.extensions.xml.sax.Writer" ); 1038*cdf0e10cSrcweir } 1039*cdf0e10cSrcweir 1040*cdf0e10cSrcweir Sequence< OUString > SaxWriter_getSupportedServiceNames(void) throw() 1041*cdf0e10cSrcweir { 1042*cdf0e10cSrcweir Sequence<OUString> aRet(1); 1043*cdf0e10cSrcweir aRet.getArray()[0] = SaxWriter_getServiceName(); 1044*cdf0e10cSrcweir return aRet; 1045*cdf0e10cSrcweir } 1046*cdf0e10cSrcweir 1047*cdf0e10cSrcweir 1048*cdf0e10cSrcweir sal_Int32 SAXWriter::getIndentPrefixLength( sal_Int32 nFirstLineBreakOccurence ) throw() 1049*cdf0e10cSrcweir { 1050*cdf0e10cSrcweir sal_Int32 nLength =-1; 1051*cdf0e10cSrcweir if (mp_SaxWriterHelper) 1052*cdf0e10cSrcweir { 1053*cdf0e10cSrcweir if ( m_bForceLineBreak || 1054*cdf0e10cSrcweir (m_bAllowLineBreak && 1055*cdf0e10cSrcweir ((nFirstLineBreakOccurence + mp_SaxWriterHelper->GetLastColumnCount()) > MAXCOLUMNCOUNT)) ) 1056*cdf0e10cSrcweir nLength = m_nLevel; 1057*cdf0e10cSrcweir } 1058*cdf0e10cSrcweir m_bForceLineBreak = sal_False; 1059*cdf0e10cSrcweir m_bAllowLineBreak = sal_False; 1060*cdf0e10cSrcweir return nLength; 1061*cdf0e10cSrcweir } 1062*cdf0e10cSrcweir 1063*cdf0e10cSrcweir static inline sal_Bool isFirstCharWhitespace( const sal_Unicode *p ) throw() 1064*cdf0e10cSrcweir { 1065*cdf0e10cSrcweir return *p == ' '; 1066*cdf0e10cSrcweir } 1067*cdf0e10cSrcweir 1068*cdf0e10cSrcweir 1069*cdf0e10cSrcweir // XServiceInfo 1070*cdf0e10cSrcweir OUString SAXWriter::getImplementationName() throw() 1071*cdf0e10cSrcweir { 1072*cdf0e10cSrcweir return SaxWriter_getImplementationName(); 1073*cdf0e10cSrcweir } 1074*cdf0e10cSrcweir 1075*cdf0e10cSrcweir // XServiceInfo 1076*cdf0e10cSrcweir sal_Bool SAXWriter::supportsService(const OUString& ServiceName) throw() 1077*cdf0e10cSrcweir { 1078*cdf0e10cSrcweir Sequence< OUString > aSNL = getSupportedServiceNames(); 1079*cdf0e10cSrcweir const OUString * pArray = aSNL.getConstArray(); 1080*cdf0e10cSrcweir 1081*cdf0e10cSrcweir for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 1082*cdf0e10cSrcweir if( pArray[i] == ServiceName ) 1083*cdf0e10cSrcweir return sal_True; 1084*cdf0e10cSrcweir 1085*cdf0e10cSrcweir return sal_False; 1086*cdf0e10cSrcweir } 1087*cdf0e10cSrcweir 1088*cdf0e10cSrcweir // XServiceInfo 1089*cdf0e10cSrcweir Sequence< OUString > SAXWriter::getSupportedServiceNames(void) throw () 1090*cdf0e10cSrcweir { 1091*cdf0e10cSrcweir Sequence<OUString> seq(1); 1092*cdf0e10cSrcweir seq.getArray()[0] = SaxWriter_getServiceName(); 1093*cdf0e10cSrcweir return seq; 1094*cdf0e10cSrcweir } 1095*cdf0e10cSrcweir 1096*cdf0e10cSrcweir 1097*cdf0e10cSrcweir 1098*cdf0e10cSrcweir void SAXWriter::startDocument() throw(SAXException, RuntimeException ) 1099*cdf0e10cSrcweir { 1100*cdf0e10cSrcweir if( m_bDocStarted || ! m_out.is() || !mp_SaxWriterHelper ) { 1101*cdf0e10cSrcweir throw SAXException(); 1102*cdf0e10cSrcweir } 1103*cdf0e10cSrcweir m_bDocStarted = sal_True; 1104*cdf0e10cSrcweir mp_SaxWriterHelper->startDocument(); 1105*cdf0e10cSrcweir } 1106*cdf0e10cSrcweir 1107*cdf0e10cSrcweir 1108*cdf0e10cSrcweir void SAXWriter::endDocument(void) throw(SAXException, RuntimeException) 1109*cdf0e10cSrcweir { 1110*cdf0e10cSrcweir if( ! m_bDocStarted ) 1111*cdf0e10cSrcweir { 1112*cdf0e10cSrcweir throw SAXException( 1113*cdf0e10cSrcweir OUString::createFromAscii( "endDocument called before startDocument" ), 1114*cdf0e10cSrcweir Reference< XInterface >() , Any() ); 1115*cdf0e10cSrcweir } 1116*cdf0e10cSrcweir if( m_nLevel ) { 1117*cdf0e10cSrcweir throw SAXException( 1118*cdf0e10cSrcweir OUString::createFromAscii( "unexpected end of document" ), 1119*cdf0e10cSrcweir Reference< XInterface >() , Any() ); 1120*cdf0e10cSrcweir } 1121*cdf0e10cSrcweir mp_SaxWriterHelper->endDocument(); 1122*cdf0e10cSrcweir try 1123*cdf0e10cSrcweir { 1124*cdf0e10cSrcweir m_out->closeOutput(); 1125*cdf0e10cSrcweir } 1126*cdf0e10cSrcweir catch( IOException & e ) 1127*cdf0e10cSrcweir { 1128*cdf0e10cSrcweir Any a; 1129*cdf0e10cSrcweir a <<= e; 1130*cdf0e10cSrcweir throw SAXException( 1131*cdf0e10cSrcweir OUString::createFromAscii( "IO exception during closing the IO Stream" ), 1132*cdf0e10cSrcweir Reference< XInterface > (), 1133*cdf0e10cSrcweir a ); 1134*cdf0e10cSrcweir } 1135*cdf0e10cSrcweir } 1136*cdf0e10cSrcweir 1137*cdf0e10cSrcweir 1138*cdf0e10cSrcweir void SAXWriter::startElement(const OUString& aName, const Reference< XAttributeList >& xAttribs) 1139*cdf0e10cSrcweir throw(SAXException, RuntimeException) 1140*cdf0e10cSrcweir { 1141*cdf0e10cSrcweir if( ! m_bDocStarted ) 1142*cdf0e10cSrcweir { 1143*cdf0e10cSrcweir SAXException except; 1144*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "startElement called before startDocument" )); 1145*cdf0e10cSrcweir throw except; 1146*cdf0e10cSrcweir } 1147*cdf0e10cSrcweir if( m_bIsCDATA ) 1148*cdf0e10cSrcweir { 1149*cdf0e10cSrcweir SAXException except; 1150*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "startElement call not allowed with CDATA sections" )); 1151*cdf0e10cSrcweir throw except; 1152*cdf0e10cSrcweir } 1153*cdf0e10cSrcweir 1154*cdf0e10cSrcweir sal_Int32 nLength(0); 1155*cdf0e10cSrcweir if (m_bAllowLineBreak) 1156*cdf0e10cSrcweir { 1157*cdf0e10cSrcweir sal_Int32 nAttribCount = xAttribs.is() ? xAttribs->getLength() : 0; 1158*cdf0e10cSrcweir 1159*cdf0e10cSrcweir nLength ++; // "<" 1160*cdf0e10cSrcweir nLength += calcXMLByteLength( aName.getStr() , aName.getLength(), 1161*cdf0e10cSrcweir sal_False, sal_False ); // the tag name 1162*cdf0e10cSrcweir 1163*cdf0e10cSrcweir sal_Int16 n; 1164*cdf0e10cSrcweir for( n = 0 ; n < static_cast<sal_Int16>(nAttribCount) ; n ++ ) { 1165*cdf0e10cSrcweir nLength ++; // " " 1166*cdf0e10cSrcweir OUString tmp = xAttribs->getNameByIndex( n ); 1167*cdf0e10cSrcweir 1168*cdf0e10cSrcweir nLength += calcXMLByteLength( tmp.getStr() , tmp.getLength() , sal_False, sal_False ); 1169*cdf0e10cSrcweir 1170*cdf0e10cSrcweir nLength += 2; // =" 1171*cdf0e10cSrcweir 1172*cdf0e10cSrcweir tmp = xAttribs->getValueByIndex( n ); 1173*cdf0e10cSrcweir 1174*cdf0e10cSrcweir nLength += calcXMLByteLength( tmp.getStr(), tmp.getLength(), sal_True, sal_True ); 1175*cdf0e10cSrcweir 1176*cdf0e10cSrcweir nLength += 1; // " 1177*cdf0e10cSrcweir } 1178*cdf0e10cSrcweir 1179*cdf0e10cSrcweir nLength ++; // '>' 1180*cdf0e10cSrcweir } 1181*cdf0e10cSrcweir 1182*cdf0e10cSrcweir // Is there a new indentation necesarry ? 1183*cdf0e10cSrcweir sal_Int32 nPrefix(getIndentPrefixLength( nLength )); 1184*cdf0e10cSrcweir 1185*cdf0e10cSrcweir // write into sequence 1186*cdf0e10cSrcweir if( nPrefix >= 0 ) 1187*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nPrefix ); 1188*cdf0e10cSrcweir 1189*cdf0e10cSrcweir SaxInvalidCharacterError eRet(mp_SaxWriterHelper->startElement(aName, xAttribs)); 1190*cdf0e10cSrcweir 1191*cdf0e10cSrcweir m_nLevel++; 1192*cdf0e10cSrcweir 1193*cdf0e10cSrcweir if (eRet == SAX_WARNING) 1194*cdf0e10cSrcweir { 1195*cdf0e10cSrcweir SAXInvalidCharacterException except; 1196*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export in a attribute value" ) ); 1197*cdf0e10cSrcweir throw except; 1198*cdf0e10cSrcweir } 1199*cdf0e10cSrcweir else if (eRet == SAX_ERROR) 1200*cdf0e10cSrcweir { 1201*cdf0e10cSrcweir SAXException except; 1202*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) ); 1203*cdf0e10cSrcweir throw except; 1204*cdf0e10cSrcweir } 1205*cdf0e10cSrcweir } 1206*cdf0e10cSrcweir 1207*cdf0e10cSrcweir void SAXWriter::endElement(const OUString& aName) throw (SAXException, RuntimeException) 1208*cdf0e10cSrcweir { 1209*cdf0e10cSrcweir if( ! m_bDocStarted ) { 1210*cdf0e10cSrcweir throw SAXException (); 1211*cdf0e10cSrcweir } 1212*cdf0e10cSrcweir m_nLevel --; 1213*cdf0e10cSrcweir 1214*cdf0e10cSrcweir if( m_nLevel < 0 ) { 1215*cdf0e10cSrcweir throw SAXException(); 1216*cdf0e10cSrcweir } 1217*cdf0e10cSrcweir sal_Bool bRet(sal_True); 1218*cdf0e10cSrcweir 1219*cdf0e10cSrcweir if( mp_SaxWriterHelper->FinishEmptyElement() ) 1220*cdf0e10cSrcweir m_bForceLineBreak = sal_False; 1221*cdf0e10cSrcweir else 1222*cdf0e10cSrcweir { 1223*cdf0e10cSrcweir // only ascii chars allowed 1224*cdf0e10cSrcweir sal_Int32 nLength(0); 1225*cdf0e10cSrcweir if (m_bAllowLineBreak) 1226*cdf0e10cSrcweir nLength = 3 + calcXMLByteLength( aName.getStr(), aName.getLength(), sal_False, sal_False ); 1227*cdf0e10cSrcweir sal_Int32 nPrefix = getIndentPrefixLength( nLength ); 1228*cdf0e10cSrcweir 1229*cdf0e10cSrcweir if( nPrefix >= 0 ) 1230*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nPrefix ); 1231*cdf0e10cSrcweir 1232*cdf0e10cSrcweir bRet = mp_SaxWriterHelper->endElement(aName); 1233*cdf0e10cSrcweir } 1234*cdf0e10cSrcweir 1235*cdf0e10cSrcweir if (!bRet) 1236*cdf0e10cSrcweir { 1237*cdf0e10cSrcweir SAXException except; 1238*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) ); 1239*cdf0e10cSrcweir throw except; 1240*cdf0e10cSrcweir } 1241*cdf0e10cSrcweir } 1242*cdf0e10cSrcweir 1243*cdf0e10cSrcweir void SAXWriter::characters(const OUString& aChars) throw(SAXException, RuntimeException) 1244*cdf0e10cSrcweir { 1245*cdf0e10cSrcweir if( ! m_bDocStarted ) 1246*cdf0e10cSrcweir { 1247*cdf0e10cSrcweir SAXException except; 1248*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "characters method called before startDocument" ) ); 1249*cdf0e10cSrcweir throw except; 1250*cdf0e10cSrcweir } 1251*cdf0e10cSrcweir 1252*cdf0e10cSrcweir sal_Bool bThrowException(sal_False); 1253*cdf0e10cSrcweir if( aChars.getLength() ) 1254*cdf0e10cSrcweir { 1255*cdf0e10cSrcweir if( m_bIsCDATA ) 1256*cdf0e10cSrcweir bThrowException = !mp_SaxWriterHelper->writeString( aChars, sal_False, sal_False ); 1257*cdf0e10cSrcweir else 1258*cdf0e10cSrcweir { 1259*cdf0e10cSrcweir // Note : nFirstLineBreakOccurence is not exact, because we don't know, how 1260*cdf0e10cSrcweir // many 2 and 3 byte chars are inbetween. However this whole stuff 1261*cdf0e10cSrcweir // is eitherway for pretty printing only, so it does not need to be exact. 1262*cdf0e10cSrcweir sal_Int32 nLength(0); 1263*cdf0e10cSrcweir sal_Int32 nIndentPrefix(-1); 1264*cdf0e10cSrcweir if (m_bAllowLineBreak) 1265*cdf0e10cSrcweir { 1266*cdf0e10cSrcweir sal_Int32 nFirstLineBreakOccurence = getFirstLineBreak( aChars ); 1267*cdf0e10cSrcweir 1268*cdf0e10cSrcweir nLength = calcXMLByteLength( aChars.getStr(), aChars.getLength(), 1269*cdf0e10cSrcweir ! m_bIsCDATA , sal_False ); 1270*cdf0e10cSrcweir nIndentPrefix = getIndentPrefixLength( 1271*cdf0e10cSrcweir nFirstLineBreakOccurence >= 0 ? nFirstLineBreakOccurence : nLength ); 1272*cdf0e10cSrcweir } 1273*cdf0e10cSrcweir else 1274*cdf0e10cSrcweir nIndentPrefix = getIndentPrefixLength(nLength); 1275*cdf0e10cSrcweir 1276*cdf0e10cSrcweir // insert indentation 1277*cdf0e10cSrcweir if( nIndentPrefix >= 0 ) 1278*cdf0e10cSrcweir { 1279*cdf0e10cSrcweir if( isFirstCharWhitespace( aChars.getStr() ) ) 1280*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nIndentPrefix - 1 ); 1281*cdf0e10cSrcweir else 1282*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nIndentPrefix ); 1283*cdf0e10cSrcweir } 1284*cdf0e10cSrcweir bThrowException = !mp_SaxWriterHelper->writeString(aChars, sal_True , sal_False); 1285*cdf0e10cSrcweir } 1286*cdf0e10cSrcweir } 1287*cdf0e10cSrcweir if (bThrowException) 1288*cdf0e10cSrcweir { 1289*cdf0e10cSrcweir SAXInvalidCharacterException except; 1290*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) ); 1291*cdf0e10cSrcweir throw except; 1292*cdf0e10cSrcweir } 1293*cdf0e10cSrcweir } 1294*cdf0e10cSrcweir 1295*cdf0e10cSrcweir 1296*cdf0e10cSrcweir void SAXWriter::ignorableWhitespace(const OUString&) throw(SAXException, RuntimeException) 1297*cdf0e10cSrcweir { 1298*cdf0e10cSrcweir if( ! m_bDocStarted ) 1299*cdf0e10cSrcweir { 1300*cdf0e10cSrcweir throw SAXException (); 1301*cdf0e10cSrcweir } 1302*cdf0e10cSrcweir 1303*cdf0e10cSrcweir m_bForceLineBreak = sal_True; 1304*cdf0e10cSrcweir } 1305*cdf0e10cSrcweir 1306*cdf0e10cSrcweir void SAXWriter::processingInstruction(const OUString& aTarget, const OUString& aData) 1307*cdf0e10cSrcweir throw (SAXException, RuntimeException) 1308*cdf0e10cSrcweir { 1309*cdf0e10cSrcweir if( ! m_bDocStarted || m_bIsCDATA ) 1310*cdf0e10cSrcweir { 1311*cdf0e10cSrcweir throw SAXException(); 1312*cdf0e10cSrcweir } 1313*cdf0e10cSrcweir 1314*cdf0e10cSrcweir sal_Int32 nLength(0); 1315*cdf0e10cSrcweir if (m_bAllowLineBreak) 1316*cdf0e10cSrcweir { 1317*cdf0e10cSrcweir nLength = 2; // "<?" 1318*cdf0e10cSrcweir nLength += calcXMLByteLength( aTarget.getStr(), aTarget.getLength(), sal_False, sal_False ); 1319*cdf0e10cSrcweir 1320*cdf0e10cSrcweir nLength += 1; // " " 1321*cdf0e10cSrcweir 1322*cdf0e10cSrcweir nLength += calcXMLByteLength( aData.getStr(), aData.getLength(), sal_False, sal_False ); 1323*cdf0e10cSrcweir 1324*cdf0e10cSrcweir nLength += 2; // "?>" 1325*cdf0e10cSrcweir } 1326*cdf0e10cSrcweir 1327*cdf0e10cSrcweir sal_Int32 nPrefix = getIndentPrefixLength( nLength ); 1328*cdf0e10cSrcweir 1329*cdf0e10cSrcweir if( nPrefix >= 0 ) 1330*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nPrefix ); 1331*cdf0e10cSrcweir 1332*cdf0e10cSrcweir if (!mp_SaxWriterHelper->processingInstruction(aTarget, aData)) 1333*cdf0e10cSrcweir { 1334*cdf0e10cSrcweir SAXException except; 1335*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) ); 1336*cdf0e10cSrcweir throw except; 1337*cdf0e10cSrcweir } 1338*cdf0e10cSrcweir } 1339*cdf0e10cSrcweir 1340*cdf0e10cSrcweir 1341*cdf0e10cSrcweir void SAXWriter::setDocumentLocator(const Reference< XLocator >&) 1342*cdf0e10cSrcweir throw (SAXException, RuntimeException) 1343*cdf0e10cSrcweir { 1344*cdf0e10cSrcweir 1345*cdf0e10cSrcweir } 1346*cdf0e10cSrcweir 1347*cdf0e10cSrcweir void SAXWriter::startCDATA(void) throw(SAXException, RuntimeException) 1348*cdf0e10cSrcweir { 1349*cdf0e10cSrcweir if( ! m_bDocStarted || m_bIsCDATA) 1350*cdf0e10cSrcweir { 1351*cdf0e10cSrcweir throw SAXException (); 1352*cdf0e10cSrcweir } 1353*cdf0e10cSrcweir 1354*cdf0e10cSrcweir sal_Int32 nLength = 9; 1355*cdf0e10cSrcweir sal_Int32 nPrefix = getIndentPrefixLength( nLength ); 1356*cdf0e10cSrcweir if( nPrefix >= 0 ) 1357*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nPrefix ); 1358*cdf0e10cSrcweir 1359*cdf0e10cSrcweir mp_SaxWriterHelper->startCDATA(); 1360*cdf0e10cSrcweir 1361*cdf0e10cSrcweir m_bIsCDATA = sal_True; 1362*cdf0e10cSrcweir } 1363*cdf0e10cSrcweir 1364*cdf0e10cSrcweir void SAXWriter::endCDATA(void) throw (RuntimeException) 1365*cdf0e10cSrcweir { 1366*cdf0e10cSrcweir if( ! m_bDocStarted | ! m_bIsCDATA) 1367*cdf0e10cSrcweir { 1368*cdf0e10cSrcweir SAXException except; 1369*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "endCDATA was called without startCDATA" ) ); 1370*cdf0e10cSrcweir throw except; 1371*cdf0e10cSrcweir } 1372*cdf0e10cSrcweir 1373*cdf0e10cSrcweir sal_Int32 nLength = 3; 1374*cdf0e10cSrcweir sal_Int32 nPrefix = getIndentPrefixLength( nLength ); 1375*cdf0e10cSrcweir if( nPrefix >= 0 ) 1376*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nPrefix ); 1377*cdf0e10cSrcweir 1378*cdf0e10cSrcweir mp_SaxWriterHelper->endCDATA(); 1379*cdf0e10cSrcweir 1380*cdf0e10cSrcweir m_bIsCDATA = sal_False; 1381*cdf0e10cSrcweir } 1382*cdf0e10cSrcweir 1383*cdf0e10cSrcweir 1384*cdf0e10cSrcweir void SAXWriter::comment(const OUString& sComment) throw(SAXException, RuntimeException) 1385*cdf0e10cSrcweir { 1386*cdf0e10cSrcweir if( ! m_bDocStarted || m_bIsCDATA ) 1387*cdf0e10cSrcweir { 1388*cdf0e10cSrcweir throw SAXException(); 1389*cdf0e10cSrcweir } 1390*cdf0e10cSrcweir 1391*cdf0e10cSrcweir sal_Int32 nLength(0); 1392*cdf0e10cSrcweir if (m_bAllowLineBreak) 1393*cdf0e10cSrcweir { 1394*cdf0e10cSrcweir nLength = 4; // "<!--" 1395*cdf0e10cSrcweir nLength += calcXMLByteLength( sComment.getStr(), sComment.getLength(), sal_False, sal_False); 1396*cdf0e10cSrcweir 1397*cdf0e10cSrcweir nLength += 3; 1398*cdf0e10cSrcweir } 1399*cdf0e10cSrcweir 1400*cdf0e10cSrcweir sal_Int32 nPrefix = getIndentPrefixLength( nLength ); 1401*cdf0e10cSrcweir if( nPrefix >= 0 ) 1402*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nPrefix ); 1403*cdf0e10cSrcweir 1404*cdf0e10cSrcweir if (!mp_SaxWriterHelper->comment(sComment)) 1405*cdf0e10cSrcweir { 1406*cdf0e10cSrcweir SAXException except; 1407*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) ); 1408*cdf0e10cSrcweir throw except; 1409*cdf0e10cSrcweir } 1410*cdf0e10cSrcweir } 1411*cdf0e10cSrcweir 1412*cdf0e10cSrcweir 1413*cdf0e10cSrcweir void SAXWriter::allowLineBreak( ) throw ( SAXException , RuntimeException) 1414*cdf0e10cSrcweir { 1415*cdf0e10cSrcweir if( ! m_bDocStarted || m_bAllowLineBreak ) { 1416*cdf0e10cSrcweir throw SAXException(); 1417*cdf0e10cSrcweir } 1418*cdf0e10cSrcweir 1419*cdf0e10cSrcweir m_bAllowLineBreak = sal_True; 1420*cdf0e10cSrcweir } 1421*cdf0e10cSrcweir 1422*cdf0e10cSrcweir void SAXWriter::unknown(const OUString& sString) throw (SAXException, RuntimeException) 1423*cdf0e10cSrcweir { 1424*cdf0e10cSrcweir 1425*cdf0e10cSrcweir if( ! m_bDocStarted ) 1426*cdf0e10cSrcweir { 1427*cdf0e10cSrcweir throw SAXException (); 1428*cdf0e10cSrcweir } 1429*cdf0e10cSrcweir if( m_bIsCDATA ) 1430*cdf0e10cSrcweir { 1431*cdf0e10cSrcweir throw SAXException(); 1432*cdf0e10cSrcweir } 1433*cdf0e10cSrcweir 1434*cdf0e10cSrcweir if( sString.matchAsciiL( "<?xml", 5 ) ) 1435*cdf0e10cSrcweir return; 1436*cdf0e10cSrcweir 1437*cdf0e10cSrcweir sal_Int32 nLength(0); 1438*cdf0e10cSrcweir if (m_bAllowLineBreak) 1439*cdf0e10cSrcweir nLength = calcXMLByteLength( sString.getStr(), sString.getLength(), sal_False, sal_False ); 1440*cdf0e10cSrcweir 1441*cdf0e10cSrcweir sal_Int32 nPrefix = getIndentPrefixLength( nLength ); 1442*cdf0e10cSrcweir if( nPrefix >= 0 ) 1443*cdf0e10cSrcweir mp_SaxWriterHelper->insertIndentation( nPrefix ); 1444*cdf0e10cSrcweir 1445*cdf0e10cSrcweir if (!mp_SaxWriterHelper->writeString( sString, sal_False, sal_False)) 1446*cdf0e10cSrcweir { 1447*cdf0e10cSrcweir SAXException except; 1448*cdf0e10cSrcweir except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) ); 1449*cdf0e10cSrcweir throw except; 1450*cdf0e10cSrcweir } 1451*cdf0e10cSrcweir } 1452*cdf0e10cSrcweir 1453*cdf0e10cSrcweir } 1454*cdf0e10cSrcweir 1455