xref: /AOO41X/main/ucb/source/ucp/odma/odma_inputstream.cxx (revision 2f86921c33504fdff5a030df6c0b258927045abb)
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