1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef SAX_FASTSERIALIZER_HXX
25 #define SAX_FASTSERIALIZER_HXX
26 
27 #include <com/sun/star/xml/sax/XFastSerializer.hpp>
28 #include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/io/XOutputStream.hpp>
31 #include <cppuhelper/implbase2.hxx>
32 
33 #include <stack>
34 
35 #include "sax/dllapi.h"
36 #include "sax/fshelper.hxx"
37 
38 #define SERIALIZER_IMPLEMENTATION_NAME	"com.sun.star.comp.extensions.xml.sax.FastSerializer"
39 #define SERIALIZER_SERVICE_NAME		"com.sun.star.xml.sax.FastSerializer"
40 
41 namespace sax_fastparser {
42 
43 class SAX_DLLPUBLIC FastSaxSerializer : public ::cppu::WeakImplHelper2< ::com::sun::star::xml::sax::XFastSerializer, ::com::sun::star::lang::XServiceInfo >
44 {
45 public:
46     explicit            FastSaxSerializer(  );
47     virtual             ~FastSaxSerializer();
48 
getOutputStream()49     ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > getOutputStream() {return mxOutputStream;}
50 
51 	// The implementation details
52     static ::com::sun::star::uno::Sequence< ::rtl::OUString > 	getSupportedServiceNames_Static(void);
53 	static ::rtl::OUString 				                        getImplementationName_Static();
54 
55 	// XFastSerializer
56 	virtual void SAL_CALL startDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
57     virtual void SAL_CALL endDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
58     virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs )
59 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
60     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 )
61 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
62     virtual void SAL_CALL endFastElement( ::sal_Int32 Element )
63 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
64     virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name )
65 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
66     virtual void SAL_CALL singleFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs )
67 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
68     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 )
69 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
70     virtual void SAL_CALL characters( const ::rtl::OUString& aChars )
71 		throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
72     virtual void SAL_CALL setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
73 		throw (::com::sun::star::uno::RuntimeException);
74     virtual void SAL_CALL setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler )
75 		throw (::com::sun::star::uno::RuntimeException);
76 
77 	// XServiceInfo
78     virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw ( ::com::sun::star::uno::RuntimeException );
79     virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw ( ::com::sun::star::uno::RuntimeException );
80     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw ( ::com::sun::star::uno::RuntimeException );
81 
82 	// C++ helpers
83     virtual void SAL_CALL writeId( ::sal_Int32 Element );
84 
85 	static ::rtl::OUString escapeXml( const ::rtl::OUString& s );
86 
87 public:
88     /** From now on, don't write directly to the stream, but to top of a stack.
89 
90         This is to be able to change the order of the data being written.
91         If you need to write eg.
92           p, r, rPr, [something], /rPr, t, [text], /r, /p,
93         but get it in order
94           p, r, t, [text], /t, rPr, [something], /rPr, /r, /p,
95         simply do
96           p, r, mark(), t, [text], /t, mark(), rPr, [something], /rPr,
97           mergeTopMarks( true ), mergeTopMarks(), /r, /p
98         and you are done.
99      */
100     void mark();
101 
102     /** Merge 2 topmost marks.
103 
104         There are 3 possibilities - prepend the top before the second top-most
105         mark, append it, or append it later; prepending brings the possibility
106         to switch parts of the output, appending later allows to write some
107         output in advance.
108 
109         Writes the result to the output stream if the mark stack becomes empty
110         by the operation.
111 
112         When the MERGE_MARKS_POSTPONE is specified, the merge happens just
113         before the next merge.
114 
115         @see mark()
116      */
117     void mergeTopMarks( sax_fastparser::MergeMarksEnum eMergeType = sax_fastparser::MERGE_MARKS_APPEND );
118 
119 private:
120 	::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > mxOutputStream;
121 	::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxFastTokenHandler;
122 
123     typedef ::com::sun::star::uno::Sequence< ::sal_Int8 > Int8Sequence;
124     class ForMerge
125     {
126         Int8Sequence maData;
127         Int8Sequence maPostponed;
128 
129     public:
ForMerge()130         ForMerge() : maData(), maPostponed() {}
131 
132         Int8Sequence& getData();
133 
134         void prepend( const Int8Sequence &rWhat );
135         void append( const Int8Sequence &rWhat );
136         void postpone( const Int8Sequence &rWhat );
137 
138     private:
139         static void merge( Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend );
140     };
141 
142     ::std::stack< ForMerge > maMarkStack;
143 
144 	void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
145     void write( const ::rtl::OUString& s );
146 
147 protected:
148     /** Forward the call to the output stream, or write to the stack.
149 
150         The latter in the case that we are inside a mark().
151      */
152     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);
153 };
154 
155 } // namespace sax_fastparser
156 
157 #endif
158