LibreOffice Module oox (master) 1
binaryoutputstream.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21
22#include <com/sun/star/io/XOutputStream.hpp>
23#include <com/sun/star/io/XSeekable.hpp>
24#include <osl/diagnose.h>
25#include <string.h>
26
27namespace oox {
28
29using namespace ::com::sun::star::io;
30using namespace ::com::sun::star::uno;
31
32namespace {
33
34const sal_Int32 OUTPUTSTREAM_BUFFERSIZE = 0x8000;
35
36} // namespace
37
38BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOutStrm, bool bAutoClose ) :
39 BinaryStreamBase( Reference< XSeekable >( rxOutStrm, UNO_QUERY ).is() ),
40 BinaryXSeekableStream( Reference< XSeekable >( rxOutStrm, UNO_QUERY ) ),
41 maBuffer( OUTPUTSTREAM_BUFFERSIZE ),
42 mxOutStrm( rxOutStrm ),
43 mbAutoClose( bAutoClose && rxOutStrm.is() )
44{
45 mbEof = !mxOutStrm.is();
46}
47
49{
50 close();
51}
52
54{
55 OSL_ENSURE( !mbAutoClose || mxOutStrm.is(), "BinaryXOutputStream::close - invalid call" );
56 if( mxOutStrm.is() ) try
57 {
58 mxOutStrm->flush();
59 if ( mbAutoClose )
60 mxOutStrm->closeOutput();
61 }
62 catch( Exception& )
63 {
64 OSL_FAIL( "BinaryXOutputStream::close - closing output stream failed" );
65 }
66 mxOutStrm.clear();
67 mbAutoClose = false;
69}
70
71void BinaryXOutputStream::writeData( const StreamDataSequence& rData, size_t /*nAtomSize*/ )
72{
73 if( mxOutStrm.is() ) try
74 {
75 mxOutStrm->writeBytes( rData );
76 }
77 catch( Exception& )
78 {
79 OSL_FAIL( "BinaryXOutputStream::writeData - stream read error" );
80 }
81}
82
83void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize )
84{
85 if( !(mxOutStrm.is() && (nBytes > 0)) )
86 return;
87
88 sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, (OUTPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize );
89 const sal_uInt8* pnMem = static_cast< const sal_uInt8* >( pMem );
90 while( nBytes > 0 )
91 {
92 sal_Int32 nWriteSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize );
93 maBuffer.realloc( nWriteSize );
94 memcpy( maBuffer.getArray(), pnMem, static_cast< size_t >( nWriteSize ) );
95 writeData( maBuffer, nAtomSize );
96 pnMem += nWriteSize;
97 nBytes -= nWriteSize;
98 }
99}
100
101void
102BinaryOutputStream::writeCharArrayUC( std::u16string_view rString, rtl_TextEncoding eTextEnc )
103{
104 OString sBuf( OUStringToOString( rString, eTextEnc ) );
105 sBuf = sBuf.replace( '\0', '?' );
106 writeMemory( static_cast< const void* >( sBuf.getStr() ), sBuf.getLength() );
107}
108
109void
111{
112 OUString sBuf = rString.replace( '\0', '?' );
113#ifdef OSL_BIGENDIAN
114 // need a non-const buffer for swapping byte order
115 sal_Unicode notConst[sBuf.getLength()];
116 memcpy( notConst, sBuf.getStr(), sizeof(sal_Unicode)*sBuf.getLength() );
117 writeArray( notConst, sBuf.getLength() );
118#else
119 writeArray( sBuf.getStr(), sBuf.getLength() );
120#endif
121}
122
123void BinaryOutputStream::writeCompressedUnicodeArray( const OUString& rString, bool bCompressed )
124{
125 if ( bCompressed )
126 // ISO-8859-1 maps all byte values 0xHH to the same Unicode code point U+00HH
127 writeCharArrayUC( rString, RTL_TEXTENCODING_ISO_8859_1 );
128 else
129 writeUnicodeArray( rString );
130}
131
133 BinaryStreamBase( true ),
134 mpData( &rData ),
135 mnPos( 0 )
136{
137}
138
139void SequenceOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize )
140{
141 if( mpData && rData.hasElements() )
142 writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize );
143}
144
145void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t /*nAtomSize*/ )
146{
147 if( mpData && (nBytes > 0) )
148 {
149 if( mpData->getLength() - mnPos < nBytes )
150 mpData->realloc( mnPos + nBytes );
151 memcpy( mpData->getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) );
152 mnPos += nBytes;
153 }
154}
155
157{
158 return mpData ? mpData->getLength() : -1;
159}
160
162{
163 return mpData ? mnPos : -1;
164}
165
166void SequenceOutputStream::seek( sal_Int64 nPos )
167{
168 if( mpData )
169 {
170 mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mpData->getLength() );
171 mbEof = mnPos != nPos;
172 }
173}
174
176{
177 mpData = nullptr;
178 mbEof = true;
179}
180
181
182} // namespace oox
183
184/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void writeCharArrayUC(std::u16string_view rString, rtl_TextEncoding eTextEnc)
virtual void writeMemory(const void *pMem, sal_Int32 nBytes, size_t nAtomSize=1)=0
Derived classes implement writing the contents of the (preallocated!) memory buffer pMem.
void writeCompressedUnicodeArray(const OUString &rString, bool bCompressed)
void writeArray(Type *opnArray, sal_Int32 nElemCount)
void writeUnicodeArray(const OUString &rString)
Base class for binary stream classes.
bool mbEof
End of stream flag.
BinaryXOutputStream(const css::uno::Reference< css::io::XOutputStream > &rxOutStrm, bool bAutoClose)
Constructs the wrapper object for the passed output stream.
virtual void writeData(const StreamDataSequence &rData, size_t nAtomSize=1) override
Writes the passed data sequence.
StreamDataSequence maBuffer
Data buffer used in writeMemory() function.
css::uno::Reference< css::io::XOutputStream > mxOutStrm
Reference to the output stream.
virtual ~BinaryXOutputStream() override
void close() override
Flushes and closes the output stream.
virtual void writeMemory(const void *pMem, sal_Int32 nBytes, size_t nAtomSize=1) override
Write nBytes bytes from the (preallocated!) buffer pMem.
bool mbAutoClose
True = automatically close stream on destruction.
Base class for binary input and output streams wrapping a UNO stream, seekable via the com....
virtual void close() override
Releases the reference to the UNO XSeekable interface.
virtual sal_Int64 tell() const override
Returns the current stream position.
StreamDataSequence * mpData
Wrapped data sequence.
virtual void close() override
Releases the reference to the data sequence.
SequenceOutputStream(StreamDataSequence &rData)
Constructs the wrapper object for the passed data sequence.
virtual sal_Int64 size() const override
Returns the size of the wrapped data sequence.
virtual void seek(sal_Int64 nPos) override
Seeks the stream to the passed position.
sal_Int32 mnPos
Current position in the sequence.
virtual void writeData(const StreamDataSequence &rData, size_t nAtomSize=1) override
Writes the passed data sequence.
virtual void writeMemory(const void *pMem, sal_Int32 nBytes, size_t nAtomSize=1) override
Write nBytes bytes from the (preallocated!) buffer pMem.
sal_uInt16 nPos
@ Exception
Reference
css::uno::Sequence< sal_Int8 > StreamDataSequence
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Reference< XOutputStream > mxOutStrm
Definition: olestorage.cxx:78
unsigned char sal_uInt8
sal_uInt16 sal_Unicode