1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
9 #include <oox/ole/axbinarywriter.hxx>
15 const sal_uInt32 AX_STRING_COMPRESSED
= 0x80000000;
19 AxAlignedOutputStream::AxAlignedOutputStream( BinaryOutputStream
& rOutStrm
) :
20 BinaryStreamBase( false ),
21 mpOutStrm( &rOutStrm
),
23 mnStrmSize( rOutStrm
.getRemaining() ),
24 mnWrappedBeginPos( rOutStrm
.tell() )
26 mbEof
= mbEof
|| rOutStrm
.isEof();
29 sal_Int64
AxAlignedOutputStream::size() const
31 return mpOutStrm
? mnStrmSize
: -1;
34 sal_Int64
AxAlignedOutputStream::tell() const
36 return mpOutStrm
? mnStrmPos
: -1;
39 void AxAlignedOutputStream::seek( sal_Int64 nPos
)
44 mpOutStrm
->seek( static_cast< sal_Int32
>( mnWrappedBeginPos
+ nPos
) );
45 mnStrmPos
= mpOutStrm
->tell() - mnWrappedBeginPos
;
49 void AxAlignedOutputStream::close()
55 void AxAlignedOutputStream::writeData( const StreamDataSequence
& orData
, size_t nAtomSize
)
57 mpOutStrm
->writeData( orData
, nAtomSize
);
58 mnStrmPos
= mpOutStrm
->tell() - mnWrappedBeginPos
;
61 void AxAlignedOutputStream::writeMemory( const void* opMem
, sal_Int32 nBytes
, size_t nAtomSize
)
63 mpOutStrm
->writeMemory( opMem
, nBytes
, nAtomSize
);
64 mnStrmPos
= mpOutStrm
->tell() - mnWrappedBeginPos
;
67 void AxAlignedOutputStream::pad( sal_Int32 nBytes
)
69 //PRESUMABLY we need to pad with 0's here as appropriate
70 css::uno::Sequence
< sal_Int8
> aData( nBytes
);
71 // ok we could be padding with rubbish here, but really that shouldn't matter
72 // set to 0(s), easier to not get fooled by 0's when looking at
74 memset( static_cast<void*>( aData
.getArray() ), 0, nBytes
);
75 mpOutStrm
->writeData( aData
);
76 mnStrmPos
= mpOutStrm
->tell() - mnWrappedBeginPos
;
79 void AxAlignedOutputStream::align( size_t nSize
)
81 pad( static_cast< sal_Int32
>( (nSize
- (mnStrmPos
% nSize
)) % nSize
) );
86 void lclWriteString( AxAlignedOutputStream
& rOutStrm
, OUString
const & rValue
, sal_uInt32 nSize
)
88 bool bCompressed
= getFlag( nSize
, AX_STRING_COMPRESSED
);
89 rOutStrm
.writeCompressedUnicodeArray( rValue
, bCompressed
);
94 AxBinaryPropertyWriter::ComplexProperty::~ComplexProperty()
98 bool AxBinaryPropertyWriter::PairProperty::writeProperty( AxAlignedOutputStream
& rOutStrm
)
100 rOutStrm
.WriteInt32(mrPairData
.first
).WriteInt32(mrPairData
.second
);
104 bool AxBinaryPropertyWriter::StringProperty::writeProperty( AxAlignedOutputStream
& rOutStrm
)
106 lclWriteString( rOutStrm
, mrValue
, mnSize
);
110 AxBinaryPropertyWriter::AxBinaryPropertyWriter( BinaryOutputStream
& rOutStrm
, bool b64BitPropFlags
) :
111 maOutStrm( rOutStrm
),
114 mb64BitPropFlags( b64BitPropFlags
)
116 sal_uInt16
nId( 0x0200 );
117 maOutStrm
.WriteUInt16(nId
);
118 mnBlockSize
= 0; // will be filled in the finalize method
120 maOutStrm
.WriteUInt16(nId
);
121 mnPropFlagsStart
= maOutStrm
.tell();
123 if( mb64BitPropFlags
)
124 maOutStrm
.WriteInt64( mnPropFlags
);
126 maOutStrm
.WriteUInt32( mnPropFlags
);
130 void AxBinaryPropertyWriter::writeBoolProperty( bool orbValue
)
132 // orbValue == bReverse false then we want to set the bit, e.g. don't skip
133 startNextProperty( !orbValue
);
136 void AxBinaryPropertyWriter::writePairProperty( AxPairData
& orPairData
)
139 maLargeProps
.push_back( ComplexPropVector::value_type( std::make_shared
<PairProperty
>( orPairData
) ) );
142 void AxBinaryPropertyWriter::writeStringProperty( OUString
& orValue
)
144 sal_uInt32 nSize
= orValue
.getLength() * 2;
145 setFlag( nSize
, AX_STRING_COMPRESSED
, false );
146 maOutStrm
.writeAligned
< sal_uInt32
>( nSize
);
147 maLargeProps
.push_back( ComplexPropVector::value_type( std::make_shared
<StringProperty
>( orValue
, nSize
) ) );
151 void AxBinaryPropertyWriter::finalizeExport()
153 // write large properties
154 maOutStrm
.align( 4 );
155 for (auto const& largeProp
: maLargeProps
)
159 largeProp
->writeProperty( maOutStrm
);
160 maOutStrm
.align( 4 );
163 mnBlockSize
= maOutStrm
.tell() - mnPropFlagsStart
;
165 // write stream properties (no stream alignment between properties!)
166 for (auto const& streamProp
: maStreamProps
)
170 streamProp
->writeProperty( maOutStrm
);
173 sal_Int64 nPos
= maOutStrm
.tell();
174 maOutStrm
.seek( mnPropFlagsStart
- sizeof( mnBlockSize
) );
176 maOutStrm
.WriteInt16( mnBlockSize
);
178 if( mb64BitPropFlags
)
179 maOutStrm
.WriteInt64( mnPropFlags
);
181 maOutStrm
.WriteUInt32( mnPropFlags
);
183 maOutStrm
.seek( nPos
);
186 bool AxBinaryPropertyWriter::ensureValid()
188 mbValid
= mbValid
&& !maOutStrm
.isEof();
192 void AxBinaryPropertyWriter::startNextProperty( bool bSkip
)
194 // if we are skipping then we clear the flag
195 setFlag( mnPropFlags
, mnNextProp
, !bSkip
);
199 } // namespace oox::ole
201 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */