1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #ifndef SAX_FASTSERIALIZER_HXX
29*cdf0e10cSrcweir #define SAX_FASTSERIALIZER_HXX
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XFastSerializer.hpp>
32*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
35*cdf0e10cSrcweir #include <cppuhelper/implbase2.hxx>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <stack>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include "sax/dllapi.h"
40*cdf0e10cSrcweir #include "sax/fshelper.hxx"
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #define SERIALIZER_IMPLEMENTATION_NAME	"com.sun.star.comp.extensions.xml.sax.FastSerializer"
43*cdf0e10cSrcweir #define SERIALIZER_SERVICE_NAME		"com.sun.star.xml.sax.FastSerializer"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir namespace sax_fastparser {
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir class SAX_DLLPUBLIC FastSaxSerializer : public ::cppu::WeakImplHelper2< ::com::sun::star::xml::sax::XFastSerializer, ::com::sun::star::lang::XServiceInfo >
48*cdf0e10cSrcweir {
49*cdf0e10cSrcweir public:
50*cdf0e10cSrcweir     explicit            FastSaxSerializer(  );
51*cdf0e10cSrcweir     virtual             ~FastSaxSerializer();
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir     ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > getOutputStream() {return mxOutputStream;}
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir 	// The implementation details
56*cdf0e10cSrcweir     static ::com::sun::star::uno::Sequence< ::rtl::OUString > 	getSupportedServiceNames_Static(void);
57*cdf0e10cSrcweir 	static ::rtl::OUString 				                        getImplementationName_Static();
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir 	// XFastSerializer
60*cdf0e10cSrcweir 	virtual void SAL_CALL startDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
61*cdf0e10cSrcweir     virtual void SAL_CALL endDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
62*cdf0e10cSrcweir     virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs )
63*cdf0e10cSrcweir 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
64*cdf0e10cSrcweir     virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs )
65*cdf0e10cSrcweir 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
66*cdf0e10cSrcweir     virtual void SAL_CALL endFastElement( ::sal_Int32 Element )
67*cdf0e10cSrcweir 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
68*cdf0e10cSrcweir     virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name )
69*cdf0e10cSrcweir 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
70*cdf0e10cSrcweir     virtual void SAL_CALL singleFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs )
71*cdf0e10cSrcweir 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
72*cdf0e10cSrcweir     virtual void SAL_CALL singleUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs )
73*cdf0e10cSrcweir 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
74*cdf0e10cSrcweir     virtual void SAL_CALL characters( const ::rtl::OUString& aChars )
75*cdf0e10cSrcweir 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
76*cdf0e10cSrcweir     virtual void SAL_CALL setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
77*cdf0e10cSrcweir 		throw (::com::sun::star::uno::RuntimeException);
78*cdf0e10cSrcweir     virtual void SAL_CALL setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler )
79*cdf0e10cSrcweir 		throw (::com::sun::star::uno::RuntimeException);
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 	// XServiceInfo
82*cdf0e10cSrcweir     virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw ( ::com::sun::star::uno::RuntimeException );
83*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw ( ::com::sun::star::uno::RuntimeException );
84*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw ( ::com::sun::star::uno::RuntimeException );
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 	// C++ helpers
87*cdf0e10cSrcweir     virtual void SAL_CALL writeId( ::sal_Int32 Element );
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 	static ::rtl::OUString escapeXml( const ::rtl::OUString& s );
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir public:
92*cdf0e10cSrcweir     /** From now on, don't write directly to the stream, but to top of a stack.
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir         This is to be able to change the order of the data being written.
95*cdf0e10cSrcweir         If you need to write eg.
96*cdf0e10cSrcweir           p, r, rPr, [something], /rPr, t, [text], /r, /p,
97*cdf0e10cSrcweir         but get it in order
98*cdf0e10cSrcweir           p, r, t, [text], /t, rPr, [something], /rPr, /r, /p,
99*cdf0e10cSrcweir         simply do
100*cdf0e10cSrcweir           p, r, mark(), t, [text], /t, mark(), rPr, [something], /rPr,
101*cdf0e10cSrcweir           mergeTopMarks( true ), mergeTopMarks(), /r, /p
102*cdf0e10cSrcweir         and you are done.
103*cdf0e10cSrcweir      */
104*cdf0e10cSrcweir     void mark();
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir     /** Merge 2 topmost marks.
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir         There are 3 possibilities - prepend the top before the second top-most
109*cdf0e10cSrcweir         mark, append it, or append it later; prepending brings the possibility
110*cdf0e10cSrcweir         to switch parts of the output, appending later allows to write some
111*cdf0e10cSrcweir         output in advance.
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir         Writes the result to the output stream if the mark stack becomes empty
114*cdf0e10cSrcweir         by the operation.
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir         When the MERGE_MARKS_POSTPONE is specified, the merge happens just
117*cdf0e10cSrcweir         before the next merge.
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir         @see mark()
120*cdf0e10cSrcweir      */
121*cdf0e10cSrcweir     void mergeTopMarks( sax_fastparser::MergeMarksEnum eMergeType = sax_fastparser::MERGE_MARKS_APPEND );
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir private:
124*cdf0e10cSrcweir 	::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > mxOutputStream;
125*cdf0e10cSrcweir 	::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxFastTokenHandler;
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir     typedef ::com::sun::star::uno::Sequence< ::sal_Int8 > Int8Sequence;
128*cdf0e10cSrcweir     class ForMerge
129*cdf0e10cSrcweir     {
130*cdf0e10cSrcweir         Int8Sequence maData;
131*cdf0e10cSrcweir         Int8Sequence maPostponed;
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir     public:
134*cdf0e10cSrcweir         ForMerge() : maData(), maPostponed() {}
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir         Int8Sequence& getData();
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir         void prepend( const Int8Sequence &rWhat );
139*cdf0e10cSrcweir         void append( const Int8Sequence &rWhat );
140*cdf0e10cSrcweir         void postpone( const Int8Sequence &rWhat );
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir     private:
143*cdf0e10cSrcweir         static void merge( Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend );
144*cdf0e10cSrcweir     };
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir     ::std::stack< ForMerge > maMarkStack;
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir 	void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
149*cdf0e10cSrcweir     void write( const ::rtl::OUString& s );
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir protected:
152*cdf0e10cSrcweir     /** Forward the call to the output stream, or write to the stack.
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir         The latter in the case that we are inside a mark().
155*cdf0e10cSrcweir      */
156*cdf0e10cSrcweir     void writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
157*cdf0e10cSrcweir };
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir } // namespace sax_fastparser
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir #endif
162