diff options
author | Noel Power <noel.power@novell.com> | 2011-09-23 17:38:38 +0100 |
---|---|---|
committer | Noel Power <noel.power@novell.com> | 2011-09-26 12:06:05 +0100 |
commit | 590d9596c54443dc6b65a811569ec74371fa4794 (patch) | |
tree | fae735dd9e74fe10f92fb77e65896411142bcc0d | |
parent | 5609c512cd4d2899300b432d88d93cff05a05c87 (diff) |
move OCX_Control ( and subclasses ) and OCX control export to oox
add forgotten new files axbinarywriter.[ch]xx
-rw-r--r-- | oox/inc/oox/ole/axbinarywriter.hxx | 195 | ||||
-rw-r--r-- | oox/source/ole/axbinarywriter.cxx | 244 |
2 files changed, 439 insertions, 0 deletions
diff --git a/oox/inc/oox/ole/axbinarywriter.hxx b/oox/inc/oox/ole/axbinarywriter.hxx new file mode 100644 index 000000000000..408abaa1f5c7 --- /dev/null +++ b/oox/inc/oox/ole/axbinarywriter.hxx @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * [ Copyright (C) 2011 Noel Power<noel.power@suse.com> (initial developer) ] + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ +#ifndef OOX_OLE_AXBINARYWRITER_HXX +#define OOX_OLE_AXBINARYWRITER_HXX + +#include <utility> +#include "oox/helper/binaryoutputstream.hxx" +#include "oox/helper/refvector.hxx" + +namespace oox { +namespace ole { +// ============================================================================ + +/** A wrapper for a binary output stream that supports aligned write operations. + + The implementation does support seeking back the wrapped stream. All + seeking operations (tell, seekTo, align) are performed relative to the + position of the wrapped stream at construction time of this wrapper. + Unlike it's reader class counterpart it is NOT possible to construct this + wrapper with an unseekable output stream. + */ +class AxAlignedOutputStream : public BinaryOutputStream +{ +public: + explicit AxAlignedOutputStream( BinaryOutputStream& rOutStrm ); + + /** Returns the size of the data this stream represents, if the wrapped + stream supports the size() operation. */ + virtual sal_Int64 size() const; + /** Return the current relative stream position (relative to position of + the wrapped stream at construction time). */ + virtual sal_Int64 tell() const; + /** Seeks the stream to the passed relative position, if it is behind the + current position. */ + virtual void seek( sal_Int64 nPos ); + /** Closes the input stream but not the wrapped stream. */ + virtual void close(); + + /** Reads nBytes bytes to the passed sequence. + @return Number of bytes really read. */ + virtual void writeData( const StreamDataSequence& orData, size_t nAtomSize = 1 ); + /** Reads nBytes bytes to the (existing) buffer opMem. + @return Number of bytes really read. */ + virtual void writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 ); + + /** Aligns the stream to a multiple of the passed size (relative to the + position of the wrapped stream at construction time). */ + void align( size_t nSize ); + + void pad( sal_Int32 nBytes, size_t nAtomSize = 1); + /** Aligns the stream according to the passed type and reads an atomar value. */ + template< typename Type > + inline void writeAligned( Type nVal ) { align( sizeof( Type ) ); writeValue( nVal ); } + /** Aligns the stream according to the passed type and skips the size of the type. */ + template< typename Type > + inline void padAligned() { align( sizeof( Type ) ); pad( sizeof( Type ) ); } + +private: + BinaryOutputStream* mpOutStrm; /// The wrapped input stream. + sal_Int64 mnStrmPos; /// Tracks relative position in the stream. + sal_Int64 mnStrmSize; /// Size of the wrapped stream data. + sal_Int64 mnWrappedBeginPos; /// starting pos or wrapped stream +}; + +/** A pair of integer values as a property. */ +typedef ::std::pair< sal_Int32, sal_Int32 > AxPairData; + +/** An array of string values as a property. */ +typedef ::std::vector< ::rtl::OUString > AxStringArray; + +// ============================================================================ + +/** Export helper to write simple and complex ActiveX form control properties + to a binary input stream. */ +class AxBinaryPropertyWriter +{ +public: + explicit AxBinaryPropertyWriter( BinaryOutputStream& rOutStrm, bool b64BitPropFlags = false ); + + /** Write an integer property value to the stream, the + respective flag in the property mask is set. */ + template< typename StreamType, typename DataType > + inline void writeIntProperty( DataType& ornValue ) + { if( startNextProperty() ) maOutStrm.writeAligned< StreamType >( ornValue ); } + /** Write a boolean property value to the stream, the + respective flag in the property mask is set. */ + void writeBoolProperty( bool& orbValue, bool bReverse = false ); + /** Write a pair property the stream, the respective flag in + the property mask is set. */ + void writePairProperty( AxPairData& orPairData ); + /** Write a string property to the stream, the respective flag + in the property mask is set. */ + void writeStringProperty( ::rtl::OUString& orValue, bool bCompressed = true ); + + /** Skips the next property clears the respective + flag in the property mask. */ + inline void skipProperty() { startNextProperty( true ); } + + /** Final processing, write contents of all complex properties, writes record size */ + bool finalizeExport(); + +private: + bool ensureValid( bool bCondition = true ); + bool startNextProperty( bool bSkip = false ); + +private: + /** Base class for complex properties such as string, point, size, GUID, picture. */ + struct ComplexProperty + { + virtual ~ComplexProperty(); + virtual bool writeProperty( AxAlignedOutputStream& rOutStrm ) = 0; + }; + + /** Complex property for a 32-bit value pair, e.g. point or size. */ + struct PairProperty : public ComplexProperty + { + AxPairData& mrPairData; + + inline explicit PairProperty( AxPairData& rPairData ) : + mrPairData( rPairData ) {} + virtual bool writeProperty( AxAlignedOutputStream& rOutStrm ); + }; + + /** Complex property for a string value. */ + struct StringProperty : public ComplexProperty + { + ::rtl::OUString& mrValue; + sal_uInt32 mnSize; + + inline explicit StringProperty( ::rtl::OUString& rValue, sal_uInt32 nSize ) : + mrValue( rValue ), mnSize( nSize ) {} + virtual bool writeProperty( AxAlignedOutputStream& rOutStrm ); + }; + + /** Stream property for a picture or mouse icon. */ + struct PictureProperty : public ComplexProperty + { + StreamDataSequence& mrPicData; + + inline explicit PictureProperty( StreamDataSequence& rPicData ) : + mrPicData( rPicData ) {} + virtual bool writeProperty( AxAlignedOutputStream& rOutStrm ); + }; + + typedef RefVector< ComplexProperty > ComplexPropVector; + +private: + AxAlignedOutputStream maOutStrm; /// The input stream to read from. + ComplexPropVector maLargeProps; /// Stores info for all used large properties. + ComplexPropVector maStreamProps; /// Stores info for all used stream data properties. + AxPairData maDummyPairData; /// Dummy pair for unsupported properties. + StreamDataSequence maDummyPicData; /// Dummy picture for unsupported properties. + ::rtl::OUString maDummyString; /// Dummy string for unsupported properties. + AxStringArray maDummyStringArray; /// Dummy string array for unsupported properties. + sal_Int16 mnBlockSize; /// + sal_Int64 mnPropFlagsStart; /// pos of Prop flags + sal_Int64 mnPropFlags; /// Flags specifying existing properties. + sal_Int64 mnNextProp; /// Next property to read. + sal_Int64 mnPropsEnd; /// End position of simple/large properties. + bool mbValid; /// True = stream still valid. + bool mb64BitPropFlags; +}; + +// ============================================================================ +} // namespace ole +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/ole/axbinarywriter.cxx b/oox/source/ole/axbinarywriter.cxx new file mode 100644 index 000000000000..390b592d50d3 --- /dev/null +++ b/oox/source/ole/axbinarywriter.cxx @@ -0,0 +1,244 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * [ Copyright (C) 2011 Noel Power <noel.power@suse.com> (initial developer) ] + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ +#include "oox/ole/axbinarywriter.hxx" + +#include "oox/ole/olehelper.hxx" + +namespace oox { +namespace ole { + +// ============================================================================ + +using ::rtl::OUString; + +// ============================================================================ + +namespace { + +const sal_uInt32 AX_STRING_SIZEMASK = 0x7FFFFFFF; +const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000; + +} // namespace + +// ============================================================================ + +AxAlignedOutputStream::AxAlignedOutputStream( BinaryOutputStream& rOutStrm ) : + BinaryStreamBase( false ), + mpOutStrm( &rOutStrm ), + mnStrmPos( 0 ), + mnStrmSize( rOutStrm.getRemaining() ), + mnWrappedBeginPos( rOutStrm.tell() ) +{ + mbEof = mbEof || rOutStrm.isEof(); +} + +sal_Int64 AxAlignedOutputStream::size() const +{ + return mpOutStrm ? mnStrmSize : -1; +} + +sal_Int64 AxAlignedOutputStream::tell() const +{ + return mpOutStrm ? mnStrmPos : -1; +} + +void AxAlignedOutputStream::seek( sal_Int64 nPos ) +{ + mbEof = (nPos < 0); + if( !mbEof ) + { + mpOutStrm->seek( static_cast< sal_Int32 >( mnWrappedBeginPos + nPos ) ); + mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos; + } +} + +void AxAlignedOutputStream::close() +{ + mpOutStrm = 0; + mbEof = true; +} + +void AxAlignedOutputStream::writeData( const StreamDataSequence& orData, size_t nAtomSize ) +{ + mpOutStrm->writeData( orData, nAtomSize ); + mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos; +} + +void AxAlignedOutputStream::writeMemory( const void* opMem, sal_Int32 nBytes, size_t nAtomSize ) +{ + mpOutStrm->writeMemory( opMem, nBytes, nAtomSize ); + mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos; +} + +void AxAlignedOutputStream::pad( sal_Int32 nBytes, size_t nAtomSize ) +{ + //PRESUMABELY we need to pad with 0's here as appropriate + com::sun::star::uno::Sequence< sal_Int8 > aData( nBytes ); + // ok we could be padding with rubbish here, but really that shouldn't matter + // set to 0(s), easier to not get fooled by 0's when looking at + // binary content...... + memset( static_cast<void*>( aData.getArray() ), 0, nBytes ); + mpOutStrm->writeData( aData, nAtomSize ); + mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos; +} + +void AxAlignedOutputStream::align( size_t nSize ) +{ + pad( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) ); +} + +// ============================================================================ + +namespace { + +void lclWriteString( AxAlignedOutputStream& rOutStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString ) +{ + bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED ); + rOutStrm.writeCompressedUnicodeArray( rValue, bCompressed || bArrayString ); +} + +} // namespace + +// ---------------------------------------------------------------------------- + +AxBinaryPropertyWriter::ComplexProperty::~ComplexProperty() +{ +} + +bool AxBinaryPropertyWriter::PairProperty::writeProperty( AxAlignedOutputStream& rOutStrm ) +{ + rOutStrm << mrPairData.first << mrPairData.second; + return true; +} + +bool AxBinaryPropertyWriter::StringProperty::writeProperty( AxAlignedOutputStream& rOutStrm ) +{ + lclWriteString( rOutStrm, mrValue, mnSize, false ); + return true; +} + +// ---------------------------------------------------------------------------- + +AxBinaryPropertyWriter::AxBinaryPropertyWriter( BinaryOutputStream& rOutStrm, bool b64BitPropFlags ) : + maOutStrm( rOutStrm ), + mnPropFlags( 0x0 ), + mbValid( true ), + mb64BitPropFlags( b64BitPropFlags ) +{ + sal_uInt16 nId( 0x0200 ); + maOutStrm << nId; + mnBlockSize = 0; // will be filled in the finalize method + + maOutStrm << nId; + mnPropFlagsStart = maOutStrm.tell(); + + if( mb64BitPropFlags ) + maOutStrm << mnPropFlags; + else + maOutStrm << sal_uInt32( mnPropFlags ); + mnNextProp = 1; +} + +void AxBinaryPropertyWriter::writeBoolProperty( bool& orbValue, bool bReverse ) +{ + // orbValue ^ bReverse true then we want to set the bit, e.g. don't skip + startNextProperty( !( ( orbValue ^ bReverse ) >= 1 ) ); +} + +void AxBinaryPropertyWriter::writePairProperty( AxPairData& orPairData ) +{ + if( startNextProperty() ) + maLargeProps.push_back( ComplexPropVector::value_type( new PairProperty( orPairData ) ) ); +} + +void AxBinaryPropertyWriter::writeStringProperty( OUString& orValue, bool bCompressed ) +{ + sal_uInt32 nSize = orValue.getLength(); + if ( bCompressed ) + setFlag( nSize, AX_STRING_COMPRESSED ); + else + nSize *= 2; + maOutStrm.writeAligned< sal_uInt32 >( nSize ); + maLargeProps.push_back( ComplexPropVector::value_type( new StringProperty( orValue, nSize ) ) ); + startNextProperty(); +} + +bool AxBinaryPropertyWriter::finalizeExport() +{ + // write large properties + maOutStrm.align( 4 ); + if( !maLargeProps.empty() ) + { + for( ComplexPropVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt ) + { + (*aIt)->writeProperty( maOutStrm ); + maOutStrm.align( 4 ); + } + } + + mnBlockSize = maOutStrm.tell() - mnPropFlagsStart; + + // write stream properties (no stream alignment between properties!) + if( !maStreamProps.empty() ) + for( ComplexPropVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt ) + (*aIt)->writeProperty( maOutStrm ); + + sal_Int64 nPos = maOutStrm.tell(); + maOutStrm.seek( mnPropFlagsStart - sizeof( mnBlockSize ) ); + + maOutStrm << mnBlockSize; + + if( mb64BitPropFlags ) + maOutStrm << mnPropFlags; + else + maOutStrm << sal_uInt32( mnPropFlags ); + + maOutStrm.seek( nPos ); + return true; +} + +bool AxBinaryPropertyWriter::ensureValid( bool bCondition ) +{ + mbValid = mbValid && bCondition && !maOutStrm.isEof(); + return mbValid; +} + +bool AxBinaryPropertyWriter::startNextProperty( bool bSkip ) +{ + // if we are skipping then we clear the flag + setFlag( mnPropFlags, mnNextProp, !bSkip ); + mnNextProp <<= 1; + return true; +} + +// ============================================================================ + +} // namespace exp +} // namespace ole + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |