xref: /trunk/main/ucb/source/ucp/odma/odma_inputstream.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucb.hxx"
30 #include "odma_inputstream.hxx"
31 #include "com/sun/star/io/IOException.hpp"
32 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
33 #include <com/sun/star/ucb/OpenMode.hpp>
34 #include <ucbhelper/content.hxx>
35 #include <com/sun/star/io/XActiveDataStreamer.hpp>
36 #include <cppuhelper/implbase1.hxx>
37 #include "odma_contentprops.hxx"
38 #include "odma_provider.hxx"
39 
40 using namespace odma;
41 using namespace com::sun::star;
42 
43 class OActiveDataStreamer : public ::cppu::WeakImplHelper1< io::XActiveDataStreamer>
44 {
45     uno::Reference< io::XStream > m_xStream;
46 public:
47     OActiveDataStreamer(){}
48     virtual void SAL_CALL setStream( const uno::Reference< io::XStream >& _rStream ) throw (uno::RuntimeException)
49     {
50         m_xStream = _rStream;
51     }
52     virtual uno::Reference< io::XStream > SAL_CALL getStream(  ) throw (uno::RuntimeException)
53     {
54         return m_xStream;
55     }
56 };
57 // -----------------------------------------------------------------------------
58 OOdmaStream::OOdmaStream(::ucbhelper::Content* _pContent,
59                          ContentProvider* _pProvider,
60                          const ::rtl::Reference<ContentProperties>& _rProp)
61  :m_pContent(_pContent)
62  ,m_bInputStreamCalled(sal_False)
63  ,m_bOutputStreamCalled(sal_False)
64  ,m_bModified(sal_False)
65  ,m_pProvider(_pProvider)
66  ,m_aProp(_rProp)
67 {
68 }
69 // -----------------------------------------------------------------------------
70 OOdmaStream::~OOdmaStream()
71 {
72     try
73     {
74         closeStream();
75         delete m_pContent;
76     }
77     catch (io::IOException const &)
78     {
79         OSL_ENSURE(false, "unexpected situation");
80     }
81     catch (uno::RuntimeException const &)
82     {
83         OSL_ENSURE(false, "unexpected situation");
84     }
85 }
86 // -----------------------------------------------------------------------------
87 uno::Reference< io::XInputStream > SAL_CALL OOdmaStream::getInputStream(  ) throw( uno::RuntimeException)
88 {
89     {
90         osl::MutexGuard aGuard( m_aMutex );
91         m_bInputStreamCalled = sal_True;
92     }
93     return uno::Reference< io::XInputStream >( this );
94 }
95 // -----------------------------------------------------------------------------
96 uno::Reference< io::XOutputStream > SAL_CALL OOdmaStream::getOutputStream(  ) throw( uno::RuntimeException )
97 {
98     {
99         osl::MutexGuard aGuard( m_aMutex );
100         m_bOutputStreamCalled = sal_True;
101     }
102     return uno::Reference< io::XOutputStream >( this );
103 }
104 // -----------------------------------------------------------------------------
105 sal_Int32 SAL_CALL OOdmaStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
106     throw( io::NotConnectedException,
107            io::BufferSizeExceededException,
108            io::IOException,
109            uno::RuntimeException)
110 {
111     ensureInputStream();
112 
113     return m_xInput->readBytes(aData,nBytesToRead);
114 }
115 // -----------------------------------------------------------------------------
116 sal_Int32 SAL_CALL OOdmaStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
117     throw( io::NotConnectedException,
118            io::BufferSizeExceededException,
119            io::IOException,
120            uno::RuntimeException)
121 {
122     return readBytes( aData,nMaxBytesToRead );
123 }
124 // -----------------------------------------------------------------------------
125 void SAL_CALL OOdmaStream::skipBytes( sal_Int32 nBytesToSkip )
126     throw( io::NotConnectedException,
127            io::BufferSizeExceededException,
128            io::IOException,
129            uno::RuntimeException )
130 {
131     ensureInputStream();
132     m_xInput->skipBytes(nBytesToSkip );
133 }
134 // -----------------------------------------------------------------------------
135 sal_Int32 SAL_CALL OOdmaStream::available()
136     throw( io::NotConnectedException,
137            io::IOException,
138            uno::RuntimeException)
139 {
140     ensureInputStream();
141     return m_xInput->available();
142 }
143 // -----------------------------------------------------------------------------
144 void SAL_CALL OOdmaStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
145     throw( io::NotConnectedException,
146            io::BufferSizeExceededException,
147            io::IOException,
148            uno::RuntimeException)
149 {
150     ensureOutputStream();
151     m_xOutput->writeBytes(aData);
152     m_bModified = sal_True;
153 }
154 // -----------------------------------------------------------------------------
155 void SAL_CALL OOdmaStream::closeStream() throw( io::NotConnectedException,io::IOException,uno::RuntimeException )
156 {
157     if( m_xInput.is() )
158     {
159         m_xInput->closeInput();
160         m_xInput        = NULL;
161         m_xInputSeek    = NULL;
162     }
163     if(m_xOutput.is())
164     {
165         m_xOutput->closeOutput();
166         m_xOutput       = NULL;
167         m_xTruncate     = NULL;
168         if(m_bModified)
169             m_pProvider->saveDocument(m_aProp->m_sDocumentId);
170     }
171 }
172 // -----------------------------------------------------------------------------
173 void SAL_CALL OOdmaStream::closeInput()
174     throw( io::NotConnectedException,
175            io::IOException,
176            uno::RuntimeException )
177 {
178     osl::MutexGuard aGuard( m_aMutex );
179     m_bInputStreamCalled = sal_False;
180 
181     if( ! m_bOutputStreamCalled )
182         closeStream();
183 }
184 // -----------------------------------------------------------------------------
185 void SAL_CALL OOdmaStream::closeOutput()
186     throw( io::NotConnectedException,
187            io::IOException,
188            uno::RuntimeException )
189 {
190     osl::MutexGuard aGuard( m_aMutex );
191     m_bOutputStreamCalled = sal_False;
192 
193     if( ! m_bInputStreamCalled )
194         closeStream();
195 }
196 // -----------------------------------------------------------------------------
197 void SAL_CALL OOdmaStream::flush()
198     throw( io::NotConnectedException,
199            io::BufferSizeExceededException,
200            io::IOException,
201            uno::RuntimeException )
202 {
203     ensureOutputStream();
204     m_xOutput->flush();
205 }
206 // -----------------------------------------------------------------------------
207 void OOdmaStream::ensureInputStream() throw( io::IOException )
208 {
209     try
210     {
211         if(!m_xInput.is())
212         {
213             m_xInput = m_pContent->openStream();
214             m_xInputSeek = uno::Reference< io::XSeekable>(m_xInput,uno::UNO_QUERY);
215         }
216     }
217     catch(const uno::Exception&)
218     {
219     }
220     if(!m_xInput.is())
221         throw io::IOException();
222 }
223 // -----------------------------------------------------------------------------
224 void OOdmaStream::ensureOutputStream() throw( io::IOException )
225 {
226     try
227     {
228         if(!m_xOutput.is())
229         {
230             ucb::OpenCommandArgument2 aCommand;
231             aCommand.Mode = ucb::OpenMode::DOCUMENT;
232             uno::Reference< io::XActiveDataStreamer > xActiveStreamer = new OActiveDataStreamer();
233             aCommand.Sink = xActiveStreamer;
234             m_pContent->executeCommand(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("open")),uno::makeAny(aCommand));
235             if(xActiveStreamer.is())
236             {
237                 uno::Reference< io::XStream> xStream = xActiveStreamer->getStream();
238                 if(xStream.is())
239                     m_xOutput = xStream->getOutputStream();
240             }
241         }
242     }
243     catch(const uno::Exception&)
244     {
245     }
246     if(!m_xOutput.is())
247         throw io::IOException();
248     m_xTruncate = uno::Reference< io::XTruncate>(m_xOutput,uno::UNO_QUERY);
249 }
250 // -----------------------------------------------------------------------------
251 // XTruncate
252 void SAL_CALL OOdmaStream::truncate( void )
253     throw( io::IOException,
254            uno::RuntimeException )
255 {
256     if(m_xTruncate.is())
257         m_xTruncate->truncate();
258 }
259 // -----------------------------------------------------------------------------
260 // XSeekable
261 void SAL_CALL OOdmaStream::seek(sal_Int64 location )
262     throw( lang::IllegalArgumentException,
263            io::IOException,
264            uno::RuntimeException )
265 {
266     ensureInputStream();
267     if(m_xInputSeek.is())
268         m_xInputSeek->seek(location);
269 }
270 // -----------------------------------------------------------------------------
271 sal_Int64 SAL_CALL OOdmaStream::getPosition()
272     throw( io::IOException,
273            uno::RuntimeException )
274 {
275     ensureInputStream();
276     return m_xInputSeek.is() ? m_xInputSeek->getPosition() : sal_Int64(0);
277 }
278 // -----------------------------------------------------------------------------
279 sal_Int64 SAL_CALL OOdmaStream::getLength()
280     throw( io::IOException,
281            uno::RuntimeException )
282 {
283     ensureInputStream();
284     return m_xInputSeek.is() ? m_xInputSeek->getLength() : sal_Int64(0);
285 }
286 // -----------------------------------------------------------------------------
287