diff options
Diffstat (limited to 'sax/source/tools')
-rw-r--r-- | sax/source/tools/fastserializer.cxx | 87 | ||||
-rw-r--r-- | sax/source/tools/fastserializer.hxx | 34 | ||||
-rw-r--r-- | sax/source/tools/fshelper.cxx | 10 |
3 files changed, 90 insertions, 41 deletions
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx index 4603ceed3343..da4fdfb261db 100644 --- a/sax/source/tools/fastserializer.cxx +++ b/sax/source/tools/fastserializer.cxx @@ -326,43 +326,29 @@ namespace sax_fastparser { void FastSaxSerializer::mark() { - maMarkStack.push( Int8Sequence() ); + maMarkStack.push( ForMerge() ); } - void FastSaxSerializer::mergeTopMarks( bool bPrepend ) + void FastSaxSerializer::mergeTopMarks( sax_fastparser::MergeMarksEnum eMergeType ) { if ( maMarkStack.empty() ) return; if ( maMarkStack.size() == 1 ) { - mxOutputStream->writeBytes( maMarkStack.top() ); + mxOutputStream->writeBytes( maMarkStack.top().getData() ); maMarkStack.pop(); + return; } - else - { - const Int8Sequence aMerge( maMarkStack.top() ); - maMarkStack.pop(); - sal_Int32 nMergeLen = aMerge.getLength(); - if ( nMergeLen > 0 ) - { - Int8Sequence &rTop = maMarkStack.top(); - sal_Int32 nTopLen = rTop.getLength(); - - rTop.realloc( nTopLen + nMergeLen ); - if ( bPrepend ) - { - // prepend the aMerge to the rTop - memmove( rTop.getArray() + nMergeLen, rTop.getConstArray(), nTopLen ); - memcpy( rTop.getArray(), aMerge.getConstArray(), nMergeLen ); - } - else - { - // append the aMerge to the rTop - memcpy( rTop.getArray() + nTopLen, aMerge.getConstArray(), nMergeLen ); - } - } + const Int8Sequence aMerge( maMarkStack.top().getData() ); + maMarkStack.pop(); + + switch ( eMergeType ) + { + case MERGE_MARKS_APPEND: maMarkStack.top().append( aMerge ); break; + case MERGE_MARKS_PREPEND: maMarkStack.top().prepend( aMerge ); break; + case MERGE_MARKS_POSTPONE: maMarkStack.top().postpone( aMerge ); break; } } @@ -371,15 +357,50 @@ namespace sax_fastparser { if ( maMarkStack.empty() ) mxOutputStream->writeBytes( aData ); else + maMarkStack.top().append( aData ); + } + + FastSaxSerializer::Int8Sequence& FastSaxSerializer::ForMerge::getData() + { + merge( maData, maPostponed, true ); + maPostponed.realloc( 0 ); + + return maData; + } + + void FastSaxSerializer::ForMerge::prepend( const Int8Sequence &rWhat ) + { + merge( maData, rWhat, false ); + } + + void FastSaxSerializer::ForMerge::append( const Int8Sequence &rWhat ) + { + merge( maData, rWhat, true ); + } + + void FastSaxSerializer::ForMerge::postpone( const Int8Sequence &rWhat ) + { + merge( maPostponed, rWhat, true ); + } + + void FastSaxSerializer::ForMerge::merge( Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend ) + { + sal_Int32 nMergeLen = rMerge.getLength(); + if ( nMergeLen > 0 ) { - sal_Int32 nDataLen = aData.getLength(); - if ( nDataLen > 0 ) - { - Int8Sequence &rTop = maMarkStack.top(); - sal_Int32 nTopLen = rTop.getLength(); + sal_Int32 nTopLen = rTop.getLength(); - rTop.realloc( nTopLen + nDataLen ); - memcpy( rTop.getArray() + nTopLen, aData.getConstArray(), nDataLen ); + rTop.realloc( nTopLen + nMergeLen ); + if ( bAppend ) + { + // append the rMerge to the rTop + memcpy( rTop.getArray() + nTopLen, rMerge.getConstArray(), nMergeLen ); + } + else + { + // prepend the rMerge to the rTop + memmove( rTop.getArray() + nMergeLen, rTop.getConstArray(), nTopLen ); + memcpy( rTop.getArray(), rMerge.getConstArray(), nMergeLen ); } } } diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx index 132b495c0a8b..b0baf8af5df8 100644 --- a/sax/source/tools/fastserializer.hxx +++ b/sax/source/tools/fastserializer.hxx @@ -45,6 +45,7 @@ #include <stack> #include "sax/dllapi.h" +#include "sax/fshelper.hxx" #define SERIALIZER_IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.FastSerializer" #define SERIALIZER_SERVICE_NAME "com.sun.star.xml.sax.FastSerializer" @@ -112,23 +113,45 @@ public: /** Merge 2 topmost marks. - There are 2 possibilities - prepend the top before the second top-most - mark, or append it; prepending brings the possibility to switch parts - of the output. + There are 3 possibilities - prepend the top before the second top-most + mark, append it, or append it later; prepending brings the possibility + to switch parts of the output, appending later allows to write some + output in advance. Writes the result to the output stream if the mark stack becomes empty by the operation. + When the MERGE_MARKS_POSTPONE is specified, the merge happens just + before the next merge. + @see mark() */ - void mergeTopMarks( bool bPrepend = false ); + void mergeTopMarks( sax_fastparser::MergeMarksEnum eMergeType = sax_fastparser::MERGE_MARKS_APPEND ); private: ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > mxOutputStream; ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxFastTokenHandler; typedef ::com::sun::star::uno::Sequence< ::sal_Int8 > Int8Sequence; - ::std::stack< Int8Sequence > maMarkStack; + class ForMerge + { + Int8Sequence maData; + Int8Sequence maPostponed; + + public: + ForMerge() : maData(), maPostponed() {} + + Int8Sequence& getData(); + + void prepend( const Int8Sequence &rWhat ); + void append( const Int8Sequence &rWhat ); + void postpone( const Int8Sequence &rWhat ); + + private: + static void merge( Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend ); + }; + + ::std::stack< ForMerge > maMarkStack; void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); void write( const ::rtl::OUString& s ); @@ -144,4 +167,3 @@ protected: } // namespace sax_fastparser #endif - diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx index 594a60ba1d76..743f499fb4f0 100644 --- a/sax/source/tools/fshelper.cxx +++ b/sax/source/tools/fshelper.cxx @@ -114,6 +114,12 @@ void FastSerializerHelper::endElement(sal_Int32 elementTokenId) mpSerializer->endFastElement(elementTokenId); } +void FastSerializerHelper::startElementV(sal_Int32 elementTokenId, XFastAttributeListRef xAttrList) +{ + mpSerializer->startFastElement(elementTokenId, xAttrList); +} + + void FastSerializerHelper::singleElement(const char* elementName, XFastAttributeListRef xAttrList) { mpSerializer->singleUnknownElement(::rtl::OUString(), ::rtl::OUString::createFromAscii(elementName), xAttrList); @@ -181,9 +187,9 @@ void FastSerializerHelper::mark() mpSerializer->mark(); } -void FastSerializerHelper::mergeTopMarks( bool bPrepend ) +void FastSerializerHelper::mergeTopMarks( MergeMarksEnum eMergeType ) { - mpSerializer->mergeTopMarks( bPrepend ); + mpSerializer->mergeTopMarks( eMergeType ); } FastAttributeList * FastSerializerHelper::createAttrList() |