bump product version to 4.1.6.2
[LibreOffice.git] / oox / source / ole / axbinarywriter.cxx
blob637ab24b77d08fc89b21314e511e6265629a7ffd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9 #include "oox/ole/axbinarywriter.hxx"
11 #include "oox/ole/olehelper.hxx"
13 namespace oox {
14 namespace ole {
16 // ============================================================================
18 namespace {
20 const sal_uInt32 AX_STRING_SIZEMASK = 0x7FFFFFFF;
21 const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000;
23 } // namespace
25 // ============================================================================
27 AxAlignedOutputStream::AxAlignedOutputStream( BinaryOutputStream& rOutStrm ) :
28 BinaryStreamBase( false ),
29 mpOutStrm( &rOutStrm ),
30 mnStrmPos( 0 ),
31 mnStrmSize( rOutStrm.getRemaining() ),
32 mnWrappedBeginPos( rOutStrm.tell() )
34 mbEof = mbEof || rOutStrm.isEof();
37 sal_Int64 AxAlignedOutputStream::size() const
39 return mpOutStrm ? mnStrmSize : -1;
42 sal_Int64 AxAlignedOutputStream::tell() const
44 return mpOutStrm ? mnStrmPos : -1;
47 void AxAlignedOutputStream::seek( sal_Int64 nPos )
49 mbEof = (nPos < 0);
50 if( !mbEof )
52 mpOutStrm->seek( static_cast< sal_Int32 >( mnWrappedBeginPos + nPos ) );
53 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
57 void AxAlignedOutputStream::close()
59 mpOutStrm = 0;
60 mbEof = true;
63 void AxAlignedOutputStream::writeData( const StreamDataSequence& orData, size_t nAtomSize )
65 mpOutStrm->writeData( orData, nAtomSize );
66 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
69 void AxAlignedOutputStream::writeMemory( const void* opMem, sal_Int32 nBytes, size_t nAtomSize )
71 mpOutStrm->writeMemory( opMem, nBytes, nAtomSize );
72 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
75 void AxAlignedOutputStream::pad( sal_Int32 nBytes, size_t nAtomSize )
77 //PRESUMABELY we need to pad with 0's here as appropriate
78 com::sun::star::uno::Sequence< sal_Int8 > aData( nBytes );
79 // ok we could be padding with rubbish here, but really that shouldn't matter
80 // set to 0(s), easier to not get fooled by 0's when looking at
81 // binary content......
82 memset( static_cast<void*>( aData.getArray() ), 0, nBytes );
83 mpOutStrm->writeData( aData, nAtomSize );
84 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
87 void AxAlignedOutputStream::align( size_t nSize )
89 pad( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) );
92 // ============================================================================
94 namespace {
96 void lclWriteString( AxAlignedOutputStream& rOutStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString )
98 bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
99 rOutStrm.writeCompressedUnicodeArray( rValue, bCompressed || bArrayString );
102 } // namespace
104 // ----------------------------------------------------------------------------
106 AxBinaryPropertyWriter::ComplexProperty::~ComplexProperty()
110 bool AxBinaryPropertyWriter::PairProperty::writeProperty( AxAlignedOutputStream& rOutStrm )
112 rOutStrm << mrPairData.first << mrPairData.second;
113 return true;
116 bool AxBinaryPropertyWriter::StringProperty::writeProperty( AxAlignedOutputStream& rOutStrm )
118 lclWriteString( rOutStrm, mrValue, mnSize, false );
119 return true;
122 // ----------------------------------------------------------------------------
124 AxBinaryPropertyWriter::AxBinaryPropertyWriter( BinaryOutputStream& rOutStrm, bool b64BitPropFlags ) :
125 maOutStrm( rOutStrm ),
126 mnPropFlags( 0x0 ),
127 mbValid( true ),
128 mb64BitPropFlags( b64BitPropFlags )
130 sal_uInt16 nId( 0x0200 );
131 maOutStrm << nId;
132 mnBlockSize = 0; // will be filled in the finalize method
134 maOutStrm << nId;
135 mnPropFlagsStart = maOutStrm.tell();
137 if( mb64BitPropFlags )
138 maOutStrm << mnPropFlags;
139 else
140 maOutStrm << sal_uInt32( mnPropFlags );
141 mnNextProp = 1;
144 void AxBinaryPropertyWriter::writeBoolProperty( bool orbValue, bool bReverse )
146 // orbValue ^ bReverse true then we want to set the bit, e.g. don't skip
147 startNextProperty( !( ( orbValue ^ bReverse ) >= 1 ) );
150 void AxBinaryPropertyWriter::writePairProperty( AxPairData& orPairData )
152 if( startNextProperty() )
153 maLargeProps.push_back( ComplexPropVector::value_type( new PairProperty( orPairData ) ) );
156 void AxBinaryPropertyWriter::writeStringProperty( OUString& orValue, bool bCompressed )
158 sal_uInt32 nSize = orValue.getLength();
159 if ( bCompressed )
160 setFlag( nSize, AX_STRING_COMPRESSED );
161 else
162 nSize *= 2;
163 maOutStrm.writeAligned< sal_uInt32 >( nSize );
164 maLargeProps.push_back( ComplexPropVector::value_type( new StringProperty( orValue, nSize ) ) );
165 startNextProperty();
168 bool AxBinaryPropertyWriter::finalizeExport()
170 // write large properties
171 maOutStrm.align( 4 );
172 if( !maLargeProps.empty() )
174 for( ComplexPropVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
176 (*aIt)->writeProperty( maOutStrm );
177 maOutStrm.align( 4 );
181 mnBlockSize = maOutStrm.tell() - mnPropFlagsStart;
183 // write stream properties (no stream alignment between properties!)
184 if( !maStreamProps.empty() )
185 for( ComplexPropVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
186 (*aIt)->writeProperty( maOutStrm );
188 sal_Int64 nPos = maOutStrm.tell();
189 maOutStrm.seek( mnPropFlagsStart - sizeof( mnBlockSize ) );
191 maOutStrm << mnBlockSize;
193 if( mb64BitPropFlags )
194 maOutStrm << mnPropFlags;
195 else
196 maOutStrm << sal_uInt32( mnPropFlags );
198 maOutStrm.seek( nPos );
199 return true;
202 bool AxBinaryPropertyWriter::ensureValid( bool bCondition )
204 mbValid = mbValid && bCondition && !maOutStrm.isEof();
205 return mbValid;
208 bool AxBinaryPropertyWriter::startNextProperty( bool bSkip )
210 // if we are skipping then we clear the flag
211 setFlag( mnPropFlags, mnNextProp, !bSkip );
212 mnNextProp <<= 1;
213 return true;
216 // ============================================================================
218 } // namespace exp
219 } // namespace ole
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */