1*dde7d3faSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*dde7d3faSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*dde7d3faSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*dde7d3faSAndrew Rist * distributed with this work for additional information
6*dde7d3faSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*dde7d3faSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*dde7d3faSAndrew Rist * "License"); you may not use this file except in compliance
9*dde7d3faSAndrew Rist * with the License. You may obtain a copy of the License at
10*dde7d3faSAndrew Rist *
11*dde7d3faSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*dde7d3faSAndrew Rist *
13*dde7d3faSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*dde7d3faSAndrew Rist * software distributed under the License is distributed on an
15*dde7d3faSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*dde7d3faSAndrew Rist * KIND, either express or implied. See the License for the
17*dde7d3faSAndrew Rist * specific language governing permissions and limitations
18*dde7d3faSAndrew Rist * under the License.
19*dde7d3faSAndrew Rist *
20*dde7d3faSAndrew Rist *************************************************************/
21*dde7d3faSAndrew Rist
22*dde7d3faSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_comphelper.hxx"
26cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
27cdf0e10cSrcweir
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include <comphelper/seekableinput.hxx>
30cdf0e10cSrcweir
31cdf0e10cSrcweir using namespace ::com::sun::star;
32cdf0e10cSrcweir
33cdf0e10cSrcweir namespace comphelper
34cdf0e10cSrcweir {
35cdf0e10cSrcweir
36cdf0e10cSrcweir const sal_Int32 nConstBufferSize = 32000;
37cdf0e10cSrcweir
38cdf0e10cSrcweir //---------------------------------------------------------------------------
copyInputToOutput_Impl(const uno::Reference<io::XInputStream> & xIn,const uno::Reference<io::XOutputStream> & xOut)39cdf0e10cSrcweir void copyInputToOutput_Impl( const uno::Reference< io::XInputStream >& xIn,
40cdf0e10cSrcweir const uno::Reference< io::XOutputStream >& xOut )
41cdf0e10cSrcweir {
42cdf0e10cSrcweir sal_Int32 nRead;
43cdf0e10cSrcweir uno::Sequence< sal_Int8 > aSequence( nConstBufferSize );
44cdf0e10cSrcweir
45cdf0e10cSrcweir do
46cdf0e10cSrcweir {
47cdf0e10cSrcweir nRead = xIn->readBytes( aSequence, nConstBufferSize );
48cdf0e10cSrcweir if ( nRead < nConstBufferSize )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir uno::Sequence< sal_Int8 > aTempBuf( aSequence.getConstArray(), nRead );
51cdf0e10cSrcweir xOut->writeBytes( aTempBuf );
52cdf0e10cSrcweir }
53cdf0e10cSrcweir else
54cdf0e10cSrcweir xOut->writeBytes( aSequence );
55cdf0e10cSrcweir }
56cdf0e10cSrcweir while ( nRead == nConstBufferSize );
57cdf0e10cSrcweir }
58cdf0e10cSrcweir
59cdf0e10cSrcweir //---------------------------------------------------------------------------
OSeekableInputWrapper(const uno::Reference<io::XInputStream> & xInStream,const uno::Reference<lang::XMultiServiceFactory> & xFactory)60cdf0e10cSrcweir OSeekableInputWrapper::OSeekableInputWrapper(
61cdf0e10cSrcweir const uno::Reference< io::XInputStream >& xInStream,
62cdf0e10cSrcweir const uno::Reference< lang::XMultiServiceFactory >& xFactory )
63cdf0e10cSrcweir : m_xFactory( xFactory )
64cdf0e10cSrcweir , m_xOriginalStream( xInStream )
65cdf0e10cSrcweir {
66cdf0e10cSrcweir if ( !m_xFactory.is() )
67cdf0e10cSrcweir throw uno::RuntimeException();
68cdf0e10cSrcweir }
69cdf0e10cSrcweir
70cdf0e10cSrcweir //---------------------------------------------------------------------------
~OSeekableInputWrapper()71cdf0e10cSrcweir OSeekableInputWrapper::~OSeekableInputWrapper()
72cdf0e10cSrcweir {
73cdf0e10cSrcweir }
74cdf0e10cSrcweir
75cdf0e10cSrcweir //---------------------------------------------------------------------------
CheckSeekableCanWrap(const uno::Reference<io::XInputStream> & xInStream,const uno::Reference<lang::XMultiServiceFactory> & xFactory)76cdf0e10cSrcweir uno::Reference< io::XInputStream > OSeekableInputWrapper::CheckSeekableCanWrap(
77cdf0e10cSrcweir const uno::Reference< io::XInputStream >& xInStream,
78cdf0e10cSrcweir const uno::Reference< lang::XMultiServiceFactory >& xFactory )
79cdf0e10cSrcweir {
80cdf0e10cSrcweir // check that the stream is seekable and just wrap it if it is not
81cdf0e10cSrcweir uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
82cdf0e10cSrcweir if ( xSeek.is() )
83cdf0e10cSrcweir return xInStream;
84cdf0e10cSrcweir
85cdf0e10cSrcweir uno::Reference< io::XInputStream > xNewStream(
86cdf0e10cSrcweir static_cast< io::XInputStream* >(
87cdf0e10cSrcweir new OSeekableInputWrapper( xInStream, xFactory ) ) );
88cdf0e10cSrcweir return xNewStream;
89cdf0e10cSrcweir }
90cdf0e10cSrcweir
91cdf0e10cSrcweir //---------------------------------------------------------------------------
PrepareCopy_Impl()92cdf0e10cSrcweir void OSeekableInputWrapper::PrepareCopy_Impl()
93cdf0e10cSrcweir {
94cdf0e10cSrcweir if ( !m_xCopyInput.is() )
95cdf0e10cSrcweir {
96cdf0e10cSrcweir if ( !m_xFactory.is() )
97cdf0e10cSrcweir throw uno::RuntimeException();
98cdf0e10cSrcweir
99cdf0e10cSrcweir uno::Reference< io::XOutputStream > xTempOut(
100cdf0e10cSrcweir m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
101cdf0e10cSrcweir uno::UNO_QUERY );
102cdf0e10cSrcweir
103cdf0e10cSrcweir if ( xTempOut.is() )
104cdf0e10cSrcweir {
105cdf0e10cSrcweir copyInputToOutput_Impl( m_xOriginalStream, xTempOut );
106cdf0e10cSrcweir xTempOut->closeOutput();
107cdf0e10cSrcweir
108cdf0e10cSrcweir uno::Reference< io::XSeekable > xTempSeek( xTempOut, uno::UNO_QUERY );
109cdf0e10cSrcweir if ( xTempSeek.is() )
110cdf0e10cSrcweir {
111cdf0e10cSrcweir xTempSeek->seek( 0 );
112cdf0e10cSrcweir m_xCopyInput = uno::Reference< io::XInputStream >( xTempOut, uno::UNO_QUERY );
113cdf0e10cSrcweir if ( m_xCopyInput.is() )
114cdf0e10cSrcweir m_xCopySeek = xTempSeek;
115cdf0e10cSrcweir }
116cdf0e10cSrcweir }
117cdf0e10cSrcweir }
118cdf0e10cSrcweir
119cdf0e10cSrcweir if ( !m_xCopyInput.is() )
120cdf0e10cSrcweir throw io::IOException();
121cdf0e10cSrcweir }
122cdf0e10cSrcweir
123cdf0e10cSrcweir // XInputStream
124cdf0e10cSrcweir //---------------------------------------------------------------------------
readBytes(uno::Sequence<sal_Int8> & aData,sal_Int32 nBytesToRead)125cdf0e10cSrcweir sal_Int32 SAL_CALL OSeekableInputWrapper::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
126cdf0e10cSrcweir throw ( io::NotConnectedException,
127cdf0e10cSrcweir io::BufferSizeExceededException,
128cdf0e10cSrcweir io::IOException,
129cdf0e10cSrcweir uno::RuntimeException )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
132cdf0e10cSrcweir
133cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
134cdf0e10cSrcweir throw io::NotConnectedException();
135cdf0e10cSrcweir
136cdf0e10cSrcweir PrepareCopy_Impl();
137cdf0e10cSrcweir
138cdf0e10cSrcweir return m_xCopyInput->readBytes( aData, nBytesToRead );
139cdf0e10cSrcweir }
140cdf0e10cSrcweir
141cdf0e10cSrcweir //---------------------------------------------------------------------------
readSomeBytes(uno::Sequence<sal_Int8> & aData,sal_Int32 nMaxBytesToRead)142cdf0e10cSrcweir sal_Int32 SAL_CALL OSeekableInputWrapper::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
143cdf0e10cSrcweir throw ( io::NotConnectedException,
144cdf0e10cSrcweir io::BufferSizeExceededException,
145cdf0e10cSrcweir io::IOException,
146cdf0e10cSrcweir uno::RuntimeException )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
149cdf0e10cSrcweir
150cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
151cdf0e10cSrcweir throw io::NotConnectedException();
152cdf0e10cSrcweir
153cdf0e10cSrcweir PrepareCopy_Impl();
154cdf0e10cSrcweir
155cdf0e10cSrcweir return m_xCopyInput->readSomeBytes( aData, nMaxBytesToRead );
156cdf0e10cSrcweir }
157cdf0e10cSrcweir
158cdf0e10cSrcweir //---------------------------------------------------------------------------
skipBytes(sal_Int32 nBytesToSkip)159cdf0e10cSrcweir void SAL_CALL OSeekableInputWrapper::skipBytes( sal_Int32 nBytesToSkip )
160cdf0e10cSrcweir throw ( io::NotConnectedException,
161cdf0e10cSrcweir io::BufferSizeExceededException,
162cdf0e10cSrcweir io::IOException,
163cdf0e10cSrcweir uno::RuntimeException )
164cdf0e10cSrcweir {
165cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
166cdf0e10cSrcweir
167cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
168cdf0e10cSrcweir throw io::NotConnectedException();
169cdf0e10cSrcweir
170cdf0e10cSrcweir PrepareCopy_Impl();
171cdf0e10cSrcweir
172cdf0e10cSrcweir m_xCopyInput->skipBytes( nBytesToSkip );
173cdf0e10cSrcweir }
174cdf0e10cSrcweir
175cdf0e10cSrcweir //---------------------------------------------------------------------------
available()176cdf0e10cSrcweir sal_Int32 SAL_CALL OSeekableInputWrapper::available()
177cdf0e10cSrcweir throw ( io::NotConnectedException,
178cdf0e10cSrcweir io::IOException,
179cdf0e10cSrcweir uno::RuntimeException )
180cdf0e10cSrcweir {
181cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
182cdf0e10cSrcweir
183cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
184cdf0e10cSrcweir throw io::NotConnectedException();
185cdf0e10cSrcweir
186cdf0e10cSrcweir PrepareCopy_Impl();
187cdf0e10cSrcweir
188cdf0e10cSrcweir return m_xCopyInput->available();
189cdf0e10cSrcweir }
190cdf0e10cSrcweir
191cdf0e10cSrcweir //---------------------------------------------------------------------------
closeInput()192cdf0e10cSrcweir void SAL_CALL OSeekableInputWrapper::closeInput()
193cdf0e10cSrcweir throw ( io::NotConnectedException,
194cdf0e10cSrcweir io::IOException,
195cdf0e10cSrcweir uno::RuntimeException )
196cdf0e10cSrcweir {
197cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
198cdf0e10cSrcweir
199cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
200cdf0e10cSrcweir throw io::NotConnectedException();
201cdf0e10cSrcweir
202cdf0e10cSrcweir m_xOriginalStream->closeInput();
203cdf0e10cSrcweir m_xOriginalStream = uno::Reference< io::XInputStream >();
204cdf0e10cSrcweir
205cdf0e10cSrcweir if ( m_xCopyInput.is() )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir m_xCopyInput->closeInput();
208cdf0e10cSrcweir m_xCopyInput = uno::Reference< io::XInputStream >();
209cdf0e10cSrcweir }
210cdf0e10cSrcweir
211cdf0e10cSrcweir m_xCopySeek = uno::Reference< io::XSeekable >();
212cdf0e10cSrcweir }
213cdf0e10cSrcweir
214cdf0e10cSrcweir
215cdf0e10cSrcweir // XSeekable
216cdf0e10cSrcweir //---------------------------------------------------------------------------
seek(sal_Int64 location)217cdf0e10cSrcweir void SAL_CALL OSeekableInputWrapper::seek( sal_Int64 location )
218cdf0e10cSrcweir throw ( lang::IllegalArgumentException,
219cdf0e10cSrcweir io::IOException,
220cdf0e10cSrcweir uno::RuntimeException )
221cdf0e10cSrcweir {
222cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
223cdf0e10cSrcweir
224cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
225cdf0e10cSrcweir throw io::NotConnectedException();
226cdf0e10cSrcweir
227cdf0e10cSrcweir PrepareCopy_Impl();
228cdf0e10cSrcweir
229cdf0e10cSrcweir m_xCopySeek->seek( location );
230cdf0e10cSrcweir }
231cdf0e10cSrcweir
232cdf0e10cSrcweir //---------------------------------------------------------------------------
getPosition()233cdf0e10cSrcweir sal_Int64 SAL_CALL OSeekableInputWrapper::getPosition()
234cdf0e10cSrcweir throw ( io::IOException,
235cdf0e10cSrcweir uno::RuntimeException )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
238cdf0e10cSrcweir
239cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
240cdf0e10cSrcweir throw io::NotConnectedException();
241cdf0e10cSrcweir
242cdf0e10cSrcweir PrepareCopy_Impl();
243cdf0e10cSrcweir
244cdf0e10cSrcweir return m_xCopySeek->getPosition();
245cdf0e10cSrcweir }
246cdf0e10cSrcweir
247cdf0e10cSrcweir //---------------------------------------------------------------------------
getLength()248cdf0e10cSrcweir sal_Int64 SAL_CALL OSeekableInputWrapper::getLength()
249cdf0e10cSrcweir throw ( io::IOException,
250cdf0e10cSrcweir uno::RuntimeException )
251cdf0e10cSrcweir {
252cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
253cdf0e10cSrcweir
254cdf0e10cSrcweir if ( !m_xOriginalStream.is() )
255cdf0e10cSrcweir throw io::NotConnectedException();
256cdf0e10cSrcweir
257cdf0e10cSrcweir PrepareCopy_Impl();
258cdf0e10cSrcweir
259cdf0e10cSrcweir return m_xCopySeek->getLength();
260cdf0e10cSrcweir }
261cdf0e10cSrcweir
262cdf0e10cSrcweir } // namespace comphelper
263cdf0e10cSrcweir
264