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 
27 namespace oox {
28 
29 using namespace ::com::sun::star::io;
30 using namespace ::com::sun::star::uno;
31 
32 namespace {
33 
34 const sal_Int32 OUTPUTSTREAM_BUFFERSIZE = 0x8000;
35 
36 } // namespace
37 
38 BinaryXOutputStream::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 
71 void 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 
83 void 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 
101 void
102 BinaryOutputStream::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 
109 void
110 BinaryOutputStream::writeUnicodeArray( const OUString& rString )
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 
123 void 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 
139 void SequenceOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize )
140 {
141  if( mpData && rData.hasElements() )
142  writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize );
143 }
144 
145 void 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 
156 sal_Int64 SequenceOutputStream::size() const
157 {
158  return mpData ? mpData->getLength() : -1;
159 }
160 
161 sal_Int64 SequenceOutputStream::tell() const
162 {
163  return mpData ? mnPos : -1;
164 }
165 
166 void 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: */
virtual void close() override
Releases the reference to the UNO XSeekable interface.
Base class for binary stream classes.
Base class for binary input and output streams wrapping a UNO stream, seekable via the com...
SequenceOutputStream(StreamDataSequence &rData)
Constructs the wrapper object for 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.
virtual sal_Int64 size() const override
Returns the size of the wrapped data sequence.
Reference
virtual void writeData(const StreamDataSequence &rData, size_t nAtomSize=1) override
Writes the passed data sequence.
Reference< XOutputStream > mxOutStrm
Definition: olestorage.cxx:77
sal_uInt16 sal_Unicode
virtual ~BinaryXOutputStream() override
void writeCompressedUnicodeArray(const OUString &rString, bool bCompressed)
BinaryXOutputStream(const css::uno::Reference< css::io::XOutputStream > &rxOutStrm, bool bAutoClose)
Constructs the wrapper object for the passed output stream.
virtual void seek(sal_Int64 nPos) override
Seeks the stream to the passed position.
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
css::uno::Sequence< sal_Int8 > StreamDataSequence
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...
css::uno::Reference< css::io::XOutputStream > mxOutStrm
Reference to the output stream.
sal_Int32 mnPos
Current position in the sequence.
StreamDataSequence maBuffer
Data buffer used in writeMemory() function.
bool mbEof
End of stream flag.
void writeCharArrayUC(std::u16string_view rString, rtl_TextEncoding eTextEnc)
virtual sal_Int64 tell() const override
Returns the current stream position.
virtual void close() override
Releases the reference to the data sequence.
virtual void writeData(const StreamDataSequence &rData, size_t nAtomSize=1) override
Writes the passed data sequence.
unsigned char sal_uInt8
void writeArray(Type *opnArray, sal_Int32 nElemCount)
virtual void writeMemory(const void *pMem, sal_Int32 nBytes, size_t nAtomSize=1) override
Write nBytes bytes from the (preallocated!) buffer pMem.
void close() override
Flushes and closes the output stream.
StreamDataSequence * mpData
Wrapped data sequence.
bool mbAutoClose
True = automatically close stream on destruction.
void writeUnicodeArray(const OUString &rString)