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