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