bump product version to 5.0.4.1
[LibreOffice.git] / sot / source / unoolestorage / xolesimplestorage.cxx
blobfd4b822e9643d2c4ab43f04d463cba9f2b80cf4c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/lang/DisposedException.hpp>
21 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 #include <com/sun/star/io/XStream.hpp>
23 #include <com/sun/star/io/XInputStream.hpp>
24 #include <com/sun/star/io/XSeekable.hpp>
25 #include <com/sun/star/io/XTruncate.hpp>
26 #include <com/sun/star/io/TempFile.hpp>
28 #include <comphelper/processfactory.hxx>
29 #include <comphelper/storagehelper.hxx>
31 #include <unotools/ucbstreamhelper.hxx>
33 #include <cppuhelper/exc_hlp.hxx>
34 #include <cppuhelper/supportsservice.hxx>
36 #include <sot/storinfo.hxx>
38 #include "xolesimplestorage.hxx"
41 using namespace ::com::sun::star;
43 const sal_Int32 nBytesCount = 32000;
47 OLESimpleStorage::OLESimpleStorage( uno::Reference< lang::XMultiServiceFactory > xFactory )
48 : m_bDisposed( false )
49 , m_pStream( NULL )
50 , m_pStorage( NULL )
51 , m_pListenersContainer( NULL )
52 , m_xFactory( xFactory )
53 , m_bNoTemporaryCopy( false )
55 OSL_ENSURE( m_xFactory.is(), "No factory is provided on creation!\n" );
56 if ( !m_xFactory.is() )
57 throw uno::RuntimeException();
61 OLESimpleStorage::~OLESimpleStorage()
63 try {
64 m_refCount++;
65 dispose();
66 } catch( uno::Exception& )
69 if ( m_pListenersContainer )
71 delete m_pListenersContainer;
72 m_pListenersContainer = NULL;
77 uno::Sequence< OUString > SAL_CALL OLESimpleStorage::impl_staticGetSupportedServiceNames()
79 uno::Sequence< OUString > aRet(1);
80 aRet[0] = "com.sun.star.embed.OLESimpleStorage";
81 return aRet;
85 OUString SAL_CALL OLESimpleStorage::impl_staticGetImplementationName()
87 return OUString("com.sun.star.comp.embed.OLESimpleStorage");
91 uno::Reference< uno::XInterface > SAL_CALL OLESimpleStorage::impl_staticCreateSelfInstance(
92 const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
94 return uno::Reference< uno::XInterface >( *new OLESimpleStorage( xServiceManager ) );
98 void OLESimpleStorage::UpdateOriginal_Impl()
100 if ( !m_bNoTemporaryCopy )
102 uno::Reference< io::XSeekable > xSeek( m_xStream, uno::UNO_QUERY_THROW );
103 xSeek->seek( 0 );
105 uno::Reference< io::XSeekable > xTempSeek( m_xTempStream, uno::UNO_QUERY_THROW );
106 sal_Int64 nPos = xTempSeek->getPosition();
107 xTempSeek->seek( 0 );
109 uno::Reference< io::XInputStream > xTempInp = m_xTempStream->getInputStream();
110 uno::Reference< io::XOutputStream > xOutputStream = m_xStream->getOutputStream();
111 if ( !xTempInp.is() || !xOutputStream.is() )
112 throw uno::RuntimeException();
114 uno::Reference< io::XTruncate > xTrunc( xOutputStream, uno::UNO_QUERY_THROW );
115 xTrunc->truncate();
117 ::comphelper::OStorageHelper::CopyInputToOutput( xTempInp, xOutputStream );
118 xOutputStream->flush();
119 xTempSeek->seek( nPos );
124 void OLESimpleStorage::InsertInputStreamToStorage_Impl( BaseStorage* pStorage, const OUString & aName, const uno::Reference< io::XInputStream >& xInputStream )
125 throw ( uno::Exception )
127 if ( !pStorage || aName.isEmpty() || !xInputStream.is() )
128 throw uno::RuntimeException();
130 if ( pStorage->IsContained( aName ) )
131 throw container::ElementExistException(); // TODO:
133 BaseStorageStream* pNewStream = pStorage->OpenStream( aName );
134 if ( !pNewStream || pNewStream->GetError() || pStorage->GetError() )
136 if ( pNewStream )
137 DELETEZ( pNewStream );
138 pStorage->ResetError();
139 throw io::IOException(); // TODO
144 uno::Sequence< sal_Int8 > aData( nBytesCount );
145 sal_Int32 nRead = 0;
148 nRead = xInputStream->readBytes( aData, nBytesCount );
149 if ( nRead < nBytesCount )
150 aData.realloc( nRead );
152 sal_Int32 nWritten = pNewStream->Write( aData.getArray(), nRead );
153 if ( nWritten < nRead )
154 throw io::IOException();
155 } while( nRead == nBytesCount );
157 catch( uno::Exception& )
159 DELETEZ( pNewStream );
160 pStorage->Remove( aName );
162 throw;
165 DELETEZ( pNewStream );
169 void OLESimpleStorage::InsertNameAccessToStorage_Impl( BaseStorage* pStorage, const OUString & aName, const uno::Reference< container::XNameAccess >& xNameAccess )
170 throw ( uno::Exception )
172 if ( !pStorage || aName.isEmpty() || !xNameAccess.is() )
173 throw uno::RuntimeException();
175 if ( pStorage->IsContained( aName ) )
176 throw container::ElementExistException(); // TODO:
178 BaseStorage* pNewStorage = pStorage->OpenStorage( aName );
179 if ( !pNewStorage || pNewStorage->GetError() || pStorage->GetError() )
181 if ( pNewStorage )
182 DELETEZ( pNewStorage );
183 pStorage->ResetError();
184 throw io::IOException(); // TODO
189 uno::Sequence< OUString > aElements = xNameAccess->getElementNames();
190 for ( sal_Int32 nInd = 0; nInd < aElements.getLength(); nInd++ )
192 uno::Reference< io::XInputStream > xInputStream;
193 uno::Reference< container::XNameAccess > xSubNameAccess;
194 uno::Any aAny = xNameAccess->getByName( aElements[nInd] );
195 if ( aAny >>= xInputStream )
196 InsertInputStreamToStorage_Impl( pNewStorage, aElements[nInd], xInputStream );
197 else if ( aAny >>= xSubNameAccess )
198 InsertNameAccessToStorage_Impl( pNewStorage, aElements[nInd], xSubNameAccess );
201 catch( uno::Exception& )
203 DELETEZ( pNewStorage );
204 pStorage->Remove( aName );
206 throw;
209 DELETEZ( pNewStorage );
213 // XInitialization
216 void SAL_CALL OLESimpleStorage::initialize( const uno::Sequence< uno::Any >& aArguments )
217 throw ( uno::Exception,
218 uno::RuntimeException, std::exception)
220 if ( m_pStream || m_pStorage )
221 throw io::IOException(); // TODO: already initilized
223 sal_Int32 nArgNum = aArguments.getLength();
224 OSL_ENSURE( nArgNum >= 1 && nArgNum <= 2, "Wrong parameter number" );
226 if ( nArgNum < 1 || nArgNum > 2 )
227 throw lang::IllegalArgumentException(); // TODO:
229 uno::Reference< io::XStream > xStream;
230 uno::Reference< io::XInputStream > xInputStream;
231 if ( !( aArguments[0] >>= xStream ) && !( aArguments[0] >>= xInputStream ) )
232 throw lang::IllegalArgumentException(); // TODO:
234 if ( nArgNum == 2 )
236 if ( !( aArguments[1] >>= m_bNoTemporaryCopy ) )
237 throw lang::IllegalArgumentException(); // TODO:
240 if ( m_bNoTemporaryCopy )
242 // TODO: ???
243 // If the temporary stream is not created, the original stream must be wrapped
244 // since SvStream wrapper closes the stream is owns
245 if ( xInputStream.is() )
247 // the stream must be seekable for direct access
248 uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
249 m_pStream = ::utl::UcbStreamHelper::CreateStream( xInputStream, false );
251 else if ( xStream.is() )
253 // the stream must be seekable for direct access
254 uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
255 m_pStream = ::utl::UcbStreamHelper::CreateStream( xStream, false );
257 else
258 throw lang::IllegalArgumentException(); // TODO:
260 else
262 uno::Reference < io::XStream > xTempFile(
263 io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
264 uno::UNO_QUERY_THROW );
265 uno::Reference < io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
266 uno::Reference< io::XOutputStream > xTempOut = xTempFile->getOutputStream();
267 if ( !xTempOut.is() )
268 throw uno::RuntimeException();
270 if ( xInputStream.is() )
274 uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
275 xSeek->seek( 0 );
277 catch( uno::Exception& )
280 ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, xTempOut );
281 xTempOut->closeOutput();
282 xTempSeek->seek( 0 );
283 uno::Reference< io::XInputStream > xTempInput = xTempFile->getInputStream();
284 m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempInput, false );
286 else if ( xStream.is() )
288 // not sure that the storage flashes the stream on commit
289 m_xStream = xStream;
290 m_xTempStream = xTempFile;
292 uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
293 xSeek->seek( 0 );
294 uno::Reference< io::XInputStream > xInpStream = xStream->getInputStream();
295 if ( !xInpStream.is() || !xStream->getOutputStream().is() )
296 throw uno::RuntimeException();
298 ::comphelper::OStorageHelper::CopyInputToOutput( xInpStream, xTempOut );
299 xTempOut->flush();
300 xTempSeek->seek( 0 );
302 m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, false );
304 else
305 throw lang::IllegalArgumentException(); // TODO:
308 if ( !m_pStream || m_pStream->GetError() )
309 throw io::IOException(); // TODO
311 m_pStorage = new Storage( *m_pStream, false );
316 // XNameContainer
320 void SAL_CALL OLESimpleStorage::insertByName( const OUString& aName, const uno::Any& aElement )
321 throw ( lang::IllegalArgumentException,
322 container::ElementExistException,
323 lang::WrappedTargetException,
324 uno::RuntimeException, std::exception)
326 ::osl::MutexGuard aGuard( m_aMutex );
328 if ( m_bDisposed )
329 throw lang::DisposedException();
331 if ( !m_pStorage )
332 throw uno::RuntimeException();
334 uno::Reference< io::XStream > xStream;
335 uno::Reference< io::XInputStream > xInputStream;
336 uno::Reference< container::XNameAccess > xNameAccess;
340 if ( !m_bNoTemporaryCopy && !m_xStream.is() )
341 throw io::IOException(); // TODO
343 if ( aElement >>= xStream )
344 xInputStream = xStream->getInputStream();
345 else if ( !( aElement >>= xInputStream ) && !( aElement >>= xNameAccess ) )
346 throw lang::IllegalArgumentException(); // TODO:
348 if ( xInputStream.is() )
349 InsertInputStreamToStorage_Impl( m_pStorage, aName, xInputStream );
350 else if ( xNameAccess.is() )
351 InsertNameAccessToStorage_Impl( m_pStorage, aName, xNameAccess );
352 else
353 throw uno::RuntimeException();
355 catch( uno::RuntimeException& )
357 throw;
359 catch( container::ElementExistException& )
361 throw;
363 catch( const uno::Exception& e )
365 throw lang::WrappedTargetException("Insert has failed!",
366 uno::Reference< uno::XInterface >(),
367 uno::makeAny( e ) );
372 void SAL_CALL OLESimpleStorage::removeByName( const OUString& aName )
373 throw ( container::NoSuchElementException,
374 lang::WrappedTargetException,
375 uno::RuntimeException, std::exception)
377 ::osl::MutexGuard aGuard( m_aMutex );
379 if ( m_bDisposed )
380 throw lang::DisposedException();
382 if ( !m_pStorage )
383 throw uno::RuntimeException();
385 if ( !m_bNoTemporaryCopy && !m_xStream.is() )
386 throw lang::WrappedTargetException(); // io::IOException(); // TODO
388 if ( !m_pStorage->IsContained( aName ) )
389 throw container::NoSuchElementException(); // TODO:
391 m_pStorage->Remove( aName );
393 if ( m_pStorage->GetError() )
395 m_pStorage->ResetError();
396 throw lang::WrappedTargetException(); // io::IOException(); // TODO
401 void SAL_CALL OLESimpleStorage::replaceByName( const OUString& aName, const uno::Any& aElement )
402 throw ( lang::IllegalArgumentException,
403 container::NoSuchElementException,
404 lang::WrappedTargetException,
405 uno::RuntimeException, std::exception)
407 ::osl::MutexGuard aGuard( m_aMutex );
409 if ( m_bDisposed )
410 throw lang::DisposedException();
412 removeByName( aName );
416 insertByName( aName, aElement );
418 catch( container::ElementExistException& )
420 uno::Any aCaught( ::cppu::getCaughtException() );
422 throw lang::WrappedTargetException("Can't copy raw stream",
423 uno::Reference< uno::XInterface >(),
424 aCaught );
429 uno::Any SAL_CALL OLESimpleStorage::getByName( const OUString& aName )
430 throw ( container::NoSuchElementException,
431 lang::WrappedTargetException,
432 uno::RuntimeException, std::exception )
434 ::osl::MutexGuard aGuard( m_aMutex );
436 if ( m_bDisposed )
437 throw lang::DisposedException();
439 if ( !m_pStorage )
440 throw uno::RuntimeException();
442 if ( !m_pStorage->IsContained( aName ) )
443 throw container::NoSuchElementException(); // TODO:
445 uno::Any aResult;
447 uno::Reference< io::XStream > xTempFile(
448 io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
449 uno::UNO_QUERY );
450 uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );
451 uno::Reference< io::XOutputStream > xOutputStream = xTempFile->getOutputStream();
452 uno::Reference< io::XInputStream > xInputStream = xTempFile->getInputStream();
453 if ( !xOutputStream.is() || !xInputStream.is() )
454 throw uno::RuntimeException();
456 if ( m_pStorage->IsStorage( aName ) )
458 BaseStorage* pStrg = m_pStorage->OpenStorage( aName );
459 m_pStorage->ResetError();
460 if ( !pStrg )
461 throw lang::WrappedTargetException(); // io::IOException(); // TODO
463 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, false ); // do not close the original stream
464 if ( !pStream )
465 throw uno::RuntimeException();
467 BaseStorage* pNewStor = new Storage( *pStream, false );
468 bool bSuccess = ( pStrg->CopyTo( pNewStor ) && pNewStor->Commit() &&
469 !pNewStor->GetError() && !pStrg->GetError() );
471 DELETEZ( pNewStor );
472 DELETEZ( pStrg );
473 DELETEZ( pStream );
475 if ( !bSuccess )
476 throw uno::RuntimeException();
478 uno::Sequence< uno::Any > aArgs( 2 );
479 aArgs[0] <<= xInputStream; // allow readonly access only
480 aArgs[1] <<= true; // do not create copy
482 uno::Reference< container::XNameContainer > xResultNameContainer(
483 m_xFactory->createInstanceWithArguments(
484 OUString("com.sun.star.embed.OLESimpleStorage"),
485 aArgs ),
486 uno::UNO_QUERY_THROW );
488 aResult <<= xResultNameContainer;
490 else
492 BaseStorageStream* pStream = m_pStorage->OpenStream( aName, StreamMode::READ | StreamMode::SHARE_DENYALL | StreamMode::NOCREATE );
495 if ( !pStream || pStream->GetError() || m_pStorage->GetError() )
497 m_pStorage->ResetError();
498 DELETEZ( pStream );
499 throw io::IOException(); // TODO
502 uno::Sequence< sal_Int8 > aData( nBytesCount );
503 sal_Int32 nSize = nBytesCount;
504 sal_Int32 nRead = 0;
505 while( 0 != ( nRead = pStream->Read( aData.getArray(), nSize ) ) )
507 if ( nRead < nSize )
509 nSize = nRead;
510 aData.realloc( nSize );
513 xOutputStream->writeBytes( aData );
516 if ( pStream->GetError() )
517 throw io::IOException(); // TODO
519 xOutputStream->closeOutput();
520 xSeekable->seek( 0 );
522 catch (const uno::RuntimeException&)
524 DELETEZ( pStream );
525 throw;
527 catch (const uno::Exception&)
529 DELETEZ( pStream );
530 throw lang::WrappedTargetException(); // TODO:
533 DELETEZ( pStream );
535 aResult <<= xInputStream;
538 return aResult;
542 uno::Sequence< OUString > SAL_CALL OLESimpleStorage::getElementNames()
543 throw ( uno::RuntimeException, std::exception )
545 ::osl::MutexGuard aGuard( m_aMutex );
547 if ( m_bDisposed )
548 throw lang::DisposedException();
550 if ( !m_pStorage )
551 throw uno::RuntimeException();
553 SvStorageInfoList aList;
554 m_pStorage->FillInfoList( &aList );
556 if ( m_pStorage->GetError() )
558 m_pStorage->ResetError();
559 throw uno::RuntimeException(); // TODO:
562 uno::Sequence< OUString > aSeq( aList.size() );
563 for ( sal_uInt32 nInd = 0; nInd < aList.size(); nInd++ )
564 aSeq[nInd] = aList[nInd].GetName();
566 return aSeq;
570 sal_Bool SAL_CALL OLESimpleStorage::hasByName( const OUString& aName )
571 throw ( uno::RuntimeException, std::exception )
573 ::osl::MutexGuard aGuard( m_aMutex );
575 if ( m_bDisposed )
576 throw lang::DisposedException();
578 if ( !m_pStorage )
579 throw uno::RuntimeException();
581 bool bResult = m_pStorage->IsContained( aName );
583 if ( m_pStorage->GetError() )
585 m_pStorage->ResetError();
586 throw uno::RuntimeException(); // TODO:
589 return bResult ? sal_True : sal_False;
593 uno::Type SAL_CALL OLESimpleStorage::getElementType()
594 throw ( uno::RuntimeException, std::exception )
596 ::osl::MutexGuard aGuard( m_aMutex );
598 if ( m_bDisposed )
599 throw lang::DisposedException();
601 return cppu::UnoType<io::XInputStream>::get();
605 sal_Bool SAL_CALL OLESimpleStorage::hasElements()
606 throw ( uno::RuntimeException, std::exception )
608 ::osl::MutexGuard aGuard( m_aMutex );
610 if ( m_bDisposed )
611 throw lang::DisposedException();
613 if ( !m_pStorage )
614 throw uno::RuntimeException();
616 SvStorageInfoList aList;
617 m_pStorage->FillInfoList( &aList );
619 if ( m_pStorage->GetError() )
621 m_pStorage->ResetError();
622 throw uno::RuntimeException(); // TODO:
625 return aList.size() != 0 ? sal_True : sal_False;
629 // XComponent
633 void SAL_CALL OLESimpleStorage::dispose()
634 throw ( uno::RuntimeException, std::exception )
636 ::osl::MutexGuard aGuard( m_aMutex );
638 if ( m_bDisposed )
639 throw lang::DisposedException();
641 if ( m_pListenersContainer )
643 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
644 m_pListenersContainer->disposeAndClear( aSource );
647 DELETEZ( m_pStorage );
648 DELETEZ( m_pStream );
650 m_xStream = uno::Reference< io::XStream >();
651 m_xTempStream = uno::Reference< io::XStream >();
653 m_bDisposed = true;
657 void SAL_CALL OLESimpleStorage::addEventListener(
658 const uno::Reference< lang::XEventListener >& xListener )
659 throw ( uno::RuntimeException, std::exception )
661 ::osl::MutexGuard aGuard( m_aMutex );
663 if ( m_bDisposed )
664 throw lang::DisposedException();
666 if ( !m_pListenersContainer )
667 m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
669 m_pListenersContainer->addInterface( xListener );
673 void SAL_CALL OLESimpleStorage::removeEventListener(
674 const uno::Reference< lang::XEventListener >& xListener )
675 throw ( uno::RuntimeException, std::exception )
677 ::osl::MutexGuard aGuard( m_aMutex );
679 if ( m_bDisposed )
680 throw lang::DisposedException();
682 if ( m_pListenersContainer )
683 m_pListenersContainer->removeInterface( xListener );
687 // XTransactedObject
691 void SAL_CALL OLESimpleStorage::commit()
692 throw ( ::com::sun::star::io::IOException,
693 ::com::sun::star::lang::WrappedTargetException,
694 ::com::sun::star::uno::RuntimeException, std::exception )
696 ::osl::MutexGuard aGuard( m_aMutex );
698 if ( m_bDisposed )
699 throw lang::DisposedException();
701 if ( !m_pStorage )
702 throw uno::RuntimeException();
704 if ( !m_bNoTemporaryCopy && !m_xStream.is() )
705 throw io::IOException(); // TODO
707 if ( !m_pStorage->Commit() || m_pStorage->GetError() )
709 m_pStorage->ResetError();
710 throw io::IOException(); // TODO
713 UpdateOriginal_Impl();
717 void SAL_CALL OLESimpleStorage::revert()
718 throw ( ::com::sun::star::io::IOException,
719 ::com::sun::star::lang::WrappedTargetException,
720 ::com::sun::star::uno::RuntimeException, std::exception )
722 ::osl::MutexGuard aGuard( m_aMutex );
724 if ( m_bDisposed )
725 throw lang::DisposedException();
727 if ( !m_pStorage )
728 throw uno::RuntimeException();
730 if ( !m_bNoTemporaryCopy && !m_xStream.is() )
731 throw io::IOException(); // TODO
733 if ( !m_pStorage->Revert() || m_pStorage->GetError() )
735 m_pStorage->ResetError();
736 throw io::IOException(); // TODO
739 UpdateOriginal_Impl();
743 // XClassifiedObject
746 uno::Sequence< sal_Int8 > SAL_CALL OLESimpleStorage::getClassID()
747 throw ( uno::RuntimeException, std::exception )
749 ::osl::MutexGuard aGuard( m_aMutex );
751 if ( m_bDisposed )
752 throw lang::DisposedException();
754 if ( !m_pStorage )
755 throw uno::RuntimeException();
757 return m_pStorage->GetClassName().GetByteSequence();
760 OUString SAL_CALL OLESimpleStorage::getClassName()
761 throw ( uno::RuntimeException, std::exception )
763 return OUString();
766 void SAL_CALL OLESimpleStorage::setClassInfo( const uno::Sequence< sal_Int8 >& /*aClassID*/,
767 const OUString& /*sClassName*/ )
768 throw ( lang::NoSupportException,
769 uno::RuntimeException, std::exception )
771 throw lang::NoSupportException();
774 // XServiceInfo
775 OUString SAL_CALL OLESimpleStorage::getImplementationName()
776 throw ( uno::RuntimeException, std::exception )
778 return impl_staticGetImplementationName();
781 sal_Bool SAL_CALL OLESimpleStorage::supportsService( const OUString& ServiceName )
782 throw ( uno::RuntimeException, std::exception )
784 return cppu::supportsService(this, ServiceName);
787 uno::Sequence< OUString > SAL_CALL OLESimpleStorage::getSupportedServiceNames()
788 throw ( uno::RuntimeException, std::exception )
790 return impl_staticGetSupportedServiceNames();
794 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */