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_comphelper.hxx" 26 27 #include "comphelper_module.hxx" 28 29 #include <sal/config.h> 30 #include <osl/mutex.hxx> 31 #include <cppuhelper/factory.hxx> 32 #include <cppuhelper/implementationentry.hxx> 33 #include <cppuhelper/implbase3.hxx> 34 #include <comphelper/seqstream.hxx> 35 #include <com/sun/star/lang/XServiceInfo.hpp> 36 #include <com/sun/star/io/XSeekableInputStream.hpp> 37 #include <com/sun/star/lang/XInitialization.hpp> 38 #include <com/sun/star/frame/DoubleInitializationException.hpp> 39 #include <com/sun/star/uno/XComponentContext.hpp> 40 41 42 using namespace ::com::sun::star; 43 44 namespace { 45 46 class SequenceInputStreamService: 47 public ::cppu::WeakImplHelper3< 48 lang::XServiceInfo, 49 io::XSeekableInputStream, 50 lang::XInitialization> 51 { 52 public: 53 explicit SequenceInputStreamService(); 54 55 // ::com::sun::star::lang::XServiceInfo: 56 virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( uno::RuntimeException ); 57 virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString & ServiceName ) throw ( uno::RuntimeException ); 58 virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( uno::RuntimeException ); 59 60 // XServiceInfo - static versions (used for component registration) 61 static ::rtl::OUString SAL_CALL getImplementationName_static(); 62 static uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); 63 static uno::Reference< uno::XInterface > SAL_CALL Create( const uno::Reference< uno::XComponentContext >& ); 64 65 // ::com::sun::star::io::XInputStream: 66 virtual ::sal_Int32 SAL_CALL readBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); 67 virtual ::sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nMaxBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); 68 virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); 69 virtual ::sal_Int32 SAL_CALL available() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ); 70 virtual void SAL_CALL closeInput() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ); 71 72 // ::com::sun::star::io::XSeekable: 73 virtual void SAL_CALL seek( ::sal_Int64 location ) throw ( uno::RuntimeException, lang::IllegalArgumentException, io::IOException ); 74 virtual ::sal_Int64 SAL_CALL getPosition() throw ( uno::RuntimeException, io::IOException ); 75 virtual ::sal_Int64 SAL_CALL getLength() throw ( uno::RuntimeException, io::IOException ); 76 77 // ::com::sun::star::lang::XInitialization: 78 virtual void SAL_CALL initialize( const uno::Sequence< ::com::sun::star::uno::Any > & aArguments ) throw ( uno::RuntimeException, uno::Exception ); 79 80 private: 81 SequenceInputStreamService( SequenceInputStreamService & ); // not defined 82 void operator =( SequenceInputStreamService & ); // not defined 83 84 virtual ~SequenceInputStreamService() {} 85 86 87 ::osl::Mutex m_aMutex; 88 sal_Bool m_bInitialized; 89 uno::Reference< io::XInputStream > m_xInputStream; 90 uno::Reference< io::XSeekable > m_xSeekable; 91 }; 92 93 SequenceInputStreamService::SequenceInputStreamService() 94 : m_bInitialized( sal_False ) 95 {} 96 97 // com.sun.star.uno.XServiceInfo: 98 ::rtl::OUString SAL_CALL SequenceInputStreamService::getImplementationName() throw ( uno::RuntimeException ) 99 { 100 return getImplementationName_static(); 101 } 102 103 ::rtl::OUString SAL_CALL SequenceInputStreamService::getImplementationName_static() 104 { 105 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.SequenceInputStreamService" ) ); 106 } 107 108 ::sal_Bool SAL_CALL SequenceInputStreamService::supportsService( ::rtl::OUString const & serviceName ) throw ( uno::RuntimeException ) 109 { 110 uno::Sequence< ::rtl::OUString > serviceNames = getSupportedServiceNames(); 111 for ( ::sal_Int32 i = 0; i < serviceNames.getLength(); ++i ) { 112 if ( serviceNames[i] == serviceName ) 113 return sal_True; 114 } 115 return sal_False; 116 } 117 118 uno::Sequence< ::rtl::OUString > SAL_CALL SequenceInputStreamService::getSupportedServiceNames() throw ( uno::RuntimeException ) 119 { 120 return getSupportedServiceNames_static(); 121 } 122 123 uno::Sequence< ::rtl::OUString > SAL_CALL SequenceInputStreamService::getSupportedServiceNames_static() 124 { 125 uno::Sequence< ::rtl::OUString > s( 1 ); 126 s[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 127 "com.sun.star.io.SequenceInputStream" ) ); 128 return s; 129 } 130 131 uno::Reference< uno::XInterface > SAL_CALL SequenceInputStreamService::Create( 132 const uno::Reference< uno::XComponentContext >& ) 133 { 134 return static_cast< ::cppu::OWeakObject * >( new SequenceInputStreamService() ); 135 } 136 137 // ::com::sun::star::io::XInputStream: 138 ::sal_Int32 SAL_CALL SequenceInputStreamService::readBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) 139 { 140 ::osl::MutexGuard aGuard( m_aMutex ); 141 if ( !m_xInputStream.is() ) 142 throw io::NotConnectedException(); 143 144 return m_xInputStream->readBytes( aData, nBytesToRead ); 145 } 146 147 ::sal_Int32 SAL_CALL SequenceInputStreamService::readSomeBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nMaxBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) 148 { 149 ::osl::MutexGuard aGuard( m_aMutex ); 150 if ( !m_xInputStream.is() ) 151 throw io::NotConnectedException(); 152 153 return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead ); 154 } 155 156 void SAL_CALL SequenceInputStreamService::skipBytes( ::sal_Int32 nBytesToSkip ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) 157 { 158 ::osl::MutexGuard aGuard( m_aMutex ); 159 if ( !m_xInputStream.is() ) 160 throw io::NotConnectedException(); 161 162 return m_xInputStream->skipBytes( nBytesToSkip ); 163 } 164 165 ::sal_Int32 SAL_CALL SequenceInputStreamService::available() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ) 166 { 167 ::osl::MutexGuard aGuard( m_aMutex ); 168 if ( !m_xInputStream.is() ) 169 throw io::NotConnectedException(); 170 171 return m_xInputStream->available(); 172 } 173 174 void SAL_CALL SequenceInputStreamService::closeInput() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ) 175 { 176 ::osl::MutexGuard aGuard( m_aMutex ); 177 if ( !m_xInputStream.is() ) 178 throw io::NotConnectedException(); 179 180 m_xInputStream->closeInput(); 181 m_xInputStream = uno::Reference< io::XInputStream >(); 182 m_xSeekable = uno::Reference< io::XSeekable >(); 183 } 184 185 // ::com::sun::star::io::XSeekable: 186 void SAL_CALL SequenceInputStreamService::seek( ::sal_Int64 location ) throw ( uno::RuntimeException, lang::IllegalArgumentException, io::IOException ) 187 { 188 ::osl::MutexGuard aGuard( m_aMutex ); 189 if ( !m_xSeekable.is() ) 190 throw io::NotConnectedException(); 191 192 m_xSeekable->seek( location ); 193 } 194 195 ::sal_Int64 SAL_CALL SequenceInputStreamService::getPosition() throw ( uno::RuntimeException, io::IOException ) 196 { 197 ::osl::MutexGuard aGuard( m_aMutex ); 198 if ( !m_xSeekable.is() ) 199 throw io::NotConnectedException(); 200 201 return m_xSeekable->getPosition(); 202 } 203 204 ::sal_Int64 SAL_CALL SequenceInputStreamService::getLength() throw ( uno::RuntimeException, io::IOException ) 205 { 206 ::osl::MutexGuard aGuard( m_aMutex ); 207 if ( !m_xSeekable.is() ) 208 throw io::NotConnectedException(); 209 210 return m_xSeekable->getLength(); 211 } 212 213 // ::com::sun::star::lang::XInitialization: 214 void SAL_CALL SequenceInputStreamService::initialize( const uno::Sequence< ::com::sun::star::uno::Any > & aArguments ) throw ( uno::RuntimeException, uno::Exception ) 215 { 216 ::osl::MutexGuard aGuard( m_aMutex ); 217 if ( m_bInitialized ) 218 throw frame::DoubleInitializationException(); 219 220 if ( aArguments.getLength() != 1 ) 221 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong number of arguments!\n" ), 222 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 223 1 ); 224 225 uno::Sequence< sal_Int8 > aSeq; 226 if ( aArguments[0] >>= aSeq ) 227 { 228 uno::Reference< io::XInputStream > xInputStream( 229 static_cast< ::cppu::OWeakObject* >( new ::comphelper::SequenceInputStream( aSeq ) ), 230 uno::UNO_QUERY_THROW ); 231 uno::Reference< io::XSeekable > xSeekable( xInputStream, uno::UNO_QUERY_THROW ); 232 m_xInputStream = xInputStream; 233 m_xSeekable = xSeekable; 234 m_bInitialized = sal_True; 235 } 236 else 237 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Unexpected type of argument!\n" ), 238 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 239 1 ); 240 } 241 242 } // anonymous namespace 243 244 void createRegistryInfo_SequenceInputStream() 245 { 246 static ::comphelper::module::OAutoRegistration< SequenceInputStreamService > aAutoRegistration; 247 } 248