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_sot.hxx"
26 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <com/sun/star/io/XStream.hpp>
28 #include <com/sun/star/io/XInputStream.hpp>
29 #include <com/sun/star/io/XSeekable.hpp>
30 #include <com/sun/star/io/XTruncate.hpp>
31 
32 #include <comphelper/storagehelper.hxx>
33 
34 #include <unotools/ucbstreamhelper.hxx>
35 
36 #include <cppuhelper/exc_hlp.hxx>
37 
38 #include <sot/storinfo.hxx>
39 
40 #include "xolesimplestorage.hxx"
41 
42 
43 using namespace ::com::sun::star;
44 
45 const sal_Int32 nBytesCount = 32000;
46 
47 
48 // --------------------------------------------------------------------------------
OLESimpleStorage(uno::Reference<lang::XMultiServiceFactory> xFactory)49 OLESimpleStorage::OLESimpleStorage( uno::Reference< lang::XMultiServiceFactory > xFactory )
50 : m_bDisposed( sal_False )
51 , m_pStream( NULL )
52 , m_pStorage( NULL )
53 , m_pListenersContainer( NULL )
54 , m_xFactory( xFactory )
55 , m_bNoTemporaryCopy( sal_False )
56 {
57 	OSL_ENSURE( m_xFactory.is(), "No factory is provided on creation!\n" );
58 	if ( !m_xFactory.is() )
59 		throw uno::RuntimeException();
60 }
61 
62 // --------------------------------------------------------------------------------
~OLESimpleStorage()63 OLESimpleStorage::~OLESimpleStorage()
64 {
65 	try {
66 		m_refCount++;
67 		dispose();
68 	} catch( uno::Exception& )
69 	{}
70 
71 	if ( m_pListenersContainer )
72 	{
73 		delete m_pListenersContainer;
74 		m_pListenersContainer = NULL;
75 	}
76 }
77 
78 //-------------------------------------------------------------------------
impl_staticGetSupportedServiceNames()79 uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::impl_staticGetSupportedServiceNames()
80 {
81     uno::Sequence< ::rtl::OUString > aRet(1);
82     aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.OLESimpleStorage");
83     return aRet;
84 }
85 
86 //-------------------------------------------------------------------------
impl_staticGetImplementationName()87 ::rtl::OUString SAL_CALL OLESimpleStorage::impl_staticGetImplementationName()
88 {
89     return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.OLESimpleStorage");
90 }
91 
92 //-------------------------------------------------------------------------
impl_staticCreateSelfInstance(const uno::Reference<lang::XMultiServiceFactory> & xServiceManager)93 uno::Reference< uno::XInterface > SAL_CALL OLESimpleStorage::impl_staticCreateSelfInstance(
94 			const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
95 {
96 	return uno::Reference< uno::XInterface >( *new OLESimpleStorage( xServiceManager ) );
97 }
98 
99 //-------------------------------------------------------------------------
UpdateOriginal_Impl()100 void OLESimpleStorage::UpdateOriginal_Impl()
101 {
102 	if ( !m_bNoTemporaryCopy )
103 	{
104 		uno::Reference< io::XSeekable > xSeek( m_xStream, uno::UNO_QUERY_THROW );
105 		xSeek->seek( 0 );
106 
107 		uno::Reference< io::XSeekable > xTempSeek( m_xTempStream, uno::UNO_QUERY_THROW );
108 		sal_Int64 nPos = xTempSeek->getPosition();
109 		xTempSeek->seek( 0 );
110 
111 		uno::Reference< io::XInputStream > xTempInp = m_xTempStream->getInputStream();
112 		uno::Reference< io::XOutputStream > xOutputStream = m_xStream->getOutputStream();
113 		if ( !xTempInp.is() || !xOutputStream.is() )
114 			throw uno::RuntimeException();
115 
116 		uno::Reference< io::XTruncate > xTrunc( xOutputStream, uno::UNO_QUERY_THROW );
117 		xTrunc->truncate();
118 
119 		::comphelper::OStorageHelper::CopyInputToOutput( xTempInp, xOutputStream );
120 		xOutputStream->flush();
121 		xTempSeek->seek( nPos );
122 	}
123 }
124 
125 //-------------------------------------------------------------------------
InsertInputStreamToStorage_Impl(BaseStorage * pStorage,::rtl::OUString aName,const uno::Reference<io::XInputStream> & xInputStream)126 void OLESimpleStorage::InsertInputStreamToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const uno::Reference< io::XInputStream >& xInputStream )
127 	throw ( uno::Exception )
128 {
129 	if ( !pStorage || !aName.getLength() || !xInputStream.is() )
130 		throw uno::RuntimeException();
131 
132 	if ( pStorage->IsContained( aName ) )
133 		throw container::ElementExistException(); // TODO:
134 
135 	BaseStorageStream* pNewStream = pStorage->OpenStream( aName );
136 	if ( !pNewStream || pNewStream->GetError() || pStorage->GetError() )
137 	{
138 		if ( pNewStream )
139 			DELETEZ( pNewStream );
140 		pStorage->ResetError();
141 		throw io::IOException(); // TODO
142 	}
143 
144 	try
145 	{
146 		uno::Sequence< sal_Int8 > aData( nBytesCount );
147 		sal_Int32 nRead = 0;
148 		do
149 		{
150 			nRead = xInputStream->readBytes( aData, nBytesCount );
151 			if ( nRead < nBytesCount )
152 				aData.realloc( nRead );
153 
154 			sal_Int32 nWritten = pNewStream->Write( aData.getArray(), nRead );
155 			if ( nWritten < nRead )
156 				throw io::IOException();
157 		} while( nRead == nBytesCount );
158 	}
159 	catch( uno::Exception& )
160 	{
161 		DELETEZ( pNewStream );
162 		pStorage->Remove( aName );
163 
164 		throw;
165 	}
166 
167 	DELETEZ( pNewStream );
168 }
169 
170 //-------------------------------------------------------------------------
InsertNameAccessToStorage_Impl(BaseStorage * pStorage,::rtl::OUString aName,const uno::Reference<container::XNameAccess> & xNameAccess)171 void OLESimpleStorage::InsertNameAccessToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const uno::Reference< container::XNameAccess >& xNameAccess )
172 	throw ( uno::Exception )
173 {
174 	if ( !pStorage || !aName.getLength() || !xNameAccess.is() )
175 		throw uno::RuntimeException();
176 
177 	if ( pStorage->IsContained( aName ) )
178 		throw container::ElementExistException(); // TODO:
179 
180 	BaseStorage* pNewStorage = pStorage->OpenStorage( aName );
181 	if ( !pNewStorage || pNewStorage->GetError() || pStorage->GetError() )
182 	{
183 		if ( pNewStorage )
184 			DELETEZ( pNewStorage );
185 		pStorage->ResetError();
186 		throw io::IOException(); // TODO
187 	}
188 
189 	try
190 	{
191 		uno::Sequence< ::rtl::OUString > aElements = xNameAccess->getElementNames();
192 		for ( sal_Int32 nInd = 0; nInd < aElements.getLength(); nInd++ )
193 		{
194 			uno::Reference< io::XInputStream > xInputStream;
195 			uno::Reference< container::XNameAccess > xSubNameAccess;
196 			uno::Any aAny = xNameAccess->getByName( aElements[nInd] );
197 			if ( aAny >>= xInputStream )
198 				InsertInputStreamToStorage_Impl( pNewStorage, aElements[nInd], xInputStream );
199 			else if ( aAny >>= xSubNameAccess )
200 				InsertNameAccessToStorage_Impl( pNewStorage, aElements[nInd], xSubNameAccess );
201 		}
202 	}
203 	catch( uno::Exception& )
204 	{
205 		DELETEZ( pNewStorage );
206 		pStorage->Remove( aName );
207 
208 		throw;
209 	}
210 
211 	DELETEZ( pNewStorage );
212 }
213 
214 //____________________________________________________________________________________________________
215 //	XInitialization
216 //____________________________________________________________________________________________________
217 
initialize(const uno::Sequence<uno::Any> & aArguments)218 void SAL_CALL OLESimpleStorage::initialize( const uno::Sequence< uno::Any >& aArguments )
219 		throw ( uno::Exception,
220 				uno::RuntimeException)
221 {
222 	if ( m_pStream || m_pStorage )
223 		throw io::IOException(); // TODO: already initilized
224 
225 	sal_Int32 nArgNum = aArguments.getLength();
226 	OSL_ENSURE( nArgNum >= 1 && nArgNum <= 2, "Wrong parameter number" );
227 
228 	if ( nArgNum < 1 || nArgNum > 2 )
229 		throw lang::IllegalArgumentException(); // TODO:
230 
231 	uno::Reference< io::XStream > xStream;
232 	uno::Reference< io::XInputStream > xInputStream;
233 	if ( !( aArguments[0] >>= xStream ) && !( aArguments[0] >>= xInputStream ) )
234 		throw lang::IllegalArgumentException(); // TODO:
235 
236 	if ( nArgNum == 2 )
237 	{
238 		if ( !( aArguments[1] >>= m_bNoTemporaryCopy ) )
239 			throw lang::IllegalArgumentException(); // TODO:
240 	}
241 
242 	if ( m_bNoTemporaryCopy )
243 	{
244 		// TODO: ???
245 		// If the temporary stream is not created, the original stream must be wrapped
246 		// since SvStream wrapper closes the stream is owns
247 		if ( xInputStream.is() )
248 		{
249 			// the stream must be seekable for direct access
250 			uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
251 			m_pStream = ::utl::UcbStreamHelper::CreateStream( xInputStream, sal_False );
252 		}
253 		else if ( xStream.is() )
254 		{
255 			// the stream must be seekable for direct access
256 			uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
257 			m_pStream = ::utl::UcbStreamHelper::CreateStream( xStream, sal_False );
258 		}
259 		else
260 			throw lang::IllegalArgumentException(); // TODO:
261 	}
262 	else
263 	{
264 		uno::Reference < io::XStream > xTempFile(
265 				m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
266 				uno::UNO_QUERY_THROW );
267 		uno::Reference < io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
268 		uno::Reference< io::XOutputStream > xTempOut = xTempFile->getOutputStream();
269 		if ( !xTempOut.is() )
270 			throw uno::RuntimeException();
271 
272 		if ( xInputStream.is() )
273 		{
274 			try
275 			{
276 				uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
277 				xSeek->seek( 0 );
278 			}
279 			catch( uno::Exception& )
280 			{}
281 
282 			::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, xTempOut );
283 			xTempOut->closeOutput();
284 			xTempSeek->seek( 0 );
285 			uno::Reference< io::XInputStream > xTempInput = xTempFile->getInputStream();
286 			m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempInput, sal_False );
287 		}
288 		else if ( xStream.is() )
289 		{
290 			// not sure that the storage flashes the stream on commit
291 			m_xStream = xStream;
292 			m_xTempStream = xTempFile;
293 
294 			uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
295 			xSeek->seek( 0 );
296 			uno::Reference< io::XInputStream > xInpStream = xStream->getInputStream();
297 			if ( !xInpStream.is() || !xStream->getOutputStream().is() )
298 				throw uno::RuntimeException();
299 
300 			::comphelper::OStorageHelper::CopyInputToOutput( xInpStream, xTempOut );
301 			xTempOut->flush();
302 			xTempSeek->seek( 0 );
303 
304 			m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, sal_False );
305 		}
306 		else
307 			throw lang::IllegalArgumentException(); // TODO:
308 	}
309 
310 	if ( !m_pStream || m_pStream->GetError() )
311 		throw io::IOException(); // TODO
312 
313 	m_pStorage = new Storage( *m_pStream, sal_False );
314 }
315 
316 
317 //____________________________________________________________________________________________________
318 //	XNameContainer
319 //____________________________________________________________________________________________________
320 
321 // --------------------------------------------------------------------------------
insertByName(const::rtl::OUString & aName,const uno::Any & aElement)322 void SAL_CALL OLESimpleStorage::insertByName( const ::rtl::OUString& aName, const uno::Any& aElement )
323 		throw ( lang::IllegalArgumentException,
324 				container::ElementExistException,
325 				lang::WrappedTargetException,
326 				uno::RuntimeException)
327 {
328 	::osl::MutexGuard aGuard( m_aMutex );
329 
330 	if ( m_bDisposed )
331 		throw lang::DisposedException();
332 
333 	  if ( !m_pStorage )
334 		throw uno::RuntimeException();
335 
336 	uno::Reference< io::XStream > xStream;
337 	uno::Reference< io::XInputStream > xInputStream;
338 	uno::Reference< container::XNameAccess > xNameAccess;
339 
340 	try
341 	{
342 		if ( !m_bNoTemporaryCopy && !m_xStream.is() )
343 			throw io::IOException(); // TODO
344 
345 		if ( aElement >>= xStream )
346 			xInputStream = xStream->getInputStream();
347 		else if ( !( aElement >>= xInputStream ) && !( aElement >>= xNameAccess ) )
348 			throw lang::IllegalArgumentException(); // TODO:
349 
350 		if ( xInputStream.is() )
351 			InsertInputStreamToStorage_Impl( m_pStorage, aName, xInputStream );
352 		else if ( xNameAccess.is() )
353 			InsertNameAccessToStorage_Impl( m_pStorage, aName, xNameAccess );
354 		else
355 			throw uno::RuntimeException();
356 	}
357 	catch( uno::RuntimeException& )
358 	{
359 		throw;
360 	}
361 	catch( container::ElementExistException& )
362 	{
363 		throw;
364 	}
365 	catch( uno::Exception& e )
366 	{
367 		throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Insert has failed!" ) ),
368 											uno::Reference< uno::XInterface >(),
369 											uno::makeAny( e ) );
370 	}
371 }
372 
373 // --------------------------------------------------------------------------------
removeByName(const::rtl::OUString & aName)374 void SAL_CALL OLESimpleStorage::removeByName( const ::rtl::OUString& aName )
375 		throw ( container::NoSuchElementException,
376 				lang::WrappedTargetException,
377 				uno::RuntimeException)
378 {
379 	::osl::MutexGuard aGuard( m_aMutex );
380 
381 	if ( m_bDisposed )
382 		throw lang::DisposedException();
383 
384 	  if ( !m_pStorage )
385 		throw uno::RuntimeException();
386 
387 	if ( !m_bNoTemporaryCopy && !m_xStream.is() )
388 		throw lang::WrappedTargetException(); // io::IOException(); // TODO
389 
390 	if ( !m_pStorage->IsContained( aName ) )
391 		throw container::NoSuchElementException(); // TODO:
392 
393 	m_pStorage->Remove( aName );
394 
395 	if ( m_pStorage->GetError() )
396 	{
397 		m_pStorage->ResetError();
398 		throw lang::WrappedTargetException(); // io::IOException(); // TODO
399 	}
400 }
401 
402 // --------------------------------------------------------------------------------
replaceByName(const::rtl::OUString & aName,const uno::Any & aElement)403 void SAL_CALL OLESimpleStorage::replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement )
404 		throw ( lang::IllegalArgumentException,
405 				container::NoSuchElementException,
406 				lang::WrappedTargetException,
407 				uno::RuntimeException)
408 {
409 	::osl::MutexGuard aGuard( m_aMutex );
410 
411 	if ( m_bDisposed )
412 		throw lang::DisposedException();
413 
414 	removeByName( aName );
415 
416 	try
417 	{
418 		insertByName( aName, aElement );
419 	}
420 	catch( container::ElementExistException& )
421 	{
422 	   	uno::Any aCaught( ::cppu::getCaughtException() );
423 
424 		throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
425 											uno::Reference< uno::XInterface >(),
426 											aCaught );
427 	}
428 }
429 
430 // --------------------------------------------------------------------------------
getByName(const::rtl::OUString & aName)431 uno::Any SAL_CALL OLESimpleStorage::getByName( const ::rtl::OUString& aName )
432 		throw ( container::NoSuchElementException,
433 				lang::WrappedTargetException,
434 				uno::RuntimeException )
435 {
436 	::osl::MutexGuard aGuard( m_aMutex );
437 
438 	if ( m_bDisposed )
439 		throw lang::DisposedException();
440 
441 	  if ( !m_pStorage )
442 		throw uno::RuntimeException();
443 
444 	if ( !m_pStorage->IsContained( aName ) )
445 		throw container::NoSuchElementException(); // TODO:
446 
447 	uno::Any aResult;
448 
449 	uno::Reference< io::XStream > xTempFile(
450 		m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
451 		uno::UNO_QUERY );
452 	uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );
453 	uno::Reference< io::XOutputStream > xOutputStream = xTempFile->getOutputStream();
454 	uno::Reference< io::XInputStream > xInputStream = xTempFile->getInputStream();
455 	if ( !xOutputStream.is() || !xInputStream.is() )
456 		throw uno::RuntimeException();
457 
458 	if ( m_pStorage->IsStorage( aName ) )
459 	{
460 		BaseStorage* pStrg = m_pStorage->OpenStorage( aName );
461 		m_pStorage->ResetError();
462 		if ( !pStrg )
463 			throw io::IOException();
464 
465 		SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, sal_False ); // do not close the original stream
466 		if ( !pStream )
467 			throw uno::RuntimeException();
468 
469 		BaseStorage* pNewStor = new Storage( *pStream, sal_False );
470 		sal_Bool bSuccess =
471 			( pStrg->CopyTo( pNewStor ) && pNewStor->Commit() && !pNewStor->GetError() && !pStrg->GetError() );
472 
473 		DELETEZ( pNewStor );
474 		DELETEZ( pStrg );
475 		DELETEZ( pStream );
476 
477 		if ( !bSuccess )
478 			throw uno::RuntimeException();
479 
480 		uno::Sequence< uno::Any > aArgs( 2 );
481 		aArgs[0] <<= xInputStream; // allow readonly access only
482 		aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
483 
484 		uno::Reference< container::XNameContainer > xResultNameContainer(
485 			m_xFactory->createInstanceWithArguments(
486 					::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
487 					aArgs ),
488 			uno::UNO_QUERY_THROW );
489 
490 		aResult <<= xResultNameContainer;
491 	}
492 	else
493 	{
494 		BaseStorageStream* pStream = m_pStorage->OpenStream( aName, STREAM_READ | STREAM_SHARE_DENYALL | STREAM_NOCREATE );
495 		if ( !pStream || pStream->GetError() || m_pStorage->GetError() )
496 		{
497 			m_pStorage->ResetError();
498 			DELETEZ( pStream );
499 			throw io::IOException(); // TODO
500 		}
501 
502 		try
503 		{
504 			uno::Sequence< sal_Int8 > aData( nBytesCount );
505 			sal_Int32 nSize = nBytesCount;
506 			sal_Int32 nRead = 0;
507 			while( 0 != ( nRead = pStream->Read( aData.getArray(), nSize ) ) )
508 			{
509 				if ( nRead < nSize )
510 				{
511 					nSize = nRead;
512 					aData.realloc( nSize );
513 				}
514 
515 				xOutputStream->writeBytes( aData );
516 			}
517 
518 			if ( pStream->GetError() )
519 				throw io::IOException(); // TODO
520 
521 			xOutputStream->closeOutput();
522 			xSeekable->seek( 0 );
523 		}
524 		catch( uno::RuntimeException& )
525 		{
526 			DELETEZ( pStream );
527 			throw;
528 		}
529 		catch( uno::Exception& )
530 		{
531 			DELETEZ( pStream );
532 			throw lang::WrappedTargetException(); // TODO:
533 		}
534 
535 		DELETEZ( pStream );
536 
537 		aResult <<= xInputStream;
538 	}
539 
540 	return aResult;
541 }
542 
543 // --------------------------------------------------------------------------------
getElementNames()544 uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::getElementNames()
545 		throw ( uno::RuntimeException )
546 {
547 	::osl::MutexGuard aGuard( m_aMutex );
548 
549 	if ( m_bDisposed )
550 		throw lang::DisposedException();
551 
552 	  if ( !m_pStorage )
553 		throw uno::RuntimeException();
554 
555 	SvStorageInfoList aList;
556 	m_pStorage->FillInfoList( &aList );
557 
558 	if ( m_pStorage->GetError() )
559 	{
560 		m_pStorage->ResetError();
561 		throw uno::RuntimeException(); // TODO:
562 	}
563 
564 	uno::Sequence< ::rtl::OUString > aSeq( aList.Count() );
565 	for ( sal_uInt32 nInd = 0; nInd < aList.Count(); nInd++ )
566 		aSeq[nInd] = aList[nInd].GetName();
567 
568 	return aSeq;
569 }
570 
571 // --------------------------------------------------------------------------------
hasByName(const::rtl::OUString & aName)572 sal_Bool SAL_CALL OLESimpleStorage::hasByName( const ::rtl::OUString& aName )
573 		throw ( uno::RuntimeException )
574 {
575 	::osl::MutexGuard aGuard( m_aMutex );
576 
577 	if ( m_bDisposed )
578 		throw lang::DisposedException();
579 
580 	 if ( !m_pStorage )
581 		throw uno::RuntimeException();
582 
583 	sal_Bool bResult = m_pStorage->IsContained( aName );
584 
585 	if ( m_pStorage->GetError() )
586 	{
587 		m_pStorage->ResetError();
588 		throw uno::RuntimeException(); // TODO:
589 	}
590 
591 	return bResult;
592 }
593 
594 // --------------------------------------------------------------------------------
getElementType()595 uno::Type SAL_CALL OLESimpleStorage::getElementType()
596 		throw ( uno::RuntimeException )
597 {
598 	::osl::MutexGuard aGuard( m_aMutex );
599 
600 	if ( m_bDisposed )
601 		throw lang::DisposedException();
602 
603 	return getCppuType( (const uno::Reference< io::XInputStream >*)NULL );
604 }
605 
606 // --------------------------------------------------------------------------------
hasElements()607 sal_Bool SAL_CALL OLESimpleStorage::hasElements()
608 		throw ( uno::RuntimeException )
609 {
610 	::osl::MutexGuard aGuard( m_aMutex );
611 
612 	if ( m_bDisposed )
613 		throw lang::DisposedException();
614 
615 	  if ( !m_pStorage )
616 		throw uno::RuntimeException();
617 
618 	SvStorageInfoList aList;
619 	m_pStorage->FillInfoList( &aList );
620 
621 	if ( m_pStorage->GetError() )
622 	{
623 		m_pStorage->ResetError();
624 		throw uno::RuntimeException(); // TODO:
625 	}
626 
627 	return ( aList.Count() != 0 );
628 }
629 
630 //____________________________________________________________________________________________________
631 //	XComponent
632 //____________________________________________________________________________________________________
633 
634 // --------------------------------------------------------------------------------
dispose()635 void SAL_CALL OLESimpleStorage::dispose()
636 		throw ( uno::RuntimeException )
637 {
638 	::osl::MutexGuard aGuard( m_aMutex );
639 
640 	if ( m_bDisposed )
641 		throw lang::DisposedException();
642 
643 	if ( m_pListenersContainer )
644 	{
645    		lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
646 		m_pListenersContainer->disposeAndClear( aSource );
647 	}
648 
649 	DELETEZ( m_pStorage );
650 	DELETEZ( m_pStream );
651 
652 	m_xStream = uno::Reference< io::XStream >();
653 	m_xTempStream = uno::Reference< io::XStream >();
654 
655 	m_bDisposed = sal_True;
656 }
657 
658 // --------------------------------------------------------------------------------
addEventListener(const uno::Reference<lang::XEventListener> & xListener)659 void SAL_CALL OLESimpleStorage::addEventListener(
660 			const uno::Reference< lang::XEventListener >& xListener )
661 		throw ( uno::RuntimeException )
662 {
663 	::osl::MutexGuard aGuard( m_aMutex );
664 
665 	if ( m_bDisposed )
666 		throw lang::DisposedException();
667 
668 	if ( !m_pListenersContainer )
669 		m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
670 
671 	m_pListenersContainer->addInterface( xListener );
672 }
673 
674 // --------------------------------------------------------------------------------
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)675 void SAL_CALL OLESimpleStorage::removeEventListener(
676 			const uno::Reference< lang::XEventListener >& xListener )
677 		throw ( uno::RuntimeException )
678 {
679 	::osl::MutexGuard aGuard( m_aMutex );
680 
681 	if ( m_bDisposed )
682 		throw lang::DisposedException();
683 
684 	if ( m_pListenersContainer )
685 		m_pListenersContainer->removeInterface( xListener );
686 }
687 
688 //____________________________________________________________________________________________________
689 //	XTransactedObject
690 //____________________________________________________________________________________________________
691 
692 // --------------------------------------------------------------------------------
commit()693 void SAL_CALL OLESimpleStorage::commit()
694 		throw ( ::com::sun::star::io::IOException,
695 				::com::sun::star::lang::WrappedTargetException,
696 				::com::sun::star::uno::RuntimeException )
697 {
698 	::osl::MutexGuard aGuard( m_aMutex );
699 
700 	if ( m_bDisposed )
701 		throw lang::DisposedException();
702 
703 	 if ( !m_pStorage )
704 		throw uno::RuntimeException();
705 
706 	if ( !m_bNoTemporaryCopy && !m_xStream.is() )
707 		throw io::IOException(); // TODO
708 
709 	if ( !m_pStorage->Commit() || m_pStorage->GetError() )
710 	{
711 		m_pStorage->ResetError();
712 		throw io::IOException(); // TODO
713 	}
714 
715 	UpdateOriginal_Impl();
716 }
717 
718 // --------------------------------------------------------------------------------
revert()719 void SAL_CALL OLESimpleStorage::revert()
720 		throw ( ::com::sun::star::io::IOException,
721 				::com::sun::star::lang::WrappedTargetException,
722 				::com::sun::star::uno::RuntimeException )
723 {
724 	::osl::MutexGuard aGuard( m_aMutex );
725 
726 	if ( m_bDisposed )
727 		throw lang::DisposedException();
728 
729 	 if ( !m_pStorage )
730 		throw uno::RuntimeException();
731 
732 	if ( !m_bNoTemporaryCopy && !m_xStream.is() )
733 		throw io::IOException(); // TODO
734 
735 	if ( !m_pStorage->Revert() || m_pStorage->GetError() )
736 	{
737 		m_pStorage->ResetError();
738 		throw io::IOException(); // TODO
739 	}
740 
741 	UpdateOriginal_Impl();
742 }
743 
744 //____________________________________________________________________________________________________
745 //	XClassifiedObject
746 //____________________________________________________________________________________________________
747 
getClassID()748 uno::Sequence< sal_Int8 > SAL_CALL OLESimpleStorage::getClassID()
749 	throw ( uno::RuntimeException )
750 {
751 	::osl::MutexGuard aGuard( m_aMutex );
752 
753 	if ( m_bDisposed )
754 		throw lang::DisposedException();
755 
756 	if ( !m_pStorage )
757 		throw uno::RuntimeException();
758 
759 	return m_pStorage->GetClassName().GetByteSequence();
760 }
761 
getClassName()762 ::rtl::OUString SAL_CALL OLESimpleStorage::getClassName()
763 	throw ( uno::RuntimeException )
764 {
765 	return ::rtl::OUString();
766 }
767 
setClassInfo(const uno::Sequence<sal_Int8> &,const::rtl::OUString &)768 void SAL_CALL OLESimpleStorage::setClassInfo( const uno::Sequence< sal_Int8 >& /*aClassID*/,
769 							const ::rtl::OUString& /*sClassName*/ )
770 		throw ( lang::NoSupportException,
771 				uno::RuntimeException )
772 {
773 	throw lang::NoSupportException();
774 }
775 
776 //____________________________________________________________________________________________________
777 //	XServiceInfo
778 //____________________________________________________________________________________________________
779 
780 // --------------------------------------------------------------------------------
getImplementationName()781 ::rtl::OUString SAL_CALL OLESimpleStorage::getImplementationName()
782 		throw ( uno::RuntimeException )
783 {
784 	return impl_staticGetImplementationName();
785 }
786 
787 // --------------------------------------------------------------------------------
supportsService(const::rtl::OUString & ServiceName)788 ::sal_Bool SAL_CALL OLESimpleStorage::supportsService( const ::rtl::OUString& ServiceName )
789 		throw ( uno::RuntimeException )
790 {
791 	uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
792 
793 	for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
794     	if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
795         	return sal_True;
796 
797 	return sal_False;
798 }
799 
800 // --------------------------------------------------------------------------------
getSupportedServiceNames()801 uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::getSupportedServiceNames()
802 		throw ( uno::RuntimeException )
803 {
804 	return impl_staticGetSupportedServiceNames();
805 }
806 
807 
808