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 &
91cdf0e10cSrcweir // nLen +=5;
92cdf0e10cSrcweir // break;
93cdf0e10cSrcweir // case '<': // <
94cdf0e10cSrcweir // case '>': // >
95cdf0e10cSrcweir // nLen +=4;
96cdf0e10cSrcweir // break;
97cdf0e10cSrcweir // case 39: // 39 == ''', '
98cdf0e10cSrcweir // case '"': // "
99cdf0e10cSrcweir // case 13: // 
100cdf0e10cSrcweir // nLen += 6;
101cdf0e10cSrcweir // break;
102cdf0e10cSrcweir
103cdf0e10cSrcweir // case 10: // 

104cdf0e10cSrcweir // case 9: // 	
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 &
300cdf0e10cSrcweir {
301cdf0e10cSrcweir if ((rPos + 5) > SEQUENCESIZE)
302cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"&", 5);
303cdf0e10cSrcweir else
304cdf0e10cSrcweir {
305cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "&", 5 );
306cdf0e10cSrcweir rPos += 5;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir }
309cdf0e10cSrcweir break;
310cdf0e10cSrcweir case '<':
311cdf0e10cSrcweir {
312cdf0e10cSrcweir if ((rPos + 4) > SEQUENCESIZE)
313cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"<", 4);
314cdf0e10cSrcweir else
315cdf0e10cSrcweir {
316cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "<" , 4 );
317cdf0e10cSrcweir rPos += 4; // <
318cdf0e10cSrcweir }
319cdf0e10cSrcweir }
320cdf0e10cSrcweir break;
321cdf0e10cSrcweir case '>':
322cdf0e10cSrcweir {
323cdf0e10cSrcweir if ((rPos + 4) > SEQUENCESIZE)
324cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)">", 4);
325cdf0e10cSrcweir else
326cdf0e10cSrcweir {
327cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , ">" , 4 );
328cdf0e10cSrcweir rPos += 4; // >
329cdf0e10cSrcweir }
330cdf0e10cSrcweir }
331cdf0e10cSrcweir break;
332cdf0e10cSrcweir case 39: // 39 == '''
333cdf0e10cSrcweir {
334cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE)
335cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"'", 6);
336cdf0e10cSrcweir else
337cdf0e10cSrcweir {
338cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "'" , 6 );
339cdf0e10cSrcweir rPos += 6; // '
340cdf0e10cSrcweir }
341cdf0e10cSrcweir }
342cdf0e10cSrcweir break;
343cdf0e10cSrcweir case '"':
344cdf0e10cSrcweir {
345cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE)
346cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)""", 6);
347cdf0e10cSrcweir else
348cdf0e10cSrcweir {
349cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , """ , 6 );
350cdf0e10cSrcweir rPos += 6; // "
351cdf0e10cSrcweir }
352cdf0e10cSrcweir }
353cdf0e10cSrcweir break;
354cdf0e10cSrcweir case 13:
355cdf0e10cSrcweir {
356cdf0e10cSrcweir if ((rPos + 6) > SEQUENCESIZE)
357cdf0e10cSrcweir AddBytes(pTarget, rPos, (sal_Int8*)"
", 6);
358cdf0e10cSrcweir else
359cdf0e10cSrcweir {
360cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "
" , 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*)"
" , 6);
371cdf0e10cSrcweir else
372cdf0e10cSrcweir {
373cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "
" , 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*)"	" , 6);
391cdf0e10cSrcweir else
392cdf0e10cSrcweir {
393cdf0e10cSrcweir memcpy( &(pTarget[rPos]) , "	" , 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 &
821cdf0e10cSrcweir nOutputLength +=5;
822cdf0e10cSrcweir break;
823cdf0e10cSrcweir case '<': // <
824cdf0e10cSrcweir case '>': // >
825cdf0e10cSrcweir nOutputLength +=4;
826cdf0e10cSrcweir break;
827cdf0e10cSrcweir case 39: // 39 == ''', '
828cdf0e10cSrcweir case '"': // "
829cdf0e10cSrcweir case 13: // 
830cdf0e10cSrcweir nOutputLength += 6;
831cdf0e10cSrcweir break;
832cdf0e10cSrcweir
833cdf0e10cSrcweir case 10: // 

834cdf0e10cSrcweir case 9: // 	
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