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( ); 57 virtual void SAL_CALL endDocument( ); 58 virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); 59 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 ); 60 virtual void SAL_CALL endFastElement( ::sal_Int32 Element ); 61 virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ); 62 virtual void SAL_CALL singleFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); 63 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 ); 64 virtual void SAL_CALL characters( const ::rtl::OUString& aChars ); 65 virtual void SAL_CALL setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream ); 66 virtual void SAL_CALL setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler ); 67 68 // XServiceInfo 69 virtual ::rtl::OUString SAL_CALL getImplementationName( ); 70 virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ); 71 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ); 72 73 // C++ helpers 74 virtual void SAL_CALL writeId( ::sal_Int32 Element ); 75 76 static ::rtl::OUString escapeXml( const ::rtl::OUString& s ); 77 78 public: 79 /** From now on, don't write directly to the stream, but to top of a stack. 80 81 This is to be able to change the order of the data being written. 82 If you need to write eg. 83 p, r, rPr, [something], /rPr, t, [text], /r, /p, 84 but get it in order 85 p, r, t, [text], /t, rPr, [something], /rPr, /r, /p, 86 simply do 87 p, r, mark(), t, [text], /t, mark(), rPr, [something], /rPr, 88 mergeTopMarks( true ), mergeTopMarks(), /r, /p 89 and you are done. 90 */ 91 void mark(); 92 93 /** Merge 2 topmost marks. 94 95 There are 3 possibilities - prepend the top before the second top-most 96 mark, append it, or append it later; prepending brings the possibility 97 to switch parts of the output, appending later allows to write some 98 output in advance. 99 100 Writes the result to the output stream if the mark stack becomes empty 101 by the operation. 102 103 When the MERGE_MARKS_POSTPONE is specified, the merge happens just 104 before the next merge. 105 106 @see mark() 107 */ 108 void mergeTopMarks( sax_fastparser::MergeMarksEnum eMergeType = sax_fastparser::MERGE_MARKS_APPEND ); 109 110 private: 111 ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > mxOutputStream; 112 ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxFastTokenHandler; 113 114 typedef ::com::sun::star::uno::Sequence< ::sal_Int8 > Int8Sequence; 115 class ForMerge 116 { 117 Int8Sequence maData; 118 Int8Sequence maPostponed; 119 120 public: ForMerge()121 ForMerge() : maData(), maPostponed() {} 122 123 Int8Sequence& getData(); 124 125 void prepend( const Int8Sequence &rWhat ); 126 void append( const Int8Sequence &rWhat ); 127 void postpone( const Int8Sequence &rWhat ); 128 129 private: 130 static void merge( Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend ); 131 }; 132 133 ::std::stack< ForMerge > maMarkStack; 134 135 void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); 136 void write( const ::rtl::OUString& s ); 137 138 protected: 139 /** Forward the call to the output stream, or write to the stack. 140 141 The latter in the case that we are inside a mark(). 142 */ 143 void writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ); 144 }; 145 146 } // namespace sax_fastparser 147 148 #endif 149