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: 43 OActiveDataStreamer(){} 44 virtual void SAL_CALL setStream( const uno::Reference< io::XStream >& _rStream ) throw (uno::RuntimeException) 45 { 46 m_xStream = _rStream; 47 } 48 virtual uno::Reference< io::XStream > SAL_CALL getStream( ) throw (uno::RuntimeException) 49 { 50 return m_xStream; 51 } 52 }; 53 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 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 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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