1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26 #include "odma_inputstream.hxx"
27 #include "com/sun/star/io/IOException.hpp"
28 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
29 #include <com/sun/star/ucb/OpenMode.hpp>
30 #include <ucbhelper/content.hxx>
31 #include <com/sun/star/io/XActiveDataStreamer.hpp>
32 #include <cppuhelper/implbase1.hxx>
33 #include "odma_contentprops.hxx"
34 #include "odma_provider.hxx"
35
36 using namespace odma;
37 using namespace com::sun::star;
38
39 class OActiveDataStreamer : public ::cppu::WeakImplHelper1< io::XActiveDataStreamer>
40 {
41 uno::Reference< io::XStream > m_xStream;
42 public:
OActiveDataStreamer()43 OActiveDataStreamer(){}
setStream(const uno::Reference<io::XStream> & _rStream)44 virtual void SAL_CALL setStream( const uno::Reference< io::XStream >& _rStream ) throw (uno::RuntimeException)
45 {
46 m_xStream = _rStream;
47 }
getStream()48 virtual uno::Reference< io::XStream > SAL_CALL getStream( ) throw (uno::RuntimeException)
49 {
50 return m_xStream;
51 }
52 };
53 // -----------------------------------------------------------------------------
OOdmaStream(::ucbhelper::Content * _pContent,ContentProvider * _pProvider,const::rtl::Reference<ContentProperties> & _rProp)54 OOdmaStream::OOdmaStream(::ucbhelper::Content* _pContent,
55 ContentProvider* _pProvider,
56 const ::rtl::Reference<ContentProperties>& _rProp)
57 :m_pContent(_pContent)
58 ,m_bInputStreamCalled(sal_False)
59 ,m_bOutputStreamCalled(sal_False)
60 ,m_bModified(sal_False)
61 ,m_pProvider(_pProvider)
62 ,m_aProp(_rProp)
63 {
64 }
65 // -----------------------------------------------------------------------------
~OOdmaStream()66 OOdmaStream::~OOdmaStream()
67 {
68 try
69 {
70 closeStream();
71 delete m_pContent;
72 }
73 catch (io::IOException const &)
74 {
75 OSL_ENSURE(false, "unexpected situation");
76 }
77 catch (uno::RuntimeException const &)
78 {
79 OSL_ENSURE(false, "unexpected situation");
80 }
81 }
82 // -----------------------------------------------------------------------------
getInputStream()83 uno::Reference< io::XInputStream > SAL_CALL OOdmaStream::getInputStream( ) throw( uno::RuntimeException)
84 {
85 {
86 osl::MutexGuard aGuard( m_aMutex );
87 m_bInputStreamCalled = sal_True;
88 }
89 return uno::Reference< io::XInputStream >( this );
90 }
91 // -----------------------------------------------------------------------------
getOutputStream()92 uno::Reference< io::XOutputStream > SAL_CALL OOdmaStream::getOutputStream( ) throw( uno::RuntimeException )
93 {
94 {
95 osl::MutexGuard aGuard( m_aMutex );
96 m_bOutputStreamCalled = sal_True;
97 }
98 return uno::Reference< io::XOutputStream >( this );
99 }
100 // -----------------------------------------------------------------------------
readBytes(uno::Sequence<sal_Int8> & aData,sal_Int32 nBytesToRead)101 sal_Int32 SAL_CALL OOdmaStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
102 throw( io::NotConnectedException,
103 io::BufferSizeExceededException,
104 io::IOException,
105 uno::RuntimeException)
106 {
107 ensureInputStream();
108
109 return m_xInput->readBytes(aData,nBytesToRead);
110 }
111 // -----------------------------------------------------------------------------
readSomeBytes(uno::Sequence<sal_Int8> & aData,sal_Int32 nMaxBytesToRead)112 sal_Int32 SAL_CALL OOdmaStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
113 throw( io::NotConnectedException,
114 io::BufferSizeExceededException,
115 io::IOException,
116 uno::RuntimeException)
117 {
118 return readBytes( aData,nMaxBytesToRead );
119 }
120 // -----------------------------------------------------------------------------
skipBytes(sal_Int32 nBytesToSkip)121 void SAL_CALL OOdmaStream::skipBytes( sal_Int32 nBytesToSkip )
122 throw( io::NotConnectedException,
123 io::BufferSizeExceededException,
124 io::IOException,
125 uno::RuntimeException )
126 {
127 ensureInputStream();
128 m_xInput->skipBytes(nBytesToSkip );
129 }
130 // -----------------------------------------------------------------------------
available()131 sal_Int32 SAL_CALL OOdmaStream::available()
132 throw( io::NotConnectedException,
133 io::IOException,
134 uno::RuntimeException)
135 {
136 ensureInputStream();
137 return m_xInput->available();
138 }
139 // -----------------------------------------------------------------------------
writeBytes(const uno::Sequence<sal_Int8> & aData)140 void SAL_CALL OOdmaStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
141 throw( io::NotConnectedException,
142 io::BufferSizeExceededException,
143 io::IOException,
144 uno::RuntimeException)
145 {
146 ensureOutputStream();
147 m_xOutput->writeBytes(aData);
148 m_bModified = sal_True;
149 }
150 // -----------------------------------------------------------------------------
closeStream()151 void SAL_CALL OOdmaStream::closeStream() throw( io::NotConnectedException,io::IOException,uno::RuntimeException )
152 {
153 if( m_xInput.is() )
154 {
155 m_xInput->closeInput();
156 m_xInput = NULL;
157 m_xInputSeek = NULL;
158 }
159 if(m_xOutput.is())
160 {
161 m_xOutput->closeOutput();
162 m_xOutput = NULL;
163 m_xTruncate = NULL;
164 if(m_bModified)
165 m_pProvider->saveDocument(m_aProp->m_sDocumentId);
166 }
167 }
168 // -----------------------------------------------------------------------------
closeInput()169 void SAL_CALL OOdmaStream::closeInput()
170 throw( io::NotConnectedException,
171 io::IOException,
172 uno::RuntimeException )
173 {
174 osl::MutexGuard aGuard( m_aMutex );
175 m_bInputStreamCalled = sal_False;
176
177 if( ! m_bOutputStreamCalled )
178 closeStream();
179 }
180 // -----------------------------------------------------------------------------
closeOutput()181 void SAL_CALL OOdmaStream::closeOutput()
182 throw( io::NotConnectedException,
183 io::IOException,
184 uno::RuntimeException )
185 {
186 osl::MutexGuard aGuard( m_aMutex );
187 m_bOutputStreamCalled = sal_False;
188
189 if( ! m_bInputStreamCalled )
190 closeStream();
191 }
192 // -----------------------------------------------------------------------------
flush()193 void SAL_CALL OOdmaStream::flush()
194 throw( io::NotConnectedException,
195 io::BufferSizeExceededException,
196 io::IOException,
197 uno::RuntimeException )
198 {
199 ensureOutputStream();
200 m_xOutput->flush();
201 }
202 // -----------------------------------------------------------------------------
ensureInputStream()203 void OOdmaStream::ensureInputStream() throw( io::IOException )
204 {
205 try
206 {
207 if(!m_xInput.is())
208 {
209 m_xInput = m_pContent->openStream();
210 m_xInputSeek = uno::Reference< io::XSeekable>(m_xInput,uno::UNO_QUERY);
211 }
212 }
213 catch(const uno::Exception&)
214 {
215 }
216 if(!m_xInput.is())
217 throw io::IOException();
218 }
219 // -----------------------------------------------------------------------------
ensureOutputStream()220 void OOdmaStream::ensureOutputStream() throw( io::IOException )
221 {
222 try
223 {
224 if(!m_xOutput.is())
225 {
226 ucb::OpenCommandArgument2 aCommand;
227 aCommand.Mode = ucb::OpenMode::DOCUMENT;
228 uno::Reference< io::XActiveDataStreamer > xActiveStreamer = new OActiveDataStreamer();
229 aCommand.Sink = xActiveStreamer;
230 m_pContent->executeCommand(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("open")),uno::makeAny(aCommand));
231 if(xActiveStreamer.is())
232 {
233 uno::Reference< io::XStream> xStream = xActiveStreamer->getStream();
234 if(xStream.is())
235 m_xOutput = xStream->getOutputStream();
236 }
237 }
238 }
239 catch(const uno::Exception&)
240 {
241 }
242 if(!m_xOutput.is())
243 throw io::IOException();
244 m_xTruncate = uno::Reference< io::XTruncate>(m_xOutput,uno::UNO_QUERY);
245 }
246 // -----------------------------------------------------------------------------
247 // XTruncate
truncate(void)248 void SAL_CALL OOdmaStream::truncate( void )
249 throw( io::IOException,
250 uno::RuntimeException )
251 {
252 if(m_xTruncate.is())
253 m_xTruncate->truncate();
254 }
255 // -----------------------------------------------------------------------------
256 // XSeekable
seek(sal_Int64 location)257 void SAL_CALL OOdmaStream::seek(sal_Int64 location )
258 throw( lang::IllegalArgumentException,
259 io::IOException,
260 uno::RuntimeException )
261 {
262 ensureInputStream();
263 if(m_xInputSeek.is())
264 m_xInputSeek->seek(location);
265 }
266 // -----------------------------------------------------------------------------
getPosition()267 sal_Int64 SAL_CALL OOdmaStream::getPosition()
268 throw( io::IOException,
269 uno::RuntimeException )
270 {
271 ensureInputStream();
272 return m_xInputSeek.is() ? m_xInputSeek->getPosition() : sal_Int64(0);
273 }
274 // -----------------------------------------------------------------------------
getLength()275 sal_Int64 SAL_CALL OOdmaStream::getLength()
276 throw( io::IOException,
277 uno::RuntimeException )
278 {
279 ensureInputStream();
280 return m_xInputSeek.is() ? m_xInputSeek->getLength() : sal_Int64(0);
281 }
282 // -----------------------------------------------------------------------------
283