From 6b7af2b91761f48301e6efbe5569944d46f1a611 Mon Sep 17 00:00:00 2001 From: Cédric Bosdonnat Date: Sat, 6 Nov 2010 15:20:20 +0100 Subject: DOCX export: order pPr children according to specs This is still a first attempt: the base is present and all the exported properties needs to be checked. rPr properties order needs to be checked as well. --- sax/source/tools/fastserializer.cxx | 98 ++++++++++++++++++++++++++++++++----- sax/source/tools/fastserializer.hxx | 51 ++++++++++++++++--- sax/source/tools/fshelper.cxx | 4 +- 3 files changed, 131 insertions(+), 22 deletions(-) (limited to 'sax/source') diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx index b475f6d2342c..7e8394039831 100644 --- a/sax/source/tools/fastserializer.cxx +++ b/sax/source/tools/fastserializer.cxx @@ -135,6 +135,9 @@ namespace sax_fastparser { if (!mxOutputStream.is()) return; + if ( !maMarkStack.empty() ) + maMarkStack.top()->setCurrentElement( Element ); + writeBytes(toUnoSequence(aOpeningBracket)); writeId(Element); @@ -202,6 +205,9 @@ namespace sax_fastparser { if (!mxOutputStream.is()) return; + if ( !maMarkStack.empty() ) + maMarkStack.top()->setCurrentElement( Element ); + writeBytes(toUnoSequence(aOpeningBracket)); writeId(Element); @@ -323,24 +329,31 @@ namespace sax_fastparser { return aRet; } - void FastSaxSerializer::mark() + void FastSaxSerializer::mark( Int32Sequence aOrder ) { - maMarkStack.push( ForMerge() ); + if ( aOrder.hasElements() ) + { + boost::shared_ptr< ForMerge > pSort( new ForSort( aOrder ) ); + maMarkStack.push( pSort ); + } + else + { + boost::shared_ptr< ForMerge > pMerge( new ForMerge( ) ); + maMarkStack.push( pMerge ); + } } #if DEBUG void FastSaxSerializer::printMarkStack( ) { - ::std::stack< ForMerge > aCopy( maMarkStack ); + ::std::stack< boost::shared_ptr< ForMerge > > aCopy( maMarkStack ); int nSize = aCopy.size(); int i = 0; while ( !aCopy.empty() ) { fprintf( stderr, "%d\n", nSize - i ); - ForMerge aMarks = aCopy.top( ); - aMarks.print(); - + aCopy.top( )->print( ); fprintf( stderr, "\n" ); @@ -357,19 +370,19 @@ namespace sax_fastparser { if ( maMarkStack.size() == 1 ) { - mxOutputStream->writeBytes( maMarkStack.top().getData() ); + mxOutputStream->writeBytes( maMarkStack.top()->getData() ); maMarkStack.pop(); return; } - const Int8Sequence aMerge( maMarkStack.top().getData() ); + 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; + 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; } } @@ -378,7 +391,7 @@ namespace sax_fastparser { if ( maMarkStack.empty() ) mxOutputStream->writeBytes( aData ); else - maMarkStack.top().append( aData ); + maMarkStack.top()->append( aData ); } FastSaxSerializer::Int8Sequence& FastSaxSerializer::ForMerge::getData() @@ -445,6 +458,67 @@ namespace sax_fastparser { } } + void FastSaxSerializer::ForMerge::resetData( ) + { + maData = Int8Sequence(); + } + + void FastSaxSerializer::ForSort::setCurrentElement( sal_Int32 nElement ) + { + mnCurrentElement = nElement; + if ( maData.find( nElement ) == maData.end() ) + maData[ nElement ] = Int8Sequence(); + } + + void FastSaxSerializer::ForSort::prepend( const Int8Sequence &rWhat ) + { + append( rWhat ); + } + + void FastSaxSerializer::ForSort::append( const Int8Sequence &rWhat ) + { + merge( maData[mnCurrentElement], rWhat, true ); + } + + void FastSaxSerializer::ForSort::sort() + { + // Clear the ForMerge data to avoid duplicate items + resetData(); + + // Sort it all + std::map< sal_Int32, Int8Sequence >::iterator iter; + for ( sal_Int32 i=0, len=maOrder.getLength(); i < len; i++ ) + { + iter = maData.find( maOrder[i] ); + if ( iter != maData.end() ) + ForMerge::append( iter->second ); + } + } + + FastSaxSerializer::Int8Sequence& FastSaxSerializer::ForSort::getData() + { + sort( ); + return ForMerge::getData(); + } + +#if DEBUG + void FastSaxSerializer::ForSort::print( ) + { + std::map< sal_Int32, Int8Sequence >::iterator iter = maData.begin(); + while ( iter != maData.end( ) ) + { + fprintf( stderr, "pair: %d, ", iter->first ); + for ( sal_Int32 i=0, len=iter->second.getLength(); i < len; i++ ) + fprintf( stderr, "%c", iter->second[i] ); + fprintf( stderr, "\n" ); + iter++; + } + + sort( ); + ForMerge::print(); + } +#endif + } // namespace sax_fastparser /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx index cb57be1f61fb..493ef5cb3c92 100644 --- a/sax/source/tools/fastserializer.hxx +++ b/sax/source/tools/fastserializer.hxx @@ -36,6 +36,9 @@ #include #include +#include + +#include #include "sax/dllapi.h" #include "sax/fshelper.hxx" @@ -47,6 +50,9 @@ namespace sax_fastparser { class SAX_DLLPUBLIC FastSaxSerializer : public ::cppu::WeakImplHelper2< ::com::sun::star::xml::sax::XFastSerializer, ::com::sun::star::lang::XServiceInfo > { + typedef ::com::sun::star::uno::Sequence< ::sal_Int8 > Int8Sequence; + typedef ::com::sun::star::uno::Sequence< ::sal_Int32 > Int32Sequence; + public: explicit FastSaxSerializer( ); virtual ~FastSaxSerializer(); @@ -102,7 +108,7 @@ public: mergeTopMarks( true ), mergeTopMarks(), /r, /p and you are done. */ - void mark(); + void mark( Int32Sequence aOrder = Int32Sequence() ); /** Merge 2 topmost marks. @@ -125,7 +131,6 @@ 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; class ForMerge { Int8Sequence maData; @@ -134,24 +139,54 @@ private: public: ForMerge() : maData(), maPostponed() {} - Int8Sequence& getData(); + virtual void setCurrentElement( ::sal_Int32 /*nToken*/ ) {} + virtual Int8Sequence& getData(); #if DEBUG - void print(); + virtual void print(); #endif - void prepend( const Int8Sequence &rWhat ); - void append( const Int8Sequence &rWhat ); + virtual void prepend( const Int8Sequence &rWhat ); + virtual void append( const Int8Sequence &rWhat ); void postpone( const Int8Sequence &rWhat ); - private: + protected: + void resetData( ); static void merge( Int8Sequence &rTop, const Int8Sequence &rMerge, bool bAppend ); }; + class ForSort : public ForMerge + { + std::map< ::sal_Int32, Int8Sequence > maData; + sal_Int32 mnCurrentElement; + + Int32Sequence maOrder; + + public: + ForSort( Int32Sequence aOrder ) : + ForMerge(), + maData(), + mnCurrentElement( 0 ), + maOrder( aOrder ) {} + + void setCurrentElement( ::sal_Int32 nToken ); + + virtual Int8Sequence& getData(); + +#if DEBUG + virtual void print(); +#endif + + virtual void prepend( const Int8Sequence &rWhat ); + virtual void append( const Int8Sequence &rWhat ); + private: + void sort(); + }; + #if DEBUG void printMarkStack( ); #endif - ::std::stack< ForMerge > maMarkStack; + ::std::stack< boost::shared_ptr< ForMerge > > maMarkStack; void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); void write( const ::rtl::OUString& s ); diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx index 16b3acb3e021..3096dc6a3ee2 100644 --- a/sax/source/tools/fshelper.cxx +++ b/sax/source/tools/fshelper.cxx @@ -183,9 +183,9 @@ FastSerializerHelper* FastSerializerHelper::writeId(sal_Int32 tokenId) return mpSerializer->getOutputStream(); } -void FastSerializerHelper::mark() +void FastSerializerHelper::mark( Sequence< sal_Int32 > aOrder ) { - mpSerializer->mark(); + mpSerializer->mark( aOrder ); } void FastSerializerHelper::mergeTopMarks( MergeMarksEnum eMergeType ) -- cgit