1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski #include <string.h>
24*b1cdbd2cSJim Jagielski
25*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XServiceInfo.hpp>
26*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XCloneable.hpp>
27*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
28*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/XParser.hpp>
29*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/SAXParseException.hpp>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp>
31*b1cdbd2cSJim Jagielski
32*b1cdbd2cSJim Jagielski #include <com/sun/star/io/XActiveDataSource.hpp>
33*b1cdbd2cSJim Jagielski
34*b1cdbd2cSJim Jagielski #include <cppuhelper/factory.hxx>
35*b1cdbd2cSJim Jagielski #include <cppuhelper/weak.hxx>
36*b1cdbd2cSJim Jagielski #include <cppuhelper/implbase3.hxx>
37*b1cdbd2cSJim Jagielski
38*b1cdbd2cSJim Jagielski #include <rtl/strbuf.hxx>
39*b1cdbd2cSJim Jagielski #include <rtl/byteseq.hxx>
40*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
41*b1cdbd2cSJim Jagielski
42*b1cdbd2cSJim Jagielski using namespace ::rtl;
43*b1cdbd2cSJim Jagielski using namespace ::std;
44*b1cdbd2cSJim Jagielski using namespace ::osl;
45*b1cdbd2cSJim Jagielski using namespace ::cppu;
46*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::uno;
47*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::lang;
48*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::registry;
49*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::xml::sax;
50*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::util;
51*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::io;
52*b1cdbd2cSJim Jagielski
53*b1cdbd2cSJim Jagielski #include "factory.hxx"
54*b1cdbd2cSJim Jagielski #include "xml2utf.hxx"
55*b1cdbd2cSJim Jagielski
56*b1cdbd2cSJim Jagielski #define LINEFEED 10
57*b1cdbd2cSJim Jagielski #define SEQUENCESIZE 1024
58*b1cdbd2cSJim Jagielski #define MAXCOLUMNCOUNT 72
59*b1cdbd2cSJim Jagielski
60*b1cdbd2cSJim Jagielski /******
61*b1cdbd2cSJim Jagielski *
62*b1cdbd2cSJim Jagielski *
63*b1cdbd2cSJim Jagielski * Character conversion functions
64*b1cdbd2cSJim Jagielski *
65*b1cdbd2cSJim Jagielski *
66*b1cdbd2cSJim Jagielski *****/
67*b1cdbd2cSJim Jagielski
68*b1cdbd2cSJim Jagielski namespace sax_expatwrap {
69*b1cdbd2cSJim Jagielski /*****
70*b1cdbd2cSJim Jagielski *
71*b1cdbd2cSJim Jagielski * Calculates the length of the sequence after conversion, but the conversion is not done.
72*b1cdbd2cSJim Jagielski * .g. &<>"' plus some more are
73*b1cdbd2cSJim Jagielski * special characters in XML that need to be transformed
74*b1cdbd2cSJim Jagielski *
75*b1cdbd2cSJim Jagielski * @param bConvertAll For Attributes it is necessary to convert every symbol (including line feed and tab)
76*b1cdbd2cSJim Jagielski * Set this to true, if you want to perform this special conversion
77*b1cdbd2cSJim Jagielski * @return The returned value is equal to the length of the incoming sequence, when no
78*b1cdbd2cSJim Jagielski + conversion is necessary, otherwise it is larger than the length of the sequence.
79*b1cdbd2cSJim Jagielski ****/
80*b1cdbd2cSJim Jagielski // inline sal_Int32 CalcXMLLen( const Sequence<sal_Int8> & seq , sal_Bool bConvertAll ) throw()
81*b1cdbd2cSJim Jagielski // {
82*b1cdbd2cSJim Jagielski // sal_Int32 nLen = 0;
83*b1cdbd2cSJim Jagielski // const sal_Int8 *pArray = seq.getConstArray();
84*b1cdbd2cSJim Jagielski
85*b1cdbd2cSJim Jagielski // for( int i = 0 ; i < seq.getLength() ; i ++ ) {
86*b1cdbd2cSJim Jagielski
87*b1cdbd2cSJim Jagielski // sal_Int8 c = pArray[i];
88*b1cdbd2cSJim Jagielski // switch( c )
89*b1cdbd2cSJim Jagielski // {
90*b1cdbd2cSJim Jagielski // case '&': // resemble to &
91*b1cdbd2cSJim Jagielski // nLen +=5;
92*b1cdbd2cSJim Jagielski // break;
93*b1cdbd2cSJim Jagielski // case '<': // <
94*b1cdbd2cSJim Jagielski // case '>': // >
95*b1cdbd2cSJim Jagielski // nLen +=4;
96*b1cdbd2cSJim Jagielski // break;
97*b1cdbd2cSJim Jagielski // case 39: // 39 == ''', '
98*b1cdbd2cSJim Jagielski // case '"': // "
99*b1cdbd2cSJim Jagielski // case 13: // 
100*b1cdbd2cSJim Jagielski // nLen += 6;
101*b1cdbd2cSJim Jagielski // break;
102*b1cdbd2cSJim Jagielski
103*b1cdbd2cSJim Jagielski // case 10: // 

104*b1cdbd2cSJim Jagielski // case 9: // 	
105*b1cdbd2cSJim Jagielski // if( bConvertAll )
106*b1cdbd2cSJim Jagielski // {
107*b1cdbd2cSJim Jagielski // nLen += 6; //
108*b1cdbd2cSJim Jagielski // }
109*b1cdbd2cSJim Jagielski // break;
110*b1cdbd2cSJim Jagielski // default:
111*b1cdbd2cSJim Jagielski // nLen ++;
112*b1cdbd2cSJim Jagielski // }
113*b1cdbd2cSJim Jagielski // }
114*b1cdbd2cSJim Jagielski
115*b1cdbd2cSJim Jagielski // return nLen;
116*b1cdbd2cSJim Jagielski // }
117*b1cdbd2cSJim Jagielski
118*b1cdbd2cSJim Jagielski enum SaxInvalidCharacterError
119*b1cdbd2cSJim Jagielski {
120*b1cdbd2cSJim Jagielski SAX_NONE,
121*b1cdbd2cSJim Jagielski SAX_WARNING,
122*b1cdbd2cSJim Jagielski SAX_ERROR
123*b1cdbd2cSJim Jagielski };
124*b1cdbd2cSJim Jagielski
125*b1cdbd2cSJim Jagielski class SaxWriterHelper
126*b1cdbd2cSJim Jagielski {
127*b1cdbd2cSJim Jagielski Reference< XOutputStream > m_out;
128*b1cdbd2cSJim Jagielski Sequence < sal_Int8 > m_Sequence;
129*b1cdbd2cSJim Jagielski sal_Int8* mp_Sequence;
130*b1cdbd2cSJim Jagielski
131*b1cdbd2cSJim Jagielski sal_Int32 nLastLineFeedPos; // is negative after writing a sequence
132*b1cdbd2cSJim Jagielski sal_uInt32 nCurrentPos;
133*b1cdbd2cSJim Jagielski sal_Bool m_bStartElementFinished;
134*b1cdbd2cSJim Jagielski
135*b1cdbd2cSJim Jagielski
136*b1cdbd2cSJim Jagielski inline sal_uInt32 writeSequence() throw( SAXException );
137*b1cdbd2cSJim Jagielski
138*b1cdbd2cSJim Jagielski // use only if to insert the bytes more space in the sequence is needed and
139*b1cdbd2cSJim Jagielski // so the sequence has to write out and reset rPos to 0
140*b1cdbd2cSJim Jagielski // writes sequence only on overflow, sequence could be full on the end (rPos == SEQUENCESIZE)
141*b1cdbd2cSJim Jagielski inline void AddBytes(sal_Int8* pTarget, sal_uInt32& rPos,
142*b1cdbd2cSJim Jagielski const sal_Int8* pBytes, sal_uInt32 nBytesCount) throw( SAXException );
143*b1cdbd2cSJim Jagielski inline sal_Bool convertToXML(const sal_Unicode * pStr,
144*b1cdbd2cSJim Jagielski sal_Int32 nStrLen,
145*b1cdbd2cSJim Jagielski sal_Bool bDoNormalization,
146*b1cdbd2cSJim Jagielski sal_Bool bNormalizeWhitespace,
147*b1cdbd2cSJim Jagielski sal_Int8 *pTarget,
148*b1cdbd2cSJim Jagielski sal_uInt32& rPos) throw( SAXException );
149*b1cdbd2cSJim Jagielski inline void FinishStartElement() throw( SAXException );
150*b1cdbd2cSJim Jagielski public:
SaxWriterHelper(Reference<XOutputStream> m_TempOut)151*b1cdbd2cSJim Jagielski SaxWriterHelper(Reference< XOutputStream > m_TempOut) :
152*b1cdbd2cSJim Jagielski m_out(m_TempOut),
153*b1cdbd2cSJim Jagielski m_Sequence(SEQUENCESIZE),
154*b1cdbd2cSJim Jagielski mp_Sequence(NULL),
155*b1cdbd2cSJim Jagielski nLastLineFeedPos(0),
156*b1cdbd2cSJim Jagielski nCurrentPos(0),
157*b1cdbd2cSJim Jagielski m_bStartElementFinished(sal_True)
158*b1cdbd2cSJim Jagielski {
159*b1cdbd2cSJim Jagielski OSL_ENSURE(SEQUENCESIZE > 50, "Sequence cache size to small");
160*b1cdbd2cSJim Jagielski mp_Sequence = m_Sequence.getArray();
161*b1cdbd2cSJim Jagielski }
~SaxWriterHelper()162*b1cdbd2cSJim Jagielski ~SaxWriterHelper()
163*b1cdbd2cSJim Jagielski {
164*b1cdbd2cSJim Jagielski OSL_ENSURE(!nCurrentPos, "cached Sequence not written");
165*b1cdbd2cSJim Jagielski OSL_ENSURE(m_bStartElementFinished, "StartElement not complettly written");
166*b1cdbd2cSJim Jagielski }
167*b1cdbd2cSJim Jagielski
168*b1cdbd2cSJim Jagielski inline void insertIndentation(sal_uInt32 m_nLevel) throw( SAXException );
169*b1cdbd2cSJim Jagielski
170*b1cdbd2cSJim Jagielski // returns whether it works correct or invalid characters were in the string
171*b1cdbd2cSJim Jagielski // If there are invalid characters in the string it returns sal_False.
172*b1cdbd2cSJim Jagielski // Than the calling method has to throw the needed Exception.
173*b1cdbd2cSJim Jagielski inline sal_Bool writeString(const rtl::OUString& rWriteOutString,
174*b1cdbd2cSJim Jagielski sal_Bool bDoNormalization,
175*b1cdbd2cSJim Jagielski sal_Bool bNormalizeWhitespace) throw( SAXException );
176*b1cdbd2cSJim Jagielski
GetLastColumnCount()177*b1cdbd2cSJim Jagielski sal_uInt32 GetLastColumnCount() { return (sal_uInt32)(nCurrentPos - nLastLineFeedPos); }
178*b1cdbd2cSJim Jagielski
179*b1cdbd2cSJim Jagielski inline void startDocument() throw( SAXException );
180*b1cdbd2cSJim Jagielski
181*b1cdbd2cSJim Jagielski // returns whether it works correct or invalid characters were in the strings
182*b1cdbd2cSJim Jagielski // If there are invalid characters in one of the strings it returns sal_False.
183*b1cdbd2cSJim Jagielski // Than the calling method has to throw the needed Exception.
184*b1cdbd2cSJim Jagielski inline SaxInvalidCharacterError startElement(const rtl::OUString& rName, const Reference< XAttributeList >& xAttribs) throw( SAXException );
185*b1cdbd2cSJim Jagielski inline sal_Bool FinishEmptyElement() throw( SAXException );
186*b1cdbd2cSJim Jagielski
187*b1cdbd2cSJim Jagielski // returns whether it works correct or invalid characters were in the string
188*b1cdbd2cSJim Jagielski // If there are invalid characters in the string it returns sal_False.
189*b1cdbd2cSJim Jagielski // Than the calling method has to throw the needed Exception.
190*b1cdbd2cSJim Jagielski inline sal_Bool endElement(const rtl::OUString& rName) throw( SAXException );
191*b1cdbd2cSJim Jagielski inline void endDocument() throw( SAXException );
192*b1cdbd2cSJim Jagielski
193*b1cdbd2cSJim Jagielski // returns whether it works correct or invalid characters were in the strings
194*b1cdbd2cSJim Jagielski // If there are invalid characters in the string it returns sal_False.
195*b1cdbd2cSJim Jagielski // Than the calling method has to throw the needed Exception.
196*b1cdbd2cSJim Jagielski inline sal_Bool processingInstruction(const rtl::OUString& rTarget, const rtl::OUString& rData) throw( SAXException );
197*b1cdbd2cSJim Jagielski inline void startCDATA() throw( SAXException );
198*b1cdbd2cSJim Jagielski inline void endCDATA() throw( SAXException );
199*b1cdbd2cSJim Jagielski
200*b1cdbd2cSJim Jagielski // returns whether it works correct or invalid characters were in the strings
201*b1cdbd2cSJim Jagielski // If there are invalid characters in the string it returns sal_False.
202*b1cdbd2cSJim Jagielski // Than the calling method has to throw the needed Exception.
203*b1cdbd2cSJim Jagielski inline sal_Bool comment(const rtl::OUString& rComment) throw( SAXException );
204*b1cdbd2cSJim Jagielski
205*b1cdbd2cSJim Jagielski inline void clearBuffer() throw( SAXException );
206*b1cdbd2cSJim Jagielski };
207*b1cdbd2cSJim Jagielski
208*b1cdbd2cSJim Jagielski const sal_Bool g_bValidCharsBelow32[32] =
209*b1cdbd2cSJim Jagielski {
210*b1cdbd2cSJim Jagielski // 0 1 2 3 4 5 6 7
211*b1cdbd2cSJim Jagielski 0,0,0,0,0,0,0,0, //0
212*b1cdbd2cSJim Jagielski 0,1,1,0,0,1,0,0, //8
213*b1cdbd2cSJim Jagielski 0,0,0,0,0,0,0,0, //16
214*b1cdbd2cSJim Jagielski 0,0,0,0,0,0,0,0
215*b1cdbd2cSJim Jagielski };
216*b1cdbd2cSJim Jagielski
IsInvalidChar(const sal_Unicode aChar)217*b1cdbd2cSJim Jagielski inline sal_Bool IsInvalidChar(const sal_Unicode aChar)
218*b1cdbd2cSJim Jagielski {
219*b1cdbd2cSJim Jagielski sal_Bool bRet(sal_False);
220*b1cdbd2cSJim Jagielski // check first for the most common characters
221*b1cdbd2cSJim Jagielski if( aChar < 32 || aChar >= 0xd800 )
222*b1cdbd2cSJim Jagielski bRet = ( (aChar < 32 && ! g_bValidCharsBelow32[aChar]) ||
223*b1cdbd2cSJim Jagielski aChar == 0xffff ||
224*b1cdbd2cSJim Jagielski aChar == 0xfffe );
225*b1cdbd2cSJim Jagielski return bRet;
226*b1cdbd2cSJim Jagielski }
227*b1cdbd2cSJim Jagielski
228*b1cdbd2cSJim Jagielski /********
229*b1cdbd2cSJim Jagielski * write through to the output stream
230*b1cdbd2cSJim Jagielski *
231*b1cdbd2cSJim Jagielski *****/
writeSequence()232*b1cdbd2cSJim Jagielski inline sal_uInt32 SaxWriterHelper::writeSequence() throw( SAXException )
233*b1cdbd2cSJim Jagielski {
234*b1cdbd2cSJim Jagielski try
235*b1cdbd2cSJim Jagielski {
236*b1cdbd2cSJim Jagielski m_out->writeBytes( m_Sequence );
237*b1cdbd2cSJim Jagielski }
238*b1cdbd2cSJim Jagielski catch( IOException & e )
239*b1cdbd2cSJim Jagielski {
240*b1cdbd2cSJim Jagielski Any a;
241*b1cdbd2cSJim Jagielski a <<= e;
242*b1cdbd2cSJim Jagielski throw SAXException(
243*b1cdbd2cSJim Jagielski OUString::createFromAscii( "io exception during writing" ),
244*b1cdbd2cSJim Jagielski Reference< XInterface > (),
245*b1cdbd2cSJim Jagielski a );
246*b1cdbd2cSJim Jagielski }
247*b1cdbd2cSJim Jagielski nLastLineFeedPos -= SEQUENCESIZE;
248*b1cdbd2cSJim Jagielski return 0;
249*b1cdbd2cSJim Jagielski }
250*b1cdbd2cSJim Jagielski
AddBytes(sal_Int8 * pTarget,sal_uInt32 & rPos,const sal_Int8 * pBytes,sal_uInt32 nBytesCount)251*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::AddBytes(sal_Int8* pTarget, sal_uInt32& rPos,
252*b1cdbd2cSJim Jagielski const sal_Int8* pBytes, sal_uInt32 nBytesCount) throw( SAXException )
253*b1cdbd2cSJim Jagielski {
254*b1cdbd2cSJim Jagielski OSL_ENSURE((rPos + nBytesCount) > SEQUENCESIZE, "wrong use of AddBytesMethod");
255*b1cdbd2cSJim Jagielski sal_uInt32 nCount(SEQUENCESIZE - rPos);
256*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , pBytes, nCount);
257*b1cdbd2cSJim Jagielski
258*b1cdbd2cSJim Jagielski OSL_ENSURE(rPos + nCount == SEQUENCESIZE, "the position should be the at the end");
259*b1cdbd2cSJim Jagielski
260*b1cdbd2cSJim Jagielski rPos = writeSequence();
261*b1cdbd2cSJim Jagielski sal_uInt32 nRestCount(nBytesCount - nCount);
262*b1cdbd2cSJim Jagielski if ((rPos + nRestCount) <= SEQUENCESIZE)
263*b1cdbd2cSJim Jagielski {
264*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]), &pBytes[nCount], nRestCount);
265*b1cdbd2cSJim Jagielski rPos += nRestCount;
266*b1cdbd2cSJim Jagielski }
267*b1cdbd2cSJim Jagielski else
268*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, &pBytes[nCount], nRestCount);
269*b1cdbd2cSJim Jagielski }
270*b1cdbd2cSJim Jagielski
271*b1cdbd2cSJim Jagielski /** Converts an UTF16 string to UTF8 and does XML normalization
272*b1cdbd2cSJim Jagielski
273*b1cdbd2cSJim Jagielski @param pTarget
274*b1cdbd2cSJim Jagielski Pointer to a piece of memory, to where the output should be written. The caller
275*b1cdbd2cSJim Jagielski must call calcXMLByteLength on the same string, to ensure,
276*b1cdbd2cSJim Jagielski that there is enough memory for converting.
277*b1cdbd2cSJim Jagielski */
convertToXML(const sal_Unicode * pStr,sal_Int32 nStrLen,sal_Bool bDoNormalization,sal_Bool bNormalizeWhitespace,sal_Int8 * pTarget,sal_uInt32 & rPos)278*b1cdbd2cSJim Jagielski inline sal_Bool SaxWriterHelper::convertToXML( const sal_Unicode * pStr,
279*b1cdbd2cSJim Jagielski sal_Int32 nStrLen,
280*b1cdbd2cSJim Jagielski sal_Bool bDoNormalization,
281*b1cdbd2cSJim Jagielski sal_Bool bNormalizeWhitespace,
282*b1cdbd2cSJim Jagielski sal_Int8 *pTarget,
283*b1cdbd2cSJim Jagielski sal_uInt32& rPos ) throw( SAXException )
284*b1cdbd2cSJim Jagielski {
285*b1cdbd2cSJim Jagielski sal_Bool bRet(sal_True);
286*b1cdbd2cSJim Jagielski sal_uInt32 nSurrogate = 0;
287*b1cdbd2cSJim Jagielski
288*b1cdbd2cSJim Jagielski for( sal_Int32 i = 0 ; i < nStrLen ; i ++ )
289*b1cdbd2cSJim Jagielski {
290*b1cdbd2cSJim Jagielski sal_uInt16 c = pStr[i];
291*b1cdbd2cSJim Jagielski if (IsInvalidChar(c))
292*b1cdbd2cSJim Jagielski bRet = sal_False;
293*b1cdbd2cSJim Jagielski else if( (c >= 0x0001) && (c <= 0x007F) )
294*b1cdbd2cSJim Jagielski {
295*b1cdbd2cSJim Jagielski if( bDoNormalization )
296*b1cdbd2cSJim Jagielski {
297*b1cdbd2cSJim Jagielski switch( c )
298*b1cdbd2cSJim Jagielski {
299*b1cdbd2cSJim Jagielski case '&': // resemble to &
300*b1cdbd2cSJim Jagielski {
301*b1cdbd2cSJim Jagielski if ((rPos + 5) > SEQUENCESIZE)
302*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)"&", 5);
303*b1cdbd2cSJim Jagielski else
304*b1cdbd2cSJim Jagielski {
305*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , "&", 5 );
306*b1cdbd2cSJim Jagielski rPos += 5;
307*b1cdbd2cSJim Jagielski }
308*b1cdbd2cSJim Jagielski }
309*b1cdbd2cSJim Jagielski break;
310*b1cdbd2cSJim Jagielski case '<':
311*b1cdbd2cSJim Jagielski {
312*b1cdbd2cSJim Jagielski if ((rPos + 4) > SEQUENCESIZE)
313*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)"<", 4);
314*b1cdbd2cSJim Jagielski else
315*b1cdbd2cSJim Jagielski {
316*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , "<" , 4 );
317*b1cdbd2cSJim Jagielski rPos += 4; // <
318*b1cdbd2cSJim Jagielski }
319*b1cdbd2cSJim Jagielski }
320*b1cdbd2cSJim Jagielski break;
321*b1cdbd2cSJim Jagielski case '>':
322*b1cdbd2cSJim Jagielski {
323*b1cdbd2cSJim Jagielski if ((rPos + 4) > SEQUENCESIZE)
324*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)">", 4);
325*b1cdbd2cSJim Jagielski else
326*b1cdbd2cSJim Jagielski {
327*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , ">" , 4 );
328*b1cdbd2cSJim Jagielski rPos += 4; // >
329*b1cdbd2cSJim Jagielski }
330*b1cdbd2cSJim Jagielski }
331*b1cdbd2cSJim Jagielski break;
332*b1cdbd2cSJim Jagielski case 39: // 39 == '''
333*b1cdbd2cSJim Jagielski {
334*b1cdbd2cSJim Jagielski if ((rPos + 6) > SEQUENCESIZE)
335*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)"'", 6);
336*b1cdbd2cSJim Jagielski else
337*b1cdbd2cSJim Jagielski {
338*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , "'" , 6 );
339*b1cdbd2cSJim Jagielski rPos += 6; // '
340*b1cdbd2cSJim Jagielski }
341*b1cdbd2cSJim Jagielski }
342*b1cdbd2cSJim Jagielski break;
343*b1cdbd2cSJim Jagielski case '"':
344*b1cdbd2cSJim Jagielski {
345*b1cdbd2cSJim Jagielski if ((rPos + 6) > SEQUENCESIZE)
346*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)""", 6);
347*b1cdbd2cSJim Jagielski else
348*b1cdbd2cSJim Jagielski {
349*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , """ , 6 );
350*b1cdbd2cSJim Jagielski rPos += 6; // "
351*b1cdbd2cSJim Jagielski }
352*b1cdbd2cSJim Jagielski }
353*b1cdbd2cSJim Jagielski break;
354*b1cdbd2cSJim Jagielski case 13:
355*b1cdbd2cSJim Jagielski {
356*b1cdbd2cSJim Jagielski if ((rPos + 6) > SEQUENCESIZE)
357*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)"
", 6);
358*b1cdbd2cSJim Jagielski else
359*b1cdbd2cSJim Jagielski {
360*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , "
" , 6 );
361*b1cdbd2cSJim Jagielski rPos += 6;
362*b1cdbd2cSJim Jagielski }
363*b1cdbd2cSJim Jagielski }
364*b1cdbd2cSJim Jagielski break;
365*b1cdbd2cSJim Jagielski case LINEFEED:
366*b1cdbd2cSJim Jagielski {
367*b1cdbd2cSJim Jagielski if( bNormalizeWhitespace )
368*b1cdbd2cSJim Jagielski {
369*b1cdbd2cSJim Jagielski if ((rPos + 6) > SEQUENCESIZE)
370*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)"
" , 6);
371*b1cdbd2cSJim Jagielski else
372*b1cdbd2cSJim Jagielski {
373*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , "
" , 6 );
374*b1cdbd2cSJim Jagielski rPos += 6;
375*b1cdbd2cSJim Jagielski }
376*b1cdbd2cSJim Jagielski }
377*b1cdbd2cSJim Jagielski else
378*b1cdbd2cSJim Jagielski {
379*b1cdbd2cSJim Jagielski pTarget[rPos] = LINEFEED;
380*b1cdbd2cSJim Jagielski nLastLineFeedPos = rPos;
381*b1cdbd2cSJim Jagielski rPos ++;
382*b1cdbd2cSJim Jagielski }
383*b1cdbd2cSJim Jagielski }
384*b1cdbd2cSJim Jagielski break;
385*b1cdbd2cSJim Jagielski case 9:
386*b1cdbd2cSJim Jagielski {
387*b1cdbd2cSJim Jagielski if( bNormalizeWhitespace )
388*b1cdbd2cSJim Jagielski {
389*b1cdbd2cSJim Jagielski if ((rPos + 6) > SEQUENCESIZE)
390*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, (sal_Int8*)"	" , 6);
391*b1cdbd2cSJim Jagielski else
392*b1cdbd2cSJim Jagielski {
393*b1cdbd2cSJim Jagielski memcpy( &(pTarget[rPos]) , "	" , 6 );
394*b1cdbd2cSJim Jagielski rPos += 6;
395*b1cdbd2cSJim Jagielski }
396*b1cdbd2cSJim Jagielski }
397*b1cdbd2cSJim Jagielski else
398*b1cdbd2cSJim Jagielski {
399*b1cdbd2cSJim Jagielski pTarget[rPos] = 9;
400*b1cdbd2cSJim Jagielski rPos ++;
401*b1cdbd2cSJim Jagielski }
402*b1cdbd2cSJim Jagielski }
403*b1cdbd2cSJim Jagielski break;
404*b1cdbd2cSJim Jagielski default:
405*b1cdbd2cSJim Jagielski {
406*b1cdbd2cSJim Jagielski pTarget[rPos] = (sal_Int8)c;
407*b1cdbd2cSJim Jagielski rPos ++;
408*b1cdbd2cSJim Jagielski }
409*b1cdbd2cSJim Jagielski break;
410*b1cdbd2cSJim Jagielski }
411*b1cdbd2cSJim Jagielski }
412*b1cdbd2cSJim Jagielski else
413*b1cdbd2cSJim Jagielski {
414*b1cdbd2cSJim Jagielski pTarget[rPos] = (sal_Int8)c;
415*b1cdbd2cSJim Jagielski if ((sal_Int8)c == LINEFEED)
416*b1cdbd2cSJim Jagielski nLastLineFeedPos = rPos;
417*b1cdbd2cSJim Jagielski rPos ++;
418*b1cdbd2cSJim Jagielski }
419*b1cdbd2cSJim Jagielski }
420*b1cdbd2cSJim Jagielski else if( c >= 0xd800 && c < 0xdc00 )
421*b1cdbd2cSJim Jagielski {
422*b1cdbd2cSJim Jagielski // 1. surrogate: save (until 2. surrogate)
423*b1cdbd2cSJim Jagielski OSL_ENSURE( nSurrogate == 0, "left-over Unicode surrogate" );
424*b1cdbd2cSJim Jagielski nSurrogate = ( ( c & 0x03ff ) + 0x0040 );
425*b1cdbd2cSJim Jagielski }
426*b1cdbd2cSJim Jagielski else if( c >= 0xdc00 && c < 0xe000 )
427*b1cdbd2cSJim Jagielski {
428*b1cdbd2cSJim Jagielski // 2. surrogate: write as UTF-8
429*b1cdbd2cSJim Jagielski OSL_ENSURE( nSurrogate != 0, "lone 2nd Unicode surrogate" );
430*b1cdbd2cSJim Jagielski
431*b1cdbd2cSJim Jagielski nSurrogate = ( nSurrogate << 10 ) | ( c & 0x03ff );
432*b1cdbd2cSJim Jagielski if( nSurrogate >= 0x00010000 && nSurrogate <= 0x0010FFFF )
433*b1cdbd2cSJim Jagielski {
434*b1cdbd2cSJim Jagielski sal_Int8 aBytes[] = { sal_Int8(0xF0 | ((nSurrogate >> 18) & 0x0F)),
435*b1cdbd2cSJim Jagielski sal_Int8(0x80 | ((nSurrogate >> 12) & 0x3F)),
436*b1cdbd2cSJim Jagielski sal_Int8(0x80 | ((nSurrogate >> 6) & 0x3F)),
437*b1cdbd2cSJim Jagielski sal_Int8(0x80 | ((nSurrogate >> 0) & 0x3F)) };
438*b1cdbd2cSJim Jagielski if ((rPos + 4) > SEQUENCESIZE)
439*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, aBytes, 4);
440*b1cdbd2cSJim Jagielski else
441*b1cdbd2cSJim Jagielski {
442*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[0];
443*b1cdbd2cSJim Jagielski rPos ++;
444*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[1];
445*b1cdbd2cSJim Jagielski rPos ++;
446*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[2];
447*b1cdbd2cSJim Jagielski rPos ++;
448*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[3];
449*b1cdbd2cSJim Jagielski rPos ++;
450*b1cdbd2cSJim Jagielski }
451*b1cdbd2cSJim Jagielski }
452*b1cdbd2cSJim Jagielski else
453*b1cdbd2cSJim Jagielski {
454*b1cdbd2cSJim Jagielski OSL_ENSURE( false, "illegal Unicode character" );
455*b1cdbd2cSJim Jagielski bRet = sal_False;
456*b1cdbd2cSJim Jagielski }
457*b1cdbd2cSJim Jagielski
458*b1cdbd2cSJim Jagielski // reset surrogate
459*b1cdbd2cSJim Jagielski nSurrogate = 0;
460*b1cdbd2cSJim Jagielski }
461*b1cdbd2cSJim Jagielski else if( c > 0x07FF )
462*b1cdbd2cSJim Jagielski {
463*b1cdbd2cSJim Jagielski sal_Int8 aBytes[] = { sal_Int8(0xE0 | ((c >> 12) & 0x0F)),
464*b1cdbd2cSJim Jagielski sal_Int8(0x80 | ((c >> 6) & 0x3F)),
465*b1cdbd2cSJim Jagielski sal_Int8(0x80 | ((c >> 0) & 0x3F)) };
466*b1cdbd2cSJim Jagielski if ((rPos + 3) > SEQUENCESIZE)
467*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, aBytes, 3);
468*b1cdbd2cSJim Jagielski else
469*b1cdbd2cSJim Jagielski {
470*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[0];
471*b1cdbd2cSJim Jagielski rPos ++;
472*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[1];
473*b1cdbd2cSJim Jagielski rPos ++;
474*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[2];
475*b1cdbd2cSJim Jagielski rPos ++;
476*b1cdbd2cSJim Jagielski }
477*b1cdbd2cSJim Jagielski }
478*b1cdbd2cSJim Jagielski else
479*b1cdbd2cSJim Jagielski {
480*b1cdbd2cSJim Jagielski sal_Int8 aBytes[] = { sal_Int8(0xC0 | ((c >> 6) & 0x1F)),
481*b1cdbd2cSJim Jagielski sal_Int8(0x80 | ((c >> 0) & 0x3F)) };
482*b1cdbd2cSJim Jagielski if ((rPos + 2) > SEQUENCESIZE)
483*b1cdbd2cSJim Jagielski AddBytes(pTarget, rPos, aBytes, 2);
484*b1cdbd2cSJim Jagielski else
485*b1cdbd2cSJim Jagielski {
486*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[0];
487*b1cdbd2cSJim Jagielski rPos ++;
488*b1cdbd2cSJim Jagielski pTarget[rPos] = aBytes[1];
489*b1cdbd2cSJim Jagielski rPos ++;
490*b1cdbd2cSJim Jagielski }
491*b1cdbd2cSJim Jagielski }
492*b1cdbd2cSJim Jagielski OSL_ENSURE(rPos <= SEQUENCESIZE, "not reset current position");
493*b1cdbd2cSJim Jagielski if (rPos == SEQUENCESIZE)
494*b1cdbd2cSJim Jagielski rPos = writeSequence();
495*b1cdbd2cSJim Jagielski
496*b1cdbd2cSJim Jagielski // reset left-over surrogate
497*b1cdbd2cSJim Jagielski if( ( nSurrogate != 0 ) && !( c >= 0xd800 && c < 0xdc00 ) )
498*b1cdbd2cSJim Jagielski {
499*b1cdbd2cSJim Jagielski OSL_ENSURE( nSurrogate != 0, "left-over Unicode surrogate" );
500*b1cdbd2cSJim Jagielski nSurrogate = 0;
501*b1cdbd2cSJim Jagielski bRet = sal_False;
502*b1cdbd2cSJim Jagielski }
503*b1cdbd2cSJim Jagielski }
504*b1cdbd2cSJim Jagielski return bRet;
505*b1cdbd2cSJim Jagielski }
506*b1cdbd2cSJim Jagielski
FinishStartElement()507*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::FinishStartElement() throw( SAXException )
508*b1cdbd2cSJim Jagielski {
509*b1cdbd2cSJim Jagielski if (!m_bStartElementFinished)
510*b1cdbd2cSJim Jagielski {
511*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '>';
512*b1cdbd2cSJim Jagielski nCurrentPos++;
513*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
514*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
515*b1cdbd2cSJim Jagielski m_bStartElementFinished = sal_True;
516*b1cdbd2cSJim Jagielski }
517*b1cdbd2cSJim Jagielski }
518*b1cdbd2cSJim Jagielski
insertIndentation(sal_uInt32 m_nLevel)519*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::insertIndentation(sal_uInt32 m_nLevel) throw( SAXException )
520*b1cdbd2cSJim Jagielski {
521*b1cdbd2cSJim Jagielski FinishStartElement();
522*b1cdbd2cSJim Jagielski if (m_nLevel > 0)
523*b1cdbd2cSJim Jagielski {
524*b1cdbd2cSJim Jagielski if ((nCurrentPos + m_nLevel + 1) <= SEQUENCESIZE)
525*b1cdbd2cSJim Jagielski {
526*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = LINEFEED;
527*b1cdbd2cSJim Jagielski nLastLineFeedPos = nCurrentPos;
528*b1cdbd2cSJim Jagielski nCurrentPos++;
529*b1cdbd2cSJim Jagielski memset( &(mp_Sequence[nCurrentPos]) , 32 , m_nLevel );
530*b1cdbd2cSJim Jagielski nCurrentPos += m_nLevel;
531*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
532*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
533*b1cdbd2cSJim Jagielski }
534*b1cdbd2cSJim Jagielski else
535*b1cdbd2cSJim Jagielski {
536*b1cdbd2cSJim Jagielski sal_uInt32 nCount(m_nLevel + 1);
537*b1cdbd2cSJim Jagielski sal_Int8* pBytes = new sal_Int8[nCount];
538*b1cdbd2cSJim Jagielski pBytes[0] = LINEFEED;
539*b1cdbd2cSJim Jagielski memset( &(pBytes[1]), 32, m_nLevel );
540*b1cdbd2cSJim Jagielski AddBytes(mp_Sequence, nCurrentPos, pBytes, nCount);
541*b1cdbd2cSJim Jagielski delete[] pBytes;
542*b1cdbd2cSJim Jagielski nLastLineFeedPos = nCurrentPos - nCount;
543*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
544*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
545*b1cdbd2cSJim Jagielski }
546*b1cdbd2cSJim Jagielski }
547*b1cdbd2cSJim Jagielski else
548*b1cdbd2cSJim Jagielski {
549*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = LINEFEED;
550*b1cdbd2cSJim Jagielski nLastLineFeedPos = nCurrentPos;
551*b1cdbd2cSJim Jagielski nCurrentPos++;
552*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
553*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
554*b1cdbd2cSJim Jagielski }
555*b1cdbd2cSJim Jagielski }
556*b1cdbd2cSJim Jagielski
writeString(const rtl::OUString & rWriteOutString,sal_Bool bDoNormalization,sal_Bool bNormalizeWhitespace)557*b1cdbd2cSJim Jagielski inline sal_Bool SaxWriterHelper::writeString( const rtl::OUString& rWriteOutString,
558*b1cdbd2cSJim Jagielski sal_Bool bDoNormalization,
559*b1cdbd2cSJim Jagielski sal_Bool bNormalizeWhitespace ) throw( SAXException )
560*b1cdbd2cSJim Jagielski {
561*b1cdbd2cSJim Jagielski FinishStartElement();
562*b1cdbd2cSJim Jagielski return convertToXML(rWriteOutString.getStr(),
563*b1cdbd2cSJim Jagielski rWriteOutString.getLength(),
564*b1cdbd2cSJim Jagielski bDoNormalization,
565*b1cdbd2cSJim Jagielski bNormalizeWhitespace,
566*b1cdbd2cSJim Jagielski mp_Sequence,
567*b1cdbd2cSJim Jagielski nCurrentPos);
568*b1cdbd2cSJim Jagielski }
569*b1cdbd2cSJim Jagielski
startDocument()570*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::startDocument() throw( SAXException )
571*b1cdbd2cSJim Jagielski {
572*b1cdbd2cSJim Jagielski const char pc[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
573*b1cdbd2cSJim Jagielski const int nLen = strlen( pc );
574*b1cdbd2cSJim Jagielski if ((nCurrentPos + nLen) <= SEQUENCESIZE)
575*b1cdbd2cSJim Jagielski {
576*b1cdbd2cSJim Jagielski memcpy( mp_Sequence, pc , nLen );
577*b1cdbd2cSJim Jagielski nCurrentPos += nLen;
578*b1cdbd2cSJim Jagielski }
579*b1cdbd2cSJim Jagielski else
580*b1cdbd2cSJim Jagielski {
581*b1cdbd2cSJim Jagielski AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)pc, nLen);
582*b1cdbd2cSJim Jagielski }
583*b1cdbd2cSJim Jagielski OSL_ENSURE(nCurrentPos <= SEQUENCESIZE, "not reset current position");
584*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
585*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
586*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = LINEFEED;
587*b1cdbd2cSJim Jagielski nCurrentPos++;
588*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
589*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
590*b1cdbd2cSJim Jagielski }
591*b1cdbd2cSJim Jagielski
startElement(const rtl::OUString & rName,const Reference<XAttributeList> & xAttribs)592*b1cdbd2cSJim Jagielski inline SaxInvalidCharacterError SaxWriterHelper::startElement(const rtl::OUString& rName, const Reference< XAttributeList >& xAttribs) throw( SAXException )
593*b1cdbd2cSJim Jagielski {
594*b1cdbd2cSJim Jagielski FinishStartElement();
595*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '<';
596*b1cdbd2cSJim Jagielski nCurrentPos++;
597*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
598*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
599*b1cdbd2cSJim Jagielski
600*b1cdbd2cSJim Jagielski SaxInvalidCharacterError eRet(SAX_NONE);
601*b1cdbd2cSJim Jagielski if (!writeString(rName, sal_False, sal_False))
602*b1cdbd2cSJim Jagielski eRet = SAX_ERROR;
603*b1cdbd2cSJim Jagielski
604*b1cdbd2cSJim Jagielski sal_Int16 nAttribCount = xAttribs.is() ? static_cast<sal_Int16>(xAttribs->getLength()) : 0;
605*b1cdbd2cSJim Jagielski for(sal_Int16 i = 0 ; i < nAttribCount ; i++ )
606*b1cdbd2cSJim Jagielski {
607*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = ' ';
608*b1cdbd2cSJim Jagielski nCurrentPos++;
609*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
610*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
611*b1cdbd2cSJim Jagielski
612*b1cdbd2cSJim Jagielski if (!writeString(xAttribs->getNameByIndex( i ), sal_False, sal_False))
613*b1cdbd2cSJim Jagielski eRet = SAX_ERROR;
614*b1cdbd2cSJim Jagielski
615*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '=';
616*b1cdbd2cSJim Jagielski nCurrentPos++;
617*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
618*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
619*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '"';
620*b1cdbd2cSJim Jagielski nCurrentPos++;
621*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
622*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
623*b1cdbd2cSJim Jagielski
624*b1cdbd2cSJim Jagielski if (!writeString(xAttribs->getValueByIndex( i ), sal_True, sal_True) &&
625*b1cdbd2cSJim Jagielski !(eRet == SAX_ERROR))
626*b1cdbd2cSJim Jagielski eRet = SAX_WARNING;
627*b1cdbd2cSJim Jagielski
628*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '"';
629*b1cdbd2cSJim Jagielski nCurrentPos++;
630*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
631*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
632*b1cdbd2cSJim Jagielski }
633*b1cdbd2cSJim Jagielski
634*b1cdbd2cSJim Jagielski m_bStartElementFinished = sal_False; // because the '>' character is not added,
635*b1cdbd2cSJim Jagielski // because it is possible, that the "/>"
636*b1cdbd2cSJim Jagielski // characters have to add
637*b1cdbd2cSJim Jagielski return eRet;
638*b1cdbd2cSJim Jagielski }
639*b1cdbd2cSJim Jagielski
FinishEmptyElement()640*b1cdbd2cSJim Jagielski inline sal_Bool SaxWriterHelper::FinishEmptyElement() throw( SAXException )
641*b1cdbd2cSJim Jagielski {
642*b1cdbd2cSJim Jagielski if (m_bStartElementFinished)
643*b1cdbd2cSJim Jagielski return sal_False;
644*b1cdbd2cSJim Jagielski
645*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '/';
646*b1cdbd2cSJim Jagielski nCurrentPos++;
647*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
648*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
649*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '>';
650*b1cdbd2cSJim Jagielski nCurrentPos++;
651*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
652*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
653*b1cdbd2cSJim Jagielski
654*b1cdbd2cSJim Jagielski m_bStartElementFinished = sal_True;
655*b1cdbd2cSJim Jagielski
656*b1cdbd2cSJim Jagielski return sal_True;
657*b1cdbd2cSJim Jagielski }
658*b1cdbd2cSJim Jagielski
endElement(const rtl::OUString & rName)659*b1cdbd2cSJim Jagielski inline sal_Bool SaxWriterHelper::endElement(const rtl::OUString& rName) throw( SAXException )
660*b1cdbd2cSJim Jagielski {
661*b1cdbd2cSJim Jagielski FinishStartElement();
662*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '<';
663*b1cdbd2cSJim Jagielski nCurrentPos++;
664*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
665*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
666*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '/';
667*b1cdbd2cSJim Jagielski nCurrentPos++;
668*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
669*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
670*b1cdbd2cSJim Jagielski
671*b1cdbd2cSJim Jagielski sal_Bool bRet(writeString( rName, sal_False, sal_False));
672*b1cdbd2cSJim Jagielski
673*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '>';
674*b1cdbd2cSJim Jagielski nCurrentPos++;
675*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
676*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
677*b1cdbd2cSJim Jagielski
678*b1cdbd2cSJim Jagielski return bRet;
679*b1cdbd2cSJim Jagielski }
680*b1cdbd2cSJim Jagielski
endDocument()681*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::endDocument() throw( SAXException )
682*b1cdbd2cSJim Jagielski {
683*b1cdbd2cSJim Jagielski if (nCurrentPos > 0)
684*b1cdbd2cSJim Jagielski {
685*b1cdbd2cSJim Jagielski m_Sequence.realloc(nCurrentPos);
686*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
687*b1cdbd2cSJim Jagielski //m_Sequence.realloc(SEQUENCESIZE);
688*b1cdbd2cSJim Jagielski }
689*b1cdbd2cSJim Jagielski }
690*b1cdbd2cSJim Jagielski
clearBuffer()691*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::clearBuffer() throw( SAXException )
692*b1cdbd2cSJim Jagielski {
693*b1cdbd2cSJim Jagielski FinishStartElement();
694*b1cdbd2cSJim Jagielski if (nCurrentPos > 0)
695*b1cdbd2cSJim Jagielski {
696*b1cdbd2cSJim Jagielski m_Sequence.realloc(nCurrentPos);
697*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
698*b1cdbd2cSJim Jagielski m_Sequence.realloc(SEQUENCESIZE);
699*b1cdbd2cSJim Jagielski // Be sure to update the array pointer after the reallocation.
700*b1cdbd2cSJim Jagielski mp_Sequence = m_Sequence.getArray();
701*b1cdbd2cSJim Jagielski }
702*b1cdbd2cSJim Jagielski }
703*b1cdbd2cSJim Jagielski
processingInstruction(const rtl::OUString & rTarget,const rtl::OUString & rData)704*b1cdbd2cSJim Jagielski inline sal_Bool SaxWriterHelper::processingInstruction(const rtl::OUString& rTarget, const rtl::OUString& rData) throw( SAXException )
705*b1cdbd2cSJim Jagielski {
706*b1cdbd2cSJim Jagielski FinishStartElement();
707*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '<';
708*b1cdbd2cSJim Jagielski nCurrentPos++;
709*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
710*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
711*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '?';
712*b1cdbd2cSJim Jagielski nCurrentPos++;
713*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
714*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
715*b1cdbd2cSJim Jagielski
716*b1cdbd2cSJim Jagielski sal_Bool bRet(writeString( rTarget, sal_False, sal_False ));
717*b1cdbd2cSJim Jagielski
718*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = ' ';
719*b1cdbd2cSJim Jagielski nCurrentPos++;
720*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
721*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
722*b1cdbd2cSJim Jagielski
723*b1cdbd2cSJim Jagielski if (!writeString( rData, sal_False, sal_False ))
724*b1cdbd2cSJim Jagielski bRet = sal_False;
725*b1cdbd2cSJim Jagielski
726*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '?';
727*b1cdbd2cSJim Jagielski nCurrentPos++;
728*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
729*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
730*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '>';
731*b1cdbd2cSJim Jagielski nCurrentPos++;
732*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
733*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
734*b1cdbd2cSJim Jagielski
735*b1cdbd2cSJim Jagielski return bRet;
736*b1cdbd2cSJim Jagielski }
737*b1cdbd2cSJim Jagielski
startCDATA()738*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::startCDATA() throw( SAXException )
739*b1cdbd2cSJim Jagielski {
740*b1cdbd2cSJim Jagielski FinishStartElement();
741*b1cdbd2cSJim Jagielski if ((nCurrentPos + 9) <= SEQUENCESIZE)
742*b1cdbd2cSJim Jagielski {
743*b1cdbd2cSJim Jagielski memcpy( &(mp_Sequence[nCurrentPos]), "<![CDATA[" , 9 );
744*b1cdbd2cSJim Jagielski nCurrentPos += 9;
745*b1cdbd2cSJim Jagielski }
746*b1cdbd2cSJim Jagielski else
747*b1cdbd2cSJim Jagielski AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)"<![CDATA[" , 9);
748*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
749*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
750*b1cdbd2cSJim Jagielski }
751*b1cdbd2cSJim Jagielski
endCDATA()752*b1cdbd2cSJim Jagielski inline void SaxWriterHelper::endCDATA() throw( SAXException )
753*b1cdbd2cSJim Jagielski {
754*b1cdbd2cSJim Jagielski FinishStartElement();
755*b1cdbd2cSJim Jagielski if ((nCurrentPos + 3) <= SEQUENCESIZE)
756*b1cdbd2cSJim Jagielski {
757*b1cdbd2cSJim Jagielski memcpy( &(mp_Sequence[nCurrentPos]), "]]>" , 3 );
758*b1cdbd2cSJim Jagielski nCurrentPos += 3;
759*b1cdbd2cSJim Jagielski }
760*b1cdbd2cSJim Jagielski else
761*b1cdbd2cSJim Jagielski AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)"]]>" , 3);
762*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
763*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
764*b1cdbd2cSJim Jagielski }
765*b1cdbd2cSJim Jagielski
comment(const rtl::OUString & rComment)766*b1cdbd2cSJim Jagielski inline sal_Bool SaxWriterHelper::comment(const rtl::OUString& rComment) throw( SAXException )
767*b1cdbd2cSJim Jagielski {
768*b1cdbd2cSJim Jagielski FinishStartElement();
769*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '<';
770*b1cdbd2cSJim Jagielski nCurrentPos++;
771*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
772*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
773*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '!';
774*b1cdbd2cSJim Jagielski nCurrentPos++;
775*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
776*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
777*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '-';
778*b1cdbd2cSJim Jagielski nCurrentPos++;
779*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
780*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
781*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '-';
782*b1cdbd2cSJim Jagielski nCurrentPos++;
783*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
784*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
785*b1cdbd2cSJim Jagielski
786*b1cdbd2cSJim Jagielski sal_Bool bRet(writeString( rComment, sal_False, sal_False));
787*b1cdbd2cSJim Jagielski
788*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '-';
789*b1cdbd2cSJim Jagielski nCurrentPos++;
790*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
791*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
792*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '-';
793*b1cdbd2cSJim Jagielski nCurrentPos++;
794*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
795*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
796*b1cdbd2cSJim Jagielski mp_Sequence[nCurrentPos] = '>';
797*b1cdbd2cSJim Jagielski nCurrentPos++;
798*b1cdbd2cSJim Jagielski if (nCurrentPos == SEQUENCESIZE)
799*b1cdbd2cSJim Jagielski nCurrentPos = writeSequence();
800*b1cdbd2cSJim Jagielski
801*b1cdbd2cSJim Jagielski return bRet;
802*b1cdbd2cSJim Jagielski }
803*b1cdbd2cSJim Jagielski
calcXMLByteLength(const sal_Unicode * pStr,sal_Int32 nStrLen,sal_Bool bDoNormalization,sal_Bool bNormalizeWhitespace)804*b1cdbd2cSJim Jagielski inline sal_Int32 calcXMLByteLength( const sal_Unicode *pStr, sal_Int32 nStrLen,
805*b1cdbd2cSJim Jagielski sal_Bool bDoNormalization,
806*b1cdbd2cSJim Jagielski sal_Bool bNormalizeWhitespace )
807*b1cdbd2cSJim Jagielski {
808*b1cdbd2cSJim Jagielski sal_Int32 nOutputLength = 0;
809*b1cdbd2cSJim Jagielski sal_uInt32 nSurrogate = 0;
810*b1cdbd2cSJim Jagielski
811*b1cdbd2cSJim Jagielski for( sal_Int32 i = 0 ; i < nStrLen ; i++ )
812*b1cdbd2cSJim Jagielski {
813*b1cdbd2cSJim Jagielski sal_uInt16 c = pStr[i];
814*b1cdbd2cSJim Jagielski if( !IsInvalidChar(c) && (c >= 0x0001) && (c <= 0x007F) )
815*b1cdbd2cSJim Jagielski {
816*b1cdbd2cSJim Jagielski if( bDoNormalization )
817*b1cdbd2cSJim Jagielski {
818*b1cdbd2cSJim Jagielski switch( c )
819*b1cdbd2cSJim Jagielski {
820*b1cdbd2cSJim Jagielski case '&': // resemble to &
821*b1cdbd2cSJim Jagielski nOutputLength +=5;
822*b1cdbd2cSJim Jagielski break;
823*b1cdbd2cSJim Jagielski case '<': // <
824*b1cdbd2cSJim Jagielski case '>': // >
825*b1cdbd2cSJim Jagielski nOutputLength +=4;
826*b1cdbd2cSJim Jagielski break;
827*b1cdbd2cSJim Jagielski case 39: // 39 == ''', '
828*b1cdbd2cSJim Jagielski case '"': // "
829*b1cdbd2cSJim Jagielski case 13: // 
830*b1cdbd2cSJim Jagielski nOutputLength += 6;
831*b1cdbd2cSJim Jagielski break;
832*b1cdbd2cSJim Jagielski
833*b1cdbd2cSJim Jagielski case 10: // 

834*b1cdbd2cSJim Jagielski case 9: // 	
835*b1cdbd2cSJim Jagielski if( bNormalizeWhitespace )
836*b1cdbd2cSJim Jagielski {
837*b1cdbd2cSJim Jagielski nOutputLength += 6; //
838*b1cdbd2cSJim Jagielski }
839*b1cdbd2cSJim Jagielski else
840*b1cdbd2cSJim Jagielski {
841*b1cdbd2cSJim Jagielski nOutputLength ++;
842*b1cdbd2cSJim Jagielski }
843*b1cdbd2cSJim Jagielski break;
844*b1cdbd2cSJim Jagielski default:
845*b1cdbd2cSJim Jagielski nOutputLength ++;
846*b1cdbd2cSJim Jagielski }
847*b1cdbd2cSJim Jagielski }
848*b1cdbd2cSJim Jagielski else
849*b1cdbd2cSJim Jagielski {
850*b1cdbd2cSJim Jagielski nOutputLength ++;
851*b1cdbd2cSJim Jagielski }
852*b1cdbd2cSJim Jagielski }
853*b1cdbd2cSJim Jagielski else if( c >= 0xd800 && c < 0xdc00 )
854*b1cdbd2cSJim Jagielski {
855*b1cdbd2cSJim Jagielski // save surrogate
856*b1cdbd2cSJim Jagielski nSurrogate = ( ( c & 0x03ff ) + 0x0040 );
857*b1cdbd2cSJim Jagielski }
858*b1cdbd2cSJim Jagielski else if( c >= 0xdc00 && c < 0xe000 )
859*b1cdbd2cSJim Jagielski {
860*b1cdbd2cSJim Jagielski // 2. surrogate: write as UTF-8 (if range is OK
861*b1cdbd2cSJim Jagielski nSurrogate = ( nSurrogate << 10 ) | ( c & 0x03ff );
862*b1cdbd2cSJim Jagielski if( nSurrogate >= 0x00010000 && nSurrogate <= 0x0010FFFF )
863*b1cdbd2cSJim Jagielski nOutputLength += 4;
864*b1cdbd2cSJim Jagielski nSurrogate = 0;
865*b1cdbd2cSJim Jagielski }
866*b1cdbd2cSJim Jagielski else if( c > 0x07FF )
867*b1cdbd2cSJim Jagielski {
868*b1cdbd2cSJim Jagielski nOutputLength += 3;
869*b1cdbd2cSJim Jagielski }
870*b1cdbd2cSJim Jagielski else
871*b1cdbd2cSJim Jagielski {
872*b1cdbd2cSJim Jagielski nOutputLength += 2;
873*b1cdbd2cSJim Jagielski }
874*b1cdbd2cSJim Jagielski
875*b1cdbd2cSJim Jagielski // surrogate processing
876*b1cdbd2cSJim Jagielski if( ( nSurrogate != 0 ) && !( c >= 0xd800 && c < 0xdc00 ) )
877*b1cdbd2cSJim Jagielski nSurrogate = 0;
878*b1cdbd2cSJim Jagielski }
879*b1cdbd2cSJim Jagielski
880*b1cdbd2cSJim Jagielski return nOutputLength;
881*b1cdbd2cSJim Jagielski }
882*b1cdbd2cSJim Jagielski
883*b1cdbd2cSJim Jagielski /** returns position of first ascii 10 within the string, -1 when no 10 in string.
884*b1cdbd2cSJim Jagielski */
getFirstLineBreak(const OUString & str)885*b1cdbd2cSJim Jagielski static inline sal_Int32 getFirstLineBreak( const OUString & str ) throw ()
886*b1cdbd2cSJim Jagielski {
887*b1cdbd2cSJim Jagielski const sal_Unicode *pSource = str.getStr();
888*b1cdbd2cSJim Jagielski sal_Int32 nLen = str.getLength();
889*b1cdbd2cSJim Jagielski
890*b1cdbd2cSJim Jagielski for( int n = 0; n < nLen ; n ++ )
891*b1cdbd2cSJim Jagielski {
892*b1cdbd2cSJim Jagielski if( LINEFEED == pSource[n] ) {
893*b1cdbd2cSJim Jagielski return n;
894*b1cdbd2cSJim Jagielski }
895*b1cdbd2cSJim Jagielski }
896*b1cdbd2cSJim Jagielski return -1;
897*b1cdbd2cSJim Jagielski }
898*b1cdbd2cSJim Jagielski
899*b1cdbd2cSJim Jagielski /** returns position of last ascii 10 within sequence, -1 when no 10 in string.
900*b1cdbd2cSJim Jagielski */
getLastLineBreak(const Sequence<sal_Int8> & seq)901*b1cdbd2cSJim Jagielski static inline sal_Int32 getLastLineBreak( const Sequence<sal_Int8> & seq) throw ()
902*b1cdbd2cSJim Jagielski {
903*b1cdbd2cSJim Jagielski const sal_Int8 *pSource = seq.getConstArray();
904*b1cdbd2cSJim Jagielski sal_Int32 nLen = seq.getLength();
905*b1cdbd2cSJim Jagielski
906*b1cdbd2cSJim Jagielski for( int n = nLen-1; n >= 0 ; n -- )
907*b1cdbd2cSJim Jagielski {
908*b1cdbd2cSJim Jagielski if( LINEFEED == pSource[n] ) {
909*b1cdbd2cSJim Jagielski return n;
910*b1cdbd2cSJim Jagielski }
911*b1cdbd2cSJim Jagielski }
912*b1cdbd2cSJim Jagielski return -1;
913*b1cdbd2cSJim Jagielski }
914*b1cdbd2cSJim Jagielski
915*b1cdbd2cSJim Jagielski
916*b1cdbd2cSJim Jagielski class SAXWriter :
917*b1cdbd2cSJim Jagielski public WeakImplHelper3<
918*b1cdbd2cSJim Jagielski XActiveDataSource,
919*b1cdbd2cSJim Jagielski XExtendedDocumentHandler,
920*b1cdbd2cSJim Jagielski XServiceInfo >
921*b1cdbd2cSJim Jagielski {
922*b1cdbd2cSJim Jagielski public:
SAXWriter()923*b1cdbd2cSJim Jagielski SAXWriter( ) :
924*b1cdbd2cSJim Jagielski m_seqStartElement(),
925*b1cdbd2cSJim Jagielski mp_SaxWriterHelper( NULL ),
926*b1cdbd2cSJim Jagielski m_bForceLineBreak(sal_False),
927*b1cdbd2cSJim Jagielski m_bAllowLineBreak(sal_False)
928*b1cdbd2cSJim Jagielski {}
~SAXWriter()929*b1cdbd2cSJim Jagielski ~SAXWriter()
930*b1cdbd2cSJim Jagielski {
931*b1cdbd2cSJim Jagielski delete mp_SaxWriterHelper;
932*b1cdbd2cSJim Jagielski }
933*b1cdbd2cSJim Jagielski
934*b1cdbd2cSJim Jagielski public: // XActiveDataSource
setOutputStream(const Reference<XOutputStream> & aStream)935*b1cdbd2cSJim Jagielski virtual void SAL_CALL setOutputStream(const Reference< XOutputStream > & aStream)
936*b1cdbd2cSJim Jagielski throw (RuntimeException)
937*b1cdbd2cSJim Jagielski {
938*b1cdbd2cSJim Jagielski // temporary: set same stream again to clear buffer
939*b1cdbd2cSJim Jagielski if ( m_out == aStream && mp_SaxWriterHelper && m_bDocStarted )
940*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->clearBuffer();
941*b1cdbd2cSJim Jagielski else
942*b1cdbd2cSJim Jagielski {
943*b1cdbd2cSJim Jagielski
944*b1cdbd2cSJim Jagielski m_out = aStream;
945*b1cdbd2cSJim Jagielski delete mp_SaxWriterHelper;
946*b1cdbd2cSJim Jagielski mp_SaxWriterHelper = new SaxWriterHelper(m_out);
947*b1cdbd2cSJim Jagielski m_bDocStarted = sal_False;
948*b1cdbd2cSJim Jagielski m_nLevel = 0;
949*b1cdbd2cSJim Jagielski m_bIsCDATA = sal_False;
950*b1cdbd2cSJim Jagielski
951*b1cdbd2cSJim Jagielski }
952*b1cdbd2cSJim Jagielski }
getOutputStream(void)953*b1cdbd2cSJim Jagielski virtual Reference< XOutputStream > SAL_CALL getOutputStream(void)
954*b1cdbd2cSJim Jagielski throw(RuntimeException)
955*b1cdbd2cSJim Jagielski { return m_out; }
956*b1cdbd2cSJim Jagielski
957*b1cdbd2cSJim Jagielski public: // XDocumentHandler
958*b1cdbd2cSJim Jagielski virtual void SAL_CALL startDocument(void)
959*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
960*b1cdbd2cSJim Jagielski
961*b1cdbd2cSJim Jagielski virtual void SAL_CALL endDocument(void)
962*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
963*b1cdbd2cSJim Jagielski
964*b1cdbd2cSJim Jagielski virtual void SAL_CALL startElement(const OUString& aName,
965*b1cdbd2cSJim Jagielski const Reference< XAttributeList > & xAttribs)
966*b1cdbd2cSJim Jagielski throw (SAXException, RuntimeException);
967*b1cdbd2cSJim Jagielski
968*b1cdbd2cSJim Jagielski virtual void SAL_CALL endElement(const OUString& aName)
969*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
970*b1cdbd2cSJim Jagielski
971*b1cdbd2cSJim Jagielski virtual void SAL_CALL characters(const OUString& aChars)
972*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
973*b1cdbd2cSJim Jagielski
974*b1cdbd2cSJim Jagielski virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces)
975*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
976*b1cdbd2cSJim Jagielski virtual void SAL_CALL processingInstruction(const OUString& aTarget,
977*b1cdbd2cSJim Jagielski const OUString& aData)
978*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
979*b1cdbd2cSJim Jagielski virtual void SAL_CALL setDocumentLocator(const Reference< XLocator > & xLocator)
980*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
981*b1cdbd2cSJim Jagielski
982*b1cdbd2cSJim Jagielski public: // XExtendedDocumentHandler
983*b1cdbd2cSJim Jagielski virtual void SAL_CALL startCDATA(void) throw(SAXException, RuntimeException);
984*b1cdbd2cSJim Jagielski virtual void SAL_CALL endCDATA(void) throw(RuntimeException);
985*b1cdbd2cSJim Jagielski virtual void SAL_CALL comment(const OUString& sComment)
986*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
987*b1cdbd2cSJim Jagielski virtual void SAL_CALL unknown(const OUString& sString)
988*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException);
989*b1cdbd2cSJim Jagielski virtual void SAL_CALL allowLineBreak(void)
990*b1cdbd2cSJim Jagielski throw(SAXException,RuntimeException);
991*b1cdbd2cSJim Jagielski
992*b1cdbd2cSJim Jagielski public: // XServiceInfo
993*b1cdbd2cSJim Jagielski OUString SAL_CALL getImplementationName() throw();
994*b1cdbd2cSJim Jagielski Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
995*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
996*b1cdbd2cSJim Jagielski
997*b1cdbd2cSJim Jagielski private:
998*b1cdbd2cSJim Jagielski
999*b1cdbd2cSJim Jagielski void writeSequence( const Sequence<sal_Int8> & seq );
1000*b1cdbd2cSJim Jagielski sal_Int32 getIndentPrefixLength( sal_Int32 nFirstLineBreakOccurence ) throw();
1001*b1cdbd2cSJim Jagielski
1002*b1cdbd2cSJim Jagielski Reference< XOutputStream > m_out;
1003*b1cdbd2cSJim Jagielski Sequence < sal_Int8 > m_seqStartElement;
1004*b1cdbd2cSJim Jagielski SaxWriterHelper* mp_SaxWriterHelper;
1005*b1cdbd2cSJim Jagielski
1006*b1cdbd2cSJim Jagielski // Status information
1007*b1cdbd2cSJim Jagielski sal_Bool m_bDocStarted : 1;
1008*b1cdbd2cSJim Jagielski sal_Bool m_bIsCDATA : 1;
1009*b1cdbd2cSJim Jagielski sal_Bool m_bForceLineBreak : 1;
1010*b1cdbd2cSJim Jagielski sal_Bool m_bAllowLineBreak : 1;
1011*b1cdbd2cSJim Jagielski sal_Int32 m_nLevel;
1012*b1cdbd2cSJim Jagielski };
1013*b1cdbd2cSJim Jagielski
1014*b1cdbd2cSJim Jagielski
1015*b1cdbd2cSJim Jagielski //--------------------------------------
1016*b1cdbd2cSJim Jagielski // the extern interface
1017*b1cdbd2cSJim Jagielski //---------------------------------------
SaxWriter_CreateInstance(const Reference<XMultiServiceFactory> &)1018*b1cdbd2cSJim Jagielski Reference < XInterface > SAL_CALL SaxWriter_CreateInstance(
1019*b1cdbd2cSJim Jagielski const Reference < XMultiServiceFactory > & )
1020*b1cdbd2cSJim Jagielski throw (Exception)
1021*b1cdbd2cSJim Jagielski {
1022*b1cdbd2cSJim Jagielski SAXWriter *p = new SAXWriter;
1023*b1cdbd2cSJim Jagielski return Reference< XInterface > ( SAL_STATIC_CAST(OWeakObject *, p ) );
1024*b1cdbd2cSJim Jagielski }
1025*b1cdbd2cSJim Jagielski
SaxWriter_getServiceName()1026*b1cdbd2cSJim Jagielski OUString SaxWriter_getServiceName() throw()
1027*b1cdbd2cSJim Jagielski {
1028*b1cdbd2cSJim Jagielski return OUString::createFromAscii( "com.sun.star.xml.sax.Writer" );
1029*b1cdbd2cSJim Jagielski }
1030*b1cdbd2cSJim Jagielski
SaxWriter_getImplementationName()1031*b1cdbd2cSJim Jagielski OUString SaxWriter_getImplementationName() throw()
1032*b1cdbd2cSJim Jagielski {
1033*b1cdbd2cSJim Jagielski return OUString::createFromAscii( "com.sun.star.extensions.xml.sax.Writer" );
1034*b1cdbd2cSJim Jagielski }
1035*b1cdbd2cSJim Jagielski
SaxWriter_getSupportedServiceNames(void)1036*b1cdbd2cSJim Jagielski Sequence< OUString > SaxWriter_getSupportedServiceNames(void) throw()
1037*b1cdbd2cSJim Jagielski {
1038*b1cdbd2cSJim Jagielski Sequence<OUString> aRet(1);
1039*b1cdbd2cSJim Jagielski aRet.getArray()[0] = SaxWriter_getServiceName();
1040*b1cdbd2cSJim Jagielski return aRet;
1041*b1cdbd2cSJim Jagielski }
1042*b1cdbd2cSJim Jagielski
1043*b1cdbd2cSJim Jagielski
getIndentPrefixLength(sal_Int32 nFirstLineBreakOccurence)1044*b1cdbd2cSJim Jagielski sal_Int32 SAXWriter::getIndentPrefixLength( sal_Int32 nFirstLineBreakOccurence ) throw()
1045*b1cdbd2cSJim Jagielski {
1046*b1cdbd2cSJim Jagielski sal_Int32 nLength =-1;
1047*b1cdbd2cSJim Jagielski if (mp_SaxWriterHelper)
1048*b1cdbd2cSJim Jagielski {
1049*b1cdbd2cSJim Jagielski if ( m_bForceLineBreak ||
1050*b1cdbd2cSJim Jagielski (m_bAllowLineBreak &&
1051*b1cdbd2cSJim Jagielski ((nFirstLineBreakOccurence + mp_SaxWriterHelper->GetLastColumnCount()) > MAXCOLUMNCOUNT)) )
1052*b1cdbd2cSJim Jagielski nLength = m_nLevel;
1053*b1cdbd2cSJim Jagielski }
1054*b1cdbd2cSJim Jagielski m_bForceLineBreak = sal_False;
1055*b1cdbd2cSJim Jagielski m_bAllowLineBreak = sal_False;
1056*b1cdbd2cSJim Jagielski return nLength;
1057*b1cdbd2cSJim Jagielski }
1058*b1cdbd2cSJim Jagielski
isFirstCharWhitespace(const sal_Unicode * p)1059*b1cdbd2cSJim Jagielski static inline sal_Bool isFirstCharWhitespace( const sal_Unicode *p ) throw()
1060*b1cdbd2cSJim Jagielski {
1061*b1cdbd2cSJim Jagielski return *p == ' ';
1062*b1cdbd2cSJim Jagielski }
1063*b1cdbd2cSJim Jagielski
1064*b1cdbd2cSJim Jagielski
1065*b1cdbd2cSJim Jagielski // XServiceInfo
getImplementationName()1066*b1cdbd2cSJim Jagielski OUString SAXWriter::getImplementationName() throw()
1067*b1cdbd2cSJim Jagielski {
1068*b1cdbd2cSJim Jagielski return SaxWriter_getImplementationName();
1069*b1cdbd2cSJim Jagielski }
1070*b1cdbd2cSJim Jagielski
1071*b1cdbd2cSJim Jagielski // XServiceInfo
supportsService(const OUString & ServiceName)1072*b1cdbd2cSJim Jagielski sal_Bool SAXWriter::supportsService(const OUString& ServiceName) throw()
1073*b1cdbd2cSJim Jagielski {
1074*b1cdbd2cSJim Jagielski Sequence< OUString > aSNL = getSupportedServiceNames();
1075*b1cdbd2cSJim Jagielski const OUString * pArray = aSNL.getConstArray();
1076*b1cdbd2cSJim Jagielski
1077*b1cdbd2cSJim Jagielski for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1078*b1cdbd2cSJim Jagielski if( pArray[i] == ServiceName )
1079*b1cdbd2cSJim Jagielski return sal_True;
1080*b1cdbd2cSJim Jagielski
1081*b1cdbd2cSJim Jagielski return sal_False;
1082*b1cdbd2cSJim Jagielski }
1083*b1cdbd2cSJim Jagielski
1084*b1cdbd2cSJim Jagielski // XServiceInfo
getSupportedServiceNames(void)1085*b1cdbd2cSJim Jagielski Sequence< OUString > SAXWriter::getSupportedServiceNames(void) throw ()
1086*b1cdbd2cSJim Jagielski {
1087*b1cdbd2cSJim Jagielski Sequence<OUString> seq(1);
1088*b1cdbd2cSJim Jagielski seq.getArray()[0] = SaxWriter_getServiceName();
1089*b1cdbd2cSJim Jagielski return seq;
1090*b1cdbd2cSJim Jagielski }
1091*b1cdbd2cSJim Jagielski
1092*b1cdbd2cSJim Jagielski
1093*b1cdbd2cSJim Jagielski
startDocument()1094*b1cdbd2cSJim Jagielski void SAXWriter::startDocument() throw(SAXException, RuntimeException )
1095*b1cdbd2cSJim Jagielski {
1096*b1cdbd2cSJim Jagielski if( m_bDocStarted || ! m_out.is() || !mp_SaxWriterHelper ) {
1097*b1cdbd2cSJim Jagielski throw SAXException();
1098*b1cdbd2cSJim Jagielski }
1099*b1cdbd2cSJim Jagielski m_bDocStarted = sal_True;
1100*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->startDocument();
1101*b1cdbd2cSJim Jagielski }
1102*b1cdbd2cSJim Jagielski
1103*b1cdbd2cSJim Jagielski
endDocument(void)1104*b1cdbd2cSJim Jagielski void SAXWriter::endDocument(void) throw(SAXException, RuntimeException)
1105*b1cdbd2cSJim Jagielski {
1106*b1cdbd2cSJim Jagielski if( ! m_bDocStarted )
1107*b1cdbd2cSJim Jagielski {
1108*b1cdbd2cSJim Jagielski throw SAXException(
1109*b1cdbd2cSJim Jagielski OUString::createFromAscii( "endDocument called before startDocument" ),
1110*b1cdbd2cSJim Jagielski Reference< XInterface >() , Any() );
1111*b1cdbd2cSJim Jagielski }
1112*b1cdbd2cSJim Jagielski if( m_nLevel ) {
1113*b1cdbd2cSJim Jagielski throw SAXException(
1114*b1cdbd2cSJim Jagielski OUString::createFromAscii( "unexpected end of document" ),
1115*b1cdbd2cSJim Jagielski Reference< XInterface >() , Any() );
1116*b1cdbd2cSJim Jagielski }
1117*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->endDocument();
1118*b1cdbd2cSJim Jagielski try
1119*b1cdbd2cSJim Jagielski {
1120*b1cdbd2cSJim Jagielski m_out->closeOutput();
1121*b1cdbd2cSJim Jagielski }
1122*b1cdbd2cSJim Jagielski catch( IOException & e )
1123*b1cdbd2cSJim Jagielski {
1124*b1cdbd2cSJim Jagielski Any a;
1125*b1cdbd2cSJim Jagielski a <<= e;
1126*b1cdbd2cSJim Jagielski throw SAXException(
1127*b1cdbd2cSJim Jagielski OUString::createFromAscii( "IO exception during closing the IO Stream" ),
1128*b1cdbd2cSJim Jagielski Reference< XInterface > (),
1129*b1cdbd2cSJim Jagielski a );
1130*b1cdbd2cSJim Jagielski }
1131*b1cdbd2cSJim Jagielski }
1132*b1cdbd2cSJim Jagielski
1133*b1cdbd2cSJim Jagielski
startElement(const OUString & aName,const Reference<XAttributeList> & xAttribs)1134*b1cdbd2cSJim Jagielski void SAXWriter::startElement(const OUString& aName, const Reference< XAttributeList >& xAttribs)
1135*b1cdbd2cSJim Jagielski throw(SAXException, RuntimeException)
1136*b1cdbd2cSJim Jagielski {
1137*b1cdbd2cSJim Jagielski if( ! m_bDocStarted )
1138*b1cdbd2cSJim Jagielski {
1139*b1cdbd2cSJim Jagielski SAXException except;
1140*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "startElement called before startDocument" ));
1141*b1cdbd2cSJim Jagielski throw except;
1142*b1cdbd2cSJim Jagielski }
1143*b1cdbd2cSJim Jagielski if( m_bIsCDATA )
1144*b1cdbd2cSJim Jagielski {
1145*b1cdbd2cSJim Jagielski SAXException except;
1146*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "startElement call not allowed with CDATA sections" ));
1147*b1cdbd2cSJim Jagielski throw except;
1148*b1cdbd2cSJim Jagielski }
1149*b1cdbd2cSJim Jagielski
1150*b1cdbd2cSJim Jagielski sal_Int32 nLength(0);
1151*b1cdbd2cSJim Jagielski if (m_bAllowLineBreak)
1152*b1cdbd2cSJim Jagielski {
1153*b1cdbd2cSJim Jagielski sal_Int32 nAttribCount = xAttribs.is() ? xAttribs->getLength() : 0;
1154*b1cdbd2cSJim Jagielski
1155*b1cdbd2cSJim Jagielski nLength ++; // "<"
1156*b1cdbd2cSJim Jagielski nLength += calcXMLByteLength( aName.getStr() , aName.getLength(),
1157*b1cdbd2cSJim Jagielski sal_False, sal_False ); // the tag name
1158*b1cdbd2cSJim Jagielski
1159*b1cdbd2cSJim Jagielski sal_Int16 n;
1160*b1cdbd2cSJim Jagielski for( n = 0 ; n < static_cast<sal_Int16>(nAttribCount) ; n ++ ) {
1161*b1cdbd2cSJim Jagielski nLength ++; // " "
1162*b1cdbd2cSJim Jagielski OUString tmp = xAttribs->getNameByIndex( n );
1163*b1cdbd2cSJim Jagielski
1164*b1cdbd2cSJim Jagielski nLength += calcXMLByteLength( tmp.getStr() , tmp.getLength() , sal_False, sal_False );
1165*b1cdbd2cSJim Jagielski
1166*b1cdbd2cSJim Jagielski nLength += 2; // ="
1167*b1cdbd2cSJim Jagielski
1168*b1cdbd2cSJim Jagielski tmp = xAttribs->getValueByIndex( n );
1169*b1cdbd2cSJim Jagielski
1170*b1cdbd2cSJim Jagielski nLength += calcXMLByteLength( tmp.getStr(), tmp.getLength(), sal_True, sal_True );
1171*b1cdbd2cSJim Jagielski
1172*b1cdbd2cSJim Jagielski nLength += 1; // "
1173*b1cdbd2cSJim Jagielski }
1174*b1cdbd2cSJim Jagielski
1175*b1cdbd2cSJim Jagielski nLength ++; // '>'
1176*b1cdbd2cSJim Jagielski }
1177*b1cdbd2cSJim Jagielski
1178*b1cdbd2cSJim Jagielski // Is there a new indentation necesarry ?
1179*b1cdbd2cSJim Jagielski sal_Int32 nPrefix(getIndentPrefixLength( nLength ));
1180*b1cdbd2cSJim Jagielski
1181*b1cdbd2cSJim Jagielski // write into sequence
1182*b1cdbd2cSJim Jagielski if( nPrefix >= 0 )
1183*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nPrefix );
1184*b1cdbd2cSJim Jagielski
1185*b1cdbd2cSJim Jagielski SaxInvalidCharacterError eRet(mp_SaxWriterHelper->startElement(aName, xAttribs));
1186*b1cdbd2cSJim Jagielski
1187*b1cdbd2cSJim Jagielski m_nLevel++;
1188*b1cdbd2cSJim Jagielski
1189*b1cdbd2cSJim Jagielski if (eRet == SAX_WARNING)
1190*b1cdbd2cSJim Jagielski {
1191*b1cdbd2cSJim Jagielski SAXInvalidCharacterException except;
1192*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export in a attribute value" ) );
1193*b1cdbd2cSJim Jagielski throw except;
1194*b1cdbd2cSJim Jagielski }
1195*b1cdbd2cSJim Jagielski else if (eRet == SAX_ERROR)
1196*b1cdbd2cSJim Jagielski {
1197*b1cdbd2cSJim Jagielski SAXException except;
1198*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) );
1199*b1cdbd2cSJim Jagielski throw except;
1200*b1cdbd2cSJim Jagielski }
1201*b1cdbd2cSJim Jagielski }
1202*b1cdbd2cSJim Jagielski
endElement(const OUString & aName)1203*b1cdbd2cSJim Jagielski void SAXWriter::endElement(const OUString& aName) throw (SAXException, RuntimeException)
1204*b1cdbd2cSJim Jagielski {
1205*b1cdbd2cSJim Jagielski if( ! m_bDocStarted ) {
1206*b1cdbd2cSJim Jagielski throw SAXException ();
1207*b1cdbd2cSJim Jagielski }
1208*b1cdbd2cSJim Jagielski m_nLevel --;
1209*b1cdbd2cSJim Jagielski
1210*b1cdbd2cSJim Jagielski if( m_nLevel < 0 ) {
1211*b1cdbd2cSJim Jagielski throw SAXException();
1212*b1cdbd2cSJim Jagielski }
1213*b1cdbd2cSJim Jagielski sal_Bool bRet(sal_True);
1214*b1cdbd2cSJim Jagielski
1215*b1cdbd2cSJim Jagielski if( mp_SaxWriterHelper->FinishEmptyElement() )
1216*b1cdbd2cSJim Jagielski m_bForceLineBreak = sal_False;
1217*b1cdbd2cSJim Jagielski else
1218*b1cdbd2cSJim Jagielski {
1219*b1cdbd2cSJim Jagielski // only ascii chars allowed
1220*b1cdbd2cSJim Jagielski sal_Int32 nLength(0);
1221*b1cdbd2cSJim Jagielski if (m_bAllowLineBreak)
1222*b1cdbd2cSJim Jagielski nLength = 3 + calcXMLByteLength( aName.getStr(), aName.getLength(), sal_False, sal_False );
1223*b1cdbd2cSJim Jagielski sal_Int32 nPrefix = getIndentPrefixLength( nLength );
1224*b1cdbd2cSJim Jagielski
1225*b1cdbd2cSJim Jagielski if( nPrefix >= 0 )
1226*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nPrefix );
1227*b1cdbd2cSJim Jagielski
1228*b1cdbd2cSJim Jagielski bRet = mp_SaxWriterHelper->endElement(aName);
1229*b1cdbd2cSJim Jagielski }
1230*b1cdbd2cSJim Jagielski
1231*b1cdbd2cSJim Jagielski if (!bRet)
1232*b1cdbd2cSJim Jagielski {
1233*b1cdbd2cSJim Jagielski SAXException except;
1234*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) );
1235*b1cdbd2cSJim Jagielski throw except;
1236*b1cdbd2cSJim Jagielski }
1237*b1cdbd2cSJim Jagielski }
1238*b1cdbd2cSJim Jagielski
characters(const OUString & aChars)1239*b1cdbd2cSJim Jagielski void SAXWriter::characters(const OUString& aChars) throw(SAXException, RuntimeException)
1240*b1cdbd2cSJim Jagielski {
1241*b1cdbd2cSJim Jagielski if( ! m_bDocStarted )
1242*b1cdbd2cSJim Jagielski {
1243*b1cdbd2cSJim Jagielski SAXException except;
1244*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "characters method called before startDocument" ) );
1245*b1cdbd2cSJim Jagielski throw except;
1246*b1cdbd2cSJim Jagielski }
1247*b1cdbd2cSJim Jagielski
1248*b1cdbd2cSJim Jagielski sal_Bool bThrowException(sal_False);
1249*b1cdbd2cSJim Jagielski if( aChars.getLength() )
1250*b1cdbd2cSJim Jagielski {
1251*b1cdbd2cSJim Jagielski if( m_bIsCDATA )
1252*b1cdbd2cSJim Jagielski bThrowException = !mp_SaxWriterHelper->writeString( aChars, sal_False, sal_False );
1253*b1cdbd2cSJim Jagielski else
1254*b1cdbd2cSJim Jagielski {
1255*b1cdbd2cSJim Jagielski // Note : nFirstLineBreakOccurence is not exact, because we don't know, how
1256*b1cdbd2cSJim Jagielski // many 2 and 3 byte chars are inbetween. However this whole stuff
1257*b1cdbd2cSJim Jagielski // is eitherway for pretty printing only, so it does not need to be exact.
1258*b1cdbd2cSJim Jagielski sal_Int32 nLength(0);
1259*b1cdbd2cSJim Jagielski sal_Int32 nIndentPrefix(-1);
1260*b1cdbd2cSJim Jagielski if (m_bAllowLineBreak)
1261*b1cdbd2cSJim Jagielski {
1262*b1cdbd2cSJim Jagielski sal_Int32 nFirstLineBreakOccurence = getFirstLineBreak( aChars );
1263*b1cdbd2cSJim Jagielski
1264*b1cdbd2cSJim Jagielski nLength = calcXMLByteLength( aChars.getStr(), aChars.getLength(),
1265*b1cdbd2cSJim Jagielski ! m_bIsCDATA , sal_False );
1266*b1cdbd2cSJim Jagielski nIndentPrefix = getIndentPrefixLength(
1267*b1cdbd2cSJim Jagielski nFirstLineBreakOccurence >= 0 ? nFirstLineBreakOccurence : nLength );
1268*b1cdbd2cSJim Jagielski }
1269*b1cdbd2cSJim Jagielski else
1270*b1cdbd2cSJim Jagielski nIndentPrefix = getIndentPrefixLength(nLength);
1271*b1cdbd2cSJim Jagielski
1272*b1cdbd2cSJim Jagielski // insert indentation
1273*b1cdbd2cSJim Jagielski if( nIndentPrefix >= 0 )
1274*b1cdbd2cSJim Jagielski {
1275*b1cdbd2cSJim Jagielski if( isFirstCharWhitespace( aChars.getStr() ) )
1276*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nIndentPrefix - 1 );
1277*b1cdbd2cSJim Jagielski else
1278*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nIndentPrefix );
1279*b1cdbd2cSJim Jagielski }
1280*b1cdbd2cSJim Jagielski bThrowException = !mp_SaxWriterHelper->writeString(aChars, sal_True , sal_False);
1281*b1cdbd2cSJim Jagielski }
1282*b1cdbd2cSJim Jagielski }
1283*b1cdbd2cSJim Jagielski if (bThrowException)
1284*b1cdbd2cSJim Jagielski {
1285*b1cdbd2cSJim Jagielski SAXInvalidCharacterException except;
1286*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) );
1287*b1cdbd2cSJim Jagielski throw except;
1288*b1cdbd2cSJim Jagielski }
1289*b1cdbd2cSJim Jagielski }
1290*b1cdbd2cSJim Jagielski
1291*b1cdbd2cSJim Jagielski
ignorableWhitespace(const OUString &)1292*b1cdbd2cSJim Jagielski void SAXWriter::ignorableWhitespace(const OUString&) throw(SAXException, RuntimeException)
1293*b1cdbd2cSJim Jagielski {
1294*b1cdbd2cSJim Jagielski if( ! m_bDocStarted )
1295*b1cdbd2cSJim Jagielski {
1296*b1cdbd2cSJim Jagielski throw SAXException ();
1297*b1cdbd2cSJim Jagielski }
1298*b1cdbd2cSJim Jagielski
1299*b1cdbd2cSJim Jagielski m_bForceLineBreak = sal_True;
1300*b1cdbd2cSJim Jagielski }
1301*b1cdbd2cSJim Jagielski
processingInstruction(const OUString & aTarget,const OUString & aData)1302*b1cdbd2cSJim Jagielski void SAXWriter::processingInstruction(const OUString& aTarget, const OUString& aData)
1303*b1cdbd2cSJim Jagielski throw (SAXException, RuntimeException)
1304*b1cdbd2cSJim Jagielski {
1305*b1cdbd2cSJim Jagielski if( ! m_bDocStarted || m_bIsCDATA )
1306*b1cdbd2cSJim Jagielski {
1307*b1cdbd2cSJim Jagielski throw SAXException();
1308*b1cdbd2cSJim Jagielski }
1309*b1cdbd2cSJim Jagielski
1310*b1cdbd2cSJim Jagielski sal_Int32 nLength(0);
1311*b1cdbd2cSJim Jagielski if (m_bAllowLineBreak)
1312*b1cdbd2cSJim Jagielski {
1313*b1cdbd2cSJim Jagielski nLength = 2; // "<?"
1314*b1cdbd2cSJim Jagielski nLength += calcXMLByteLength( aTarget.getStr(), aTarget.getLength(), sal_False, sal_False );
1315*b1cdbd2cSJim Jagielski
1316*b1cdbd2cSJim Jagielski nLength += 1; // " "
1317*b1cdbd2cSJim Jagielski
1318*b1cdbd2cSJim Jagielski nLength += calcXMLByteLength( aData.getStr(), aData.getLength(), sal_False, sal_False );
1319*b1cdbd2cSJim Jagielski
1320*b1cdbd2cSJim Jagielski nLength += 2; // "?>"
1321*b1cdbd2cSJim Jagielski }
1322*b1cdbd2cSJim Jagielski
1323*b1cdbd2cSJim Jagielski sal_Int32 nPrefix = getIndentPrefixLength( nLength );
1324*b1cdbd2cSJim Jagielski
1325*b1cdbd2cSJim Jagielski if( nPrefix >= 0 )
1326*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nPrefix );
1327*b1cdbd2cSJim Jagielski
1328*b1cdbd2cSJim Jagielski if (!mp_SaxWriterHelper->processingInstruction(aTarget, aData))
1329*b1cdbd2cSJim Jagielski {
1330*b1cdbd2cSJim Jagielski SAXException except;
1331*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) );
1332*b1cdbd2cSJim Jagielski throw except;
1333*b1cdbd2cSJim Jagielski }
1334*b1cdbd2cSJim Jagielski }
1335*b1cdbd2cSJim Jagielski
1336*b1cdbd2cSJim Jagielski
setDocumentLocator(const Reference<XLocator> &)1337*b1cdbd2cSJim Jagielski void SAXWriter::setDocumentLocator(const Reference< XLocator >&)
1338*b1cdbd2cSJim Jagielski throw (SAXException, RuntimeException)
1339*b1cdbd2cSJim Jagielski {
1340*b1cdbd2cSJim Jagielski
1341*b1cdbd2cSJim Jagielski }
1342*b1cdbd2cSJim Jagielski
startCDATA(void)1343*b1cdbd2cSJim Jagielski void SAXWriter::startCDATA(void) throw(SAXException, RuntimeException)
1344*b1cdbd2cSJim Jagielski {
1345*b1cdbd2cSJim Jagielski if( ! m_bDocStarted || m_bIsCDATA)
1346*b1cdbd2cSJim Jagielski {
1347*b1cdbd2cSJim Jagielski throw SAXException ();
1348*b1cdbd2cSJim Jagielski }
1349*b1cdbd2cSJim Jagielski
1350*b1cdbd2cSJim Jagielski sal_Int32 nLength = 9;
1351*b1cdbd2cSJim Jagielski sal_Int32 nPrefix = getIndentPrefixLength( nLength );
1352*b1cdbd2cSJim Jagielski if( nPrefix >= 0 )
1353*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nPrefix );
1354*b1cdbd2cSJim Jagielski
1355*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->startCDATA();
1356*b1cdbd2cSJim Jagielski
1357*b1cdbd2cSJim Jagielski m_bIsCDATA = sal_True;
1358*b1cdbd2cSJim Jagielski }
1359*b1cdbd2cSJim Jagielski
endCDATA(void)1360*b1cdbd2cSJim Jagielski void SAXWriter::endCDATA(void) throw (RuntimeException)
1361*b1cdbd2cSJim Jagielski {
1362*b1cdbd2cSJim Jagielski if( ! m_bDocStarted | ! m_bIsCDATA)
1363*b1cdbd2cSJim Jagielski {
1364*b1cdbd2cSJim Jagielski SAXException except;
1365*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "endCDATA was called without startCDATA" ) );
1366*b1cdbd2cSJim Jagielski throw except;
1367*b1cdbd2cSJim Jagielski }
1368*b1cdbd2cSJim Jagielski
1369*b1cdbd2cSJim Jagielski sal_Int32 nLength = 3;
1370*b1cdbd2cSJim Jagielski sal_Int32 nPrefix = getIndentPrefixLength( nLength );
1371*b1cdbd2cSJim Jagielski if( nPrefix >= 0 )
1372*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nPrefix );
1373*b1cdbd2cSJim Jagielski
1374*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->endCDATA();
1375*b1cdbd2cSJim Jagielski
1376*b1cdbd2cSJim Jagielski m_bIsCDATA = sal_False;
1377*b1cdbd2cSJim Jagielski }
1378*b1cdbd2cSJim Jagielski
1379*b1cdbd2cSJim Jagielski
comment(const OUString & sComment)1380*b1cdbd2cSJim Jagielski void SAXWriter::comment(const OUString& sComment) throw(SAXException, RuntimeException)
1381*b1cdbd2cSJim Jagielski {
1382*b1cdbd2cSJim Jagielski if( ! m_bDocStarted || m_bIsCDATA )
1383*b1cdbd2cSJim Jagielski {
1384*b1cdbd2cSJim Jagielski throw SAXException();
1385*b1cdbd2cSJim Jagielski }
1386*b1cdbd2cSJim Jagielski
1387*b1cdbd2cSJim Jagielski sal_Int32 nLength(0);
1388*b1cdbd2cSJim Jagielski if (m_bAllowLineBreak)
1389*b1cdbd2cSJim Jagielski {
1390*b1cdbd2cSJim Jagielski nLength = 4; // "<!--"
1391*b1cdbd2cSJim Jagielski nLength += calcXMLByteLength( sComment.getStr(), sComment.getLength(), sal_False, sal_False);
1392*b1cdbd2cSJim Jagielski
1393*b1cdbd2cSJim Jagielski nLength += 3;
1394*b1cdbd2cSJim Jagielski }
1395*b1cdbd2cSJim Jagielski
1396*b1cdbd2cSJim Jagielski sal_Int32 nPrefix = getIndentPrefixLength( nLength );
1397*b1cdbd2cSJim Jagielski if( nPrefix >= 0 )
1398*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nPrefix );
1399*b1cdbd2cSJim Jagielski
1400*b1cdbd2cSJim Jagielski if (!mp_SaxWriterHelper->comment(sComment))
1401*b1cdbd2cSJim Jagielski {
1402*b1cdbd2cSJim Jagielski SAXException except;
1403*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) );
1404*b1cdbd2cSJim Jagielski throw except;
1405*b1cdbd2cSJim Jagielski }
1406*b1cdbd2cSJim Jagielski }
1407*b1cdbd2cSJim Jagielski
1408*b1cdbd2cSJim Jagielski
allowLineBreak()1409*b1cdbd2cSJim Jagielski void SAXWriter::allowLineBreak( ) throw ( SAXException , RuntimeException)
1410*b1cdbd2cSJim Jagielski {
1411*b1cdbd2cSJim Jagielski if( ! m_bDocStarted || m_bAllowLineBreak ) {
1412*b1cdbd2cSJim Jagielski throw SAXException();
1413*b1cdbd2cSJim Jagielski }
1414*b1cdbd2cSJim Jagielski
1415*b1cdbd2cSJim Jagielski m_bAllowLineBreak = sal_True;
1416*b1cdbd2cSJim Jagielski }
1417*b1cdbd2cSJim Jagielski
unknown(const OUString & sString)1418*b1cdbd2cSJim Jagielski void SAXWriter::unknown(const OUString& sString) throw (SAXException, RuntimeException)
1419*b1cdbd2cSJim Jagielski {
1420*b1cdbd2cSJim Jagielski
1421*b1cdbd2cSJim Jagielski if( ! m_bDocStarted )
1422*b1cdbd2cSJim Jagielski {
1423*b1cdbd2cSJim Jagielski throw SAXException ();
1424*b1cdbd2cSJim Jagielski }
1425*b1cdbd2cSJim Jagielski if( m_bIsCDATA )
1426*b1cdbd2cSJim Jagielski {
1427*b1cdbd2cSJim Jagielski throw SAXException();
1428*b1cdbd2cSJim Jagielski }
1429*b1cdbd2cSJim Jagielski
1430*b1cdbd2cSJim Jagielski if( sString.matchAsciiL( "<?xml", 5 ) )
1431*b1cdbd2cSJim Jagielski return;
1432*b1cdbd2cSJim Jagielski
1433*b1cdbd2cSJim Jagielski sal_Int32 nLength(0);
1434*b1cdbd2cSJim Jagielski if (m_bAllowLineBreak)
1435*b1cdbd2cSJim Jagielski nLength = calcXMLByteLength( sString.getStr(), sString.getLength(), sal_False, sal_False );
1436*b1cdbd2cSJim Jagielski
1437*b1cdbd2cSJim Jagielski sal_Int32 nPrefix = getIndentPrefixLength( nLength );
1438*b1cdbd2cSJim Jagielski if( nPrefix >= 0 )
1439*b1cdbd2cSJim Jagielski mp_SaxWriterHelper->insertIndentation( nPrefix );
1440*b1cdbd2cSJim Jagielski
1441*b1cdbd2cSJim Jagielski if (!mp_SaxWriterHelper->writeString( sString, sal_False, sal_False))
1442*b1cdbd2cSJim Jagielski {
1443*b1cdbd2cSJim Jagielski SAXException except;
1444*b1cdbd2cSJim Jagielski except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid charcter during XML-Export" ) );
1445*b1cdbd2cSJim Jagielski throw except;
1446*b1cdbd2cSJim Jagielski }
1447*b1cdbd2cSJim Jagielski }
1448*b1cdbd2cSJim Jagielski
1449*b1cdbd2cSJim Jagielski }
1450*b1cdbd2cSJim Jagielski
1451