bump product version to 5.0.4.1
[LibreOffice.git] / oox / source / ole / axbinarywriter.cxx
blob71c01d6dcc8b5614fc8cf571d69dae3175288357
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 namespace {
18 const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000;
20 } // namespace
22 AxAlignedOutputStream::AxAlignedOutputStream( BinaryOutputStream& rOutStrm ) :
23 BinaryStreamBase( false ),
24 mpOutStrm( &rOutStrm ),
25 mnStrmPos( 0 ),
26 mnStrmSize( rOutStrm.getRemaining() ),
27 mnWrappedBeginPos( rOutStrm.tell() )
29 mbEof = mbEof || rOutStrm.isEof();
32 sal_Int64 AxAlignedOutputStream::size() const
34 return mpOutStrm ? mnStrmSize : -1;
37 sal_Int64 AxAlignedOutputStream::tell() const
39 return mpOutStrm ? mnStrmPos : -1;
42 void AxAlignedOutputStream::seek( sal_Int64 nPos )
44 mbEof = (nPos < 0);
45 if( !mbEof )
47 mpOutStrm->seek( static_cast< sal_Int32 >( mnWrappedBeginPos + nPos ) );
48 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
52 void AxAlignedOutputStream::close()
54 mpOutStrm = 0;
55 mbEof = true;
58 void AxAlignedOutputStream::writeData( const StreamDataSequence& orData, size_t nAtomSize )
60 mpOutStrm->writeData( orData, nAtomSize );
61 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
64 void AxAlignedOutputStream::writeMemory( const void* opMem, sal_Int32 nBytes, size_t nAtomSize )
66 mpOutStrm->writeMemory( opMem, nBytes, nAtomSize );
67 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
70 void AxAlignedOutputStream::pad( sal_Int32 nBytes, size_t nAtomSize )
72 //PRESUMABLY we need to pad with 0's here as appropriate
73 com::sun::star::uno::Sequence< sal_Int8 > aData( nBytes );
74 // ok we could be padding with rubbish here, but really that shouldn't matter
75 // set to 0(s), easier to not get fooled by 0's when looking at
76 // binary content......
77 memset( static_cast<void*>( aData.getArray() ), 0, nBytes );
78 mpOutStrm->writeData( aData, nAtomSize );
79 mnStrmPos = mpOutStrm->tell() - mnWrappedBeginPos;
82 void AxAlignedOutputStream::align( size_t nSize )
84 pad( static_cast< sal_Int32 >( (nSize - (mnStrmPos % nSize)) % nSize ) );
87 namespace {
89 void lclWriteString( AxAlignedOutputStream& rOutStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString )
91 bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
92 rOutStrm.writeCompressedUnicodeArray( rValue, bCompressed || bArrayString );
95 } // namespace
97 AxBinaryPropertyWriter::ComplexProperty::~ComplexProperty()
101 bool AxBinaryPropertyWriter::PairProperty::writeProperty( AxAlignedOutputStream& rOutStrm )
103 rOutStrm.WriteInt32(mrPairData.first).WriteInt32(mrPairData.second);
104 return true;
107 bool AxBinaryPropertyWriter::StringProperty::writeProperty( AxAlignedOutputStream& rOutStrm )
109 lclWriteString( rOutStrm, mrValue, mnSize, false );
110 return true;
113 AxBinaryPropertyWriter::AxBinaryPropertyWriter( BinaryOutputStream& rOutStrm, bool b64BitPropFlags ) :
114 maOutStrm( rOutStrm ),
115 mnPropFlags( 0x0 ),
116 mbValid( true ),
117 mb64BitPropFlags( b64BitPropFlags )
119 sal_uInt16 nId( 0x0200 );
120 maOutStrm.WriteUInt16(nId);
121 mnBlockSize = 0; // will be filled in the finalize method
123 maOutStrm.WriteUInt16(nId);
124 mnPropFlagsStart = maOutStrm.tell();
126 if( mb64BitPropFlags )
127 maOutStrm.WriteInt64( mnPropFlags );
128 else
129 maOutStrm.WriteUInt32( mnPropFlags );
130 mnNextProp = 1;
133 void AxBinaryPropertyWriter::writeBoolProperty( bool orbValue, bool bReverse )
135 // orbValue == bReverse false then we want to set the bit, e.g. don't skip
136 startNextProperty( orbValue == bReverse );
139 void AxBinaryPropertyWriter::writePairProperty( AxPairData& orPairData )
141 if( startNextProperty() )
142 maLargeProps.push_back( ComplexPropVector::value_type( new PairProperty( orPairData ) ) );
145 void AxBinaryPropertyWriter::writeStringProperty( OUString& orValue, bool bCompressed )
147 sal_uInt32 nSize = orValue.getLength();
148 if ( bCompressed )
149 setFlag( nSize, AX_STRING_COMPRESSED );
150 else
151 nSize *= 2;
152 maOutStrm.writeAligned< sal_uInt32 >( nSize );
153 maLargeProps.push_back( ComplexPropVector::value_type( new StringProperty( orValue, nSize ) ) );
154 startNextProperty();
157 bool AxBinaryPropertyWriter::finalizeExport()
159 // write large properties
160 maOutStrm.align( 4 );
161 if( !maLargeProps.empty() )
163 for( ComplexPropVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
165 (*aIt)->writeProperty( maOutStrm );
166 maOutStrm.align( 4 );
170 mnBlockSize = maOutStrm.tell() - mnPropFlagsStart;
172 // write stream properties (no stream alignment between properties!)
173 if( !maStreamProps.empty() )
174 for( ComplexPropVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
175 (*aIt)->writeProperty( maOutStrm );
177 sal_Int64 nPos = maOutStrm.tell();
178 maOutStrm.seek( mnPropFlagsStart - sizeof( mnBlockSize ) );
180 maOutStrm.WriteInt16( mnBlockSize );
182 if( mb64BitPropFlags )
183 maOutStrm.WriteInt64( mnPropFlags );
184 else
185 maOutStrm.WriteUInt32( mnPropFlags );
187 maOutStrm.seek( nPos );
188 return true;
191 bool AxBinaryPropertyWriter::ensureValid( bool bCondition )
193 mbValid = mbValid && bCondition && !maOutStrm.isEof();
194 return mbValid;
197 bool AxBinaryPropertyWriter::startNextProperty( bool bSkip )
199 // if we are skipping then we clear the flag
200 setFlag( mnPropFlags, mnNextProp, !bSkip );
201 mnNextProp <<= 1;
202 return true;
205 } // namespace exp
206 } // namespace ole
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */