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