1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: seekableinput.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
33 #include <com/sun/star/io/XOutputStream.hpp>
36 #include <comphelper/seekableinput.hxx>
38 using namespace ::com::sun::star
;
43 const sal_Int32 nConstBufferSize
= 32000;
45 //---------------------------------------------------------------------------
46 void copyInputToOutput_Impl( const uno::Reference
< io::XInputStream
>& xIn
,
47 const uno::Reference
< io::XOutputStream
>& xOut
)
50 uno::Sequence
< sal_Int8
> aSequence( nConstBufferSize
);
54 nRead
= xIn
->readBytes( aSequence
, nConstBufferSize
);
55 if ( nRead
< nConstBufferSize
)
57 uno::Sequence
< sal_Int8
> aTempBuf( aSequence
.getConstArray(), nRead
);
58 xOut
->writeBytes( aTempBuf
);
61 xOut
->writeBytes( aSequence
);
63 while ( nRead
== nConstBufferSize
);
66 //---------------------------------------------------------------------------
67 OSeekableInputWrapper::OSeekableInputWrapper(
68 const uno::Reference
< io::XInputStream
>& xInStream
,
69 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
70 : m_xFactory( xFactory
)
71 , m_xOriginalStream( xInStream
)
73 if ( !m_xFactory
.is() )
74 throw uno::RuntimeException();
77 //---------------------------------------------------------------------------
78 OSeekableInputWrapper::~OSeekableInputWrapper()
82 //---------------------------------------------------------------------------
83 uno::Reference
< io::XInputStream
> OSeekableInputWrapper::CheckSeekableCanWrap(
84 const uno::Reference
< io::XInputStream
>& xInStream
,
85 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
87 // check that the stream is seekable and just wrap it if it is not
88 uno::Reference
< io::XSeekable
> xSeek( xInStream
, uno::UNO_QUERY
);
92 uno::Reference
< io::XInputStream
> xNewStream(
93 static_cast< io::XInputStream
* >(
94 new OSeekableInputWrapper( xInStream
, xFactory
) ) );
98 //---------------------------------------------------------------------------
99 void OSeekableInputWrapper::PrepareCopy_Impl()
101 if ( !m_xCopyInput
.is() )
103 if ( !m_xFactory
.is() )
104 throw uno::RuntimeException();
106 uno::Reference
< io::XOutputStream
> xTempOut(
107 m_xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
112 copyInputToOutput_Impl( m_xOriginalStream
, xTempOut
);
113 xTempOut
->closeOutput();
115 uno::Reference
< io::XSeekable
> xTempSeek( xTempOut
, uno::UNO_QUERY
);
116 if ( xTempSeek
.is() )
118 xTempSeek
->seek( 0 );
119 m_xCopyInput
= uno::Reference
< io::XInputStream
>( xTempOut
, uno::UNO_QUERY
);
120 if ( m_xCopyInput
.is() )
121 m_xCopySeek
= xTempSeek
;
126 if ( !m_xCopyInput
.is() )
127 throw io::IOException();
131 //---------------------------------------------------------------------------
132 sal_Int32 SAL_CALL
OSeekableInputWrapper::readBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
133 throw ( io::NotConnectedException
,
134 io::BufferSizeExceededException
,
136 uno::RuntimeException
)
138 ::osl::MutexGuard
aGuard( m_aMutex
);
140 if ( !m_xOriginalStream
.is() )
141 throw io::NotConnectedException();
145 return m_xCopyInput
->readBytes( aData
, nBytesToRead
);
148 //---------------------------------------------------------------------------
149 sal_Int32 SAL_CALL
OSeekableInputWrapper::readSomeBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
150 throw ( io::NotConnectedException
,
151 io::BufferSizeExceededException
,
153 uno::RuntimeException
)
155 ::osl::MutexGuard
aGuard( m_aMutex
);
157 if ( !m_xOriginalStream
.is() )
158 throw io::NotConnectedException();
162 return m_xCopyInput
->readSomeBytes( aData
, nMaxBytesToRead
);
165 //---------------------------------------------------------------------------
166 void SAL_CALL
OSeekableInputWrapper::skipBytes( sal_Int32 nBytesToSkip
)
167 throw ( io::NotConnectedException
,
168 io::BufferSizeExceededException
,
170 uno::RuntimeException
)
172 ::osl::MutexGuard
aGuard( m_aMutex
);
174 if ( !m_xOriginalStream
.is() )
175 throw io::NotConnectedException();
179 m_xCopyInput
->skipBytes( nBytesToSkip
);
182 //---------------------------------------------------------------------------
183 sal_Int32 SAL_CALL
OSeekableInputWrapper::available()
184 throw ( io::NotConnectedException
,
186 uno::RuntimeException
)
188 ::osl::MutexGuard
aGuard( m_aMutex
);
190 if ( !m_xOriginalStream
.is() )
191 throw io::NotConnectedException();
195 return m_xCopyInput
->available();
198 //---------------------------------------------------------------------------
199 void SAL_CALL
OSeekableInputWrapper::closeInput()
200 throw ( io::NotConnectedException
,
202 uno::RuntimeException
)
204 ::osl::MutexGuard
aGuard( m_aMutex
);
206 if ( !m_xOriginalStream
.is() )
207 throw io::NotConnectedException();
209 m_xOriginalStream
->closeInput();
210 m_xOriginalStream
= uno::Reference
< io::XInputStream
>();
212 if ( m_xCopyInput
.is() )
214 m_xCopyInput
->closeInput();
215 m_xCopyInput
= uno::Reference
< io::XInputStream
>();
218 m_xCopySeek
= uno::Reference
< io::XSeekable
>();
223 //---------------------------------------------------------------------------
224 void SAL_CALL
OSeekableInputWrapper::seek( sal_Int64 location
)
225 throw ( lang::IllegalArgumentException
,
227 uno::RuntimeException
)
229 ::osl::MutexGuard
aGuard( m_aMutex
);
231 if ( !m_xOriginalStream
.is() )
232 throw io::NotConnectedException();
236 m_xCopySeek
->seek( location
);
239 //---------------------------------------------------------------------------
240 sal_Int64 SAL_CALL
OSeekableInputWrapper::getPosition()
241 throw ( io::IOException
,
242 uno::RuntimeException
)
244 ::osl::MutexGuard
aGuard( m_aMutex
);
246 if ( !m_xOriginalStream
.is() )
247 throw io::NotConnectedException();
251 return m_xCopySeek
->getPosition();
254 //---------------------------------------------------------------------------
255 sal_Int64 SAL_CALL
OSeekableInputWrapper::getLength()
256 throw ( io::IOException
,
257 uno::RuntimeException
)
259 ::osl::MutexGuard
aGuard( m_aMutex
);
261 if ( !m_xOriginalStream
.is() )
262 throw io::NotConnectedException();
266 return m_xCopySeek
->getLength();
269 } // namespace comphelper