1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <osl/diagnose.h>
22 #include "XTDataObject.hxx"
23 #include <com/sun/star/datatransfer/DataFlavor.hpp>
24 #include "../misc/ImplHelper.hxx"
25 #include "DTransHelper.hxx"
26 #include "TxtCnvtHlp.hxx"
27 #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
28 #include "FmtFilter.hxx"
29 #include <comphelper/processfactory.hxx>
32 #pragma warning(push,1)
33 #pragma warning(disable:4917)
45 #define __uuidof(I) IID_##I
48 //------------------------------------------------------------------------
49 // namespace directives
50 //------------------------------------------------------------------------
52 using namespace com::sun::star::datatransfer
;
53 using namespace com::sun::star::datatransfer::clipboard
;
54 using namespace com::sun::star::uno
;
55 using namespace com::sun::star::lang
;
58 //------------------------------------------------------------------------
59 // a helper class that will be thrown by the function validateFormatEtc
60 //------------------------------------------------------------------------
62 class CInvalidFormatEtcException
66 CInvalidFormatEtcException( HRESULT hr
) : m_hr( hr
) {};
69 //------------------------------------------------------------------------
71 //------------------------------------------------------------------------
73 CXTDataObject::CXTDataObject( const Reference
< XComponentContext
>& rxContext
,
74 const Reference
< XTransferable
>& aXTransferable
)
76 , m_XTransferable( aXTransferable
)
77 , m_bFormatEtcContainerInitialized( sal_False
)
78 , m_DataFormatTranslator( rxContext
)
79 , m_FormatRegistrar( rxContext
, m_DataFormatTranslator
)
83 //------------------------------------------------------------------------
84 // IUnknown->QueryInterface
85 //------------------------------------------------------------------------
87 STDMETHODIMP
CXTDataObject::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
89 if ( NULL
== ppvObject
)
92 HRESULT hr
= E_NOINTERFACE
;
95 if ( ( __uuidof( IUnknown
) == iid
) ||
96 ( __uuidof( IDataObject
) == iid
) )
98 *ppvObject
= static_cast< IUnknown
* >( this );
99 ( (LPUNKNOWN
)*ppvObject
)->AddRef( );
106 //------------------------------------------------------------------------
108 //------------------------------------------------------------------------
110 STDMETHODIMP_(ULONG
) CXTDataObject::AddRef( )
112 return static_cast< ULONG
>( InterlockedIncrement( &m_nRefCnt
) );
115 //------------------------------------------------------------------------
117 //------------------------------------------------------------------------
119 STDMETHODIMP_(ULONG
) CXTDataObject::Release( )
122 static_cast< ULONG
>( InterlockedDecrement( &m_nRefCnt
) );
130 //------------------------------------------------------------------------
132 //------------------------------------------------------------------------
134 STDMETHODIMP
CXTDataObject::GetData( LPFORMATETC pFormatetc
, LPSTGMEDIUM pmedium
)
136 if ( !(pFormatetc
&& pmedium
) )
141 // prepare data transfer
142 invalidateStgMedium( *pmedium
);
143 validateFormatEtc( pFormatetc
);
145 // handle locale request, because locale is a artificial format for us
146 if ( CF_LOCALE
== pFormatetc
->cfFormat
)
147 renderLocaleAndSetupStgMedium( *pFormatetc
, *pmedium
);
148 else if ( CF_UNICODETEXT
== pFormatetc
->cfFormat
)
149 renderUnicodeAndSetupStgMedium( *pFormatetc
, *pmedium
);
151 renderAnyDataAndSetupStgMedium( *pFormatetc
, *pmedium
);
153 catch(UnsupportedFlavorException
&)
155 HRESULT hr
= DV_E_FORMATETC
;
157 if ( m_FormatRegistrar
.isSynthesizeableFormat( *pFormatetc
) )
158 hr
= renderSynthesizedFormatAndSetupStgMedium( *pFormatetc
, *pmedium
);
162 catch( CInvalidFormatEtcException
& ex
)
166 catch( CStgTransferHelper::CStgTransferException
& ex
)
168 return translateStgExceptionCode( ex
.m_hr
);
178 //------------------------------------------------------------------------
180 //------------------------------------------------------------------------
183 void SAL_CALL
CXTDataObject::renderDataAndSetupStgMedium(
184 const sal_Int8
* lpStorage
, const FORMATETC
& fetc
, sal_uInt32 nInitStgSize
,
185 sal_uInt32 nBytesToTransfer
, STGMEDIUM
& stgmedium
)
187 OSL_PRECOND( !nInitStgSize
|| nInitStgSize
&& (nInitStgSize
>= nBytesToTransfer
),
188 "Memory size less than number of bytes to transfer" );
190 CStgTransferHelper
stgTransfHelper( AUTO_INIT
);
192 // setup storage size
193 if ( nInitStgSize
> 0 )
194 stgTransfHelper
.init( nInitStgSize
, GHND
);
196 #if OSL_DEBUG_LEVEL > 0
197 sal_uInt32 nBytesWritten
= 0;
198 stgTransfHelper
.write( lpStorage
, nBytesToTransfer
, &nBytesWritten
);
199 OSL_ASSERT( nBytesWritten
== nBytesToTransfer
);
201 stgTransfHelper
.write( lpStorage
, nBytesToTransfer
);
204 setupStgMedium( fetc
, stgTransfHelper
, stgmedium
);
207 //------------------------------------------------------------------------
209 //------------------------------------------------------------------------
212 void SAL_CALL
CXTDataObject::renderLocaleAndSetupStgMedium(
213 FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
215 if ( m_FormatRegistrar
.hasSynthesizedLocale( ) )
217 LCID lcid
= m_FormatRegistrar
.getSynthesizedLocale( );
218 renderDataAndSetupStgMedium(
219 reinterpret_cast< sal_Int8
* >( &lcid
),
226 throw CInvalidFormatEtcException( DV_E_FORMATETC
);
229 //------------------------------------------------------------------------
231 //------------------------------------------------------------------------
234 void SAL_CALL
CXTDataObject::renderUnicodeAndSetupStgMedium(
235 FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
237 DataFlavor aFlavor
= formatEtcToDataFlavor( fetc
);
239 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
241 // unfortunately not all transferables fulfill the
242 // spec. an do throw an UnsupportedFlavorException
243 // so we must check the any
244 if ( !aAny
.hasValue( ) )
246 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
247 throw UnsupportedFlavorException( );
253 sal_uInt32 nBytesToTransfer
= aText
.getLength( ) * sizeof( sal_Unicode
);
255 // to be sure there is an ending 0
256 sal_uInt32 nRequiredMemSize
= nBytesToTransfer
+ sizeof( sal_Unicode
);
258 renderDataAndSetupStgMedium(
259 reinterpret_cast< const sal_Int8
* >( aText
.getStr( ) ),
266 //------------------------------------------------------------------------
268 //------------------------------------------------------------------------
271 void SAL_CALL
CXTDataObject::renderAnyDataAndSetupStgMedium(
272 FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
274 DataFlavor aFlavor
= formatEtcToDataFlavor( fetc
);
276 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
278 // unfortunately not all transferables fulfill the
279 // spec. an do throw an UnsupportedFlavorException
280 // so we must check the any
281 if ( !aAny
.hasValue( ) )
283 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
284 throw UnsupportedFlavorException( );
287 // unfortunately not all transferables fulfill the
288 // spec. an do throw an UnsupportedFlavorException
289 // so we must check the any
290 if ( !aAny
.hasValue( ) )
291 throw UnsupportedFlavorException( );
293 Sequence
< sal_Int8
> clipDataStream
;
294 aAny
>>= clipDataStream
;
296 sal_uInt32 nRequiredMemSize
= 0;
297 if ( m_DataFormatTranslator
.isOemOrAnsiTextFormat( fetc
.cfFormat
) )
298 nRequiredMemSize
= sizeof( sal_Int8
) * clipDataStream
.getLength( ) + 1;
300 // prepare data for transmision
301 if ( CF_DIB
== fetc
.cfFormat
)
302 clipDataStream
= OOBmpToWinDIB( clipDataStream
);
304 if ( CF_METAFILEPICT
== fetc
.cfFormat
)
306 stgmedium
.tymed
= TYMED_MFPICT
;
307 stgmedium
.hMetaFilePict
= OOMFPictToWinMFPict( clipDataStream
);
308 stgmedium
.pUnkForRelease
= NULL
;
310 else if( CF_ENHMETAFILE
== fetc
.cfFormat
)
312 stgmedium
.tymed
= TYMED_ENHMF
;
313 stgmedium
.hMetaFilePict
= OOMFPictToWinENHMFPict( clipDataStream
);
314 stgmedium
.pUnkForRelease
= NULL
;
317 renderDataAndSetupStgMedium(
318 clipDataStream
.getArray( ),
321 clipDataStream
.getLength( ),
325 //------------------------------------------------------------------------
327 //------------------------------------------------------------------------
329 HRESULT SAL_CALL
CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
335 if ( CF_UNICODETEXT
== fetc
.cfFormat
)
336 // the transferable seems to have only text
337 renderSynthesizedUnicodeAndSetupStgMedium( fetc
, stgmedium
);
338 else if ( m_DataFormatTranslator
.isOemOrAnsiTextFormat( fetc
.cfFormat
) )
339 // the transferable seems to have only unicode text
340 renderSynthesizedTextAndSetupStgMedium( fetc
, stgmedium
);
342 // the transferable seems to have only text/html
343 renderSynthesizedHtmlAndSetupStgMedium( fetc
, stgmedium
);
345 catch(UnsupportedFlavorException
&)
349 catch( CInvalidFormatEtcException
& )
351 OSL_FAIL( "Unexpected exception" );
353 catch( CStgTransferHelper::CStgTransferException
& ex
)
355 return translateStgExceptionCode( ex
.m_hr
);
365 //------------------------------------------------------------------------
366 // the transferable must have only text, so we will synthesize unicode text
367 //------------------------------------------------------------------------
369 void SAL_CALL
CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
371 OSL_ASSERT( CF_UNICODETEXT
== fetc
.cfFormat
);
373 Any aAny
= m_XTransferable
->getTransferData( m_FormatRegistrar
.getRegisteredTextFlavor( ) );
375 // unfortunately not all transferables fulfill the
376 // spec. an do throw an UnsupportedFlavorException
377 // so we must check the any
378 if ( !aAny
.hasValue( ) )
380 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
381 throw UnsupportedFlavorException( );
384 Sequence
< sal_Int8
> aText
;
387 CStgTransferHelper stgTransfHelper
;
389 MultiByteToWideCharEx(
390 m_FormatRegistrar
.getRegisteredTextCodePage( ),
391 reinterpret_cast< char* >( aText
.getArray( ) ),
395 setupStgMedium( fetc
, stgTransfHelper
, stgmedium
);
398 //------------------------------------------------------------------------
399 // the transferable must have only unicode text so we will sythesize text
400 //------------------------------------------------------------------------
402 void SAL_CALL
CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
404 OSL_ASSERT( m_DataFormatTranslator
.isOemOrAnsiTextFormat( fetc
.cfFormat
) );
406 DataFlavor aFlavor
= formatEtcToDataFlavor(
407 m_DataFormatTranslator
.getFormatEtcForClipformat( CF_UNICODETEXT
) );
409 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
411 // unfortunately not all transferables fulfill the
412 // spec. an do throw an UnsupportedFlavorException
413 // so we must check the any
414 if ( !aAny
.hasValue( ) )
416 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
417 throw UnsupportedFlavorException( );
420 OUString aUnicodeText
;
421 aAny
>>= aUnicodeText
;
423 CStgTransferHelper stgTransfHelper
;
425 WideCharToMultiByteEx(
427 reinterpret_cast<LPCWSTR
>( aUnicodeText
.getStr( ) ),
428 aUnicodeText
.getLength( ),
431 setupStgMedium( fetc
, stgTransfHelper
, stgmedium
);
434 //------------------------------------------------------------------------
436 //------------------------------------------------------------------------
438 void SAL_CALL
CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC
& fetc
, STGMEDIUM
& stgmedium
)
440 OSL_ASSERT( m_DataFormatTranslator
.isHTMLFormat( fetc
.cfFormat
) );
444 // creating a DataFlavor on the fly
445 aFlavor
.MimeType
= OUString("text/html");
446 aFlavor
.DataType
= getCppuType( (Sequence
< sal_Int8
>*)0 );
448 Any aAny
= m_XTransferable
->getTransferData( aFlavor
);
450 // unfortunately not all transferables fulfill the
451 // spec. an do throw an UnsupportedFlavorException
452 // so we must check the any
453 if ( !aAny
.hasValue( ) )
455 OSL_FAIL( "XTransferable should throw an exception if ask for an unsupported flavor" );
456 throw UnsupportedFlavorException( );
459 Sequence
< sal_Int8
> aTextHtmlSequence
;
460 aAny
>>= aTextHtmlSequence
;
462 Sequence
< sal_Int8
> aHTMLFormatSequence
= TextHtmlToHTMLFormat( aTextHtmlSequence
);
464 sal_uInt32 nBytesToTransfer
= aHTMLFormatSequence
.getLength( );
466 renderDataAndSetupStgMedium(
467 reinterpret_cast< const sal_Int8
* >( aHTMLFormatSequence
.getArray( ) ),
474 //------------------------------------------------------------------------
475 // IDataObject->EnumFormatEtc
476 //------------------------------------------------------------------------
478 STDMETHODIMP
CXTDataObject::EnumFormatEtc(
479 DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatetc
)
481 if ( NULL
== ppenumFormatetc
)
484 if ( DATADIR_SET
== dwDirection
)
487 *ppenumFormatetc
= NULL
;
489 InitializeFormatEtcContainer( );
492 if ( DATADIR_GET
== dwDirection
)
494 *ppenumFormatetc
= new CEnumFormatEtc( this, m_FormatEtcContainer
);
495 static_cast< LPUNKNOWN
>( *ppenumFormatetc
)->AddRef( );
505 //------------------------------------------------------------------------
506 // IDataObject->QueryGetData
507 //------------------------------------------------------------------------
509 STDMETHODIMP
CXTDataObject::QueryGetData( LPFORMATETC pFormatetc
)
511 if ( (NULL
== pFormatetc
) || IsBadReadPtr( pFormatetc
, sizeof( FORMATETC
) ) )
514 InitializeFormatEtcContainer( );
516 return m_FormatEtcContainer
.hasFormatEtc( *pFormatetc
) ? S_OK
: S_FALSE
;
519 //------------------------------------------------------------------------
520 // IDataObject->GetDataHere
521 //------------------------------------------------------------------------
523 STDMETHODIMP
CXTDataObject::GetDataHere( LPFORMATETC
, LPSTGMEDIUM
)
528 //------------------------------------------------------------------------
529 // IDataObject->GetCanonicalFormatEtc
530 //------------------------------------------------------------------------
532 STDMETHODIMP
CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC
, LPFORMATETC
)
537 //------------------------------------------------------------------------
538 // IDataObject->SetData
539 //------------------------------------------------------------------------
541 STDMETHODIMP
CXTDataObject::SetData( LPFORMATETC
, LPSTGMEDIUM
, BOOL
)
546 //------------------------------------------------------------------------
547 // IDataObject->DAdvise
548 //------------------------------------------------------------------------
550 STDMETHODIMP
CXTDataObject::DAdvise( LPFORMATETC
, DWORD
, LPADVISESINK
, DWORD
* )
555 //------------------------------------------------------------------------
556 // IDataObject->DUnadvise
557 //------------------------------------------------------------------------
559 STDMETHODIMP
CXTDataObject::DUnadvise( DWORD
)
564 //------------------------------------------------------------------------
565 // IDataObject->EnumDAdvise
566 //------------------------------------------------------------------------
568 STDMETHODIMP
CXTDataObject::EnumDAdvise( LPENUMSTATDATA
* )
573 //------------------------------------------------------------------------
574 // for our convenience
575 //------------------------------------------------------------------------
577 CXTDataObject::operator IDataObject
*( )
579 return static_cast< IDataObject
* >( this );
582 //------------------------------------------------------------------------
584 //------------------------------------------------------------------------
587 DataFlavor SAL_CALL
CXTDataObject::formatEtcToDataFlavor( const FORMATETC
& aFormatEtc
) const
591 if ( m_FormatRegistrar
.hasSynthesizedLocale( ) )
593 m_DataFormatTranslator
.getDataFlavorFromFormatEtc( aFormatEtc
, m_FormatRegistrar
.getSynthesizedLocale( ) );
595 aFlavor
= m_DataFormatTranslator
.getDataFlavorFromFormatEtc( aFormatEtc
);
597 if ( !aFlavor
.MimeType
.getLength( ) )
598 throw UnsupportedFlavorException( );
603 //------------------------------------------------------------------------
605 //------------------------------------------------------------------------
608 void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc
) const
610 OSL_ASSERT( lpFormatEtc
);
612 if ( lpFormatEtc
->lindex
!= -1 )
613 throw CInvalidFormatEtcException( DV_E_LINDEX
);
615 if ( !(lpFormatEtc
->dwAspect
& DVASPECT_CONTENT
) &&
616 !(lpFormatEtc
->dwAspect
& DVASPECT_SHORTNAME
) )
617 throw CInvalidFormatEtcException( DV_E_DVASPECT
);
619 if ( !(lpFormatEtc
->tymed
& TYMED_HGLOBAL
) &&
620 !(lpFormatEtc
->tymed
& TYMED_ISTREAM
) &&
621 !(lpFormatEtc
->tymed
& TYMED_MFPICT
) &&
622 !(lpFormatEtc
->tymed
& TYMED_ENHMF
) )
623 throw CInvalidFormatEtcException( DV_E_TYMED
);
625 if ( lpFormatEtc
->cfFormat
== CF_METAFILEPICT
&&
626 !(lpFormatEtc
->tymed
& TYMED_MFPICT
) )
627 throw CInvalidFormatEtcException( DV_E_TYMED
);
629 if ( lpFormatEtc
->cfFormat
== CF_ENHMETAFILE
&&
630 !(lpFormatEtc
->tymed
& TYMED_ENHMF
) )
631 throw CInvalidFormatEtcException( DV_E_TYMED
);
634 //------------------------------------------------------------------------
636 //------------------------------------------------------------------------
639 void SAL_CALL
CXTDataObject::setupStgMedium( const FORMATETC
& fetc
,
640 CStgTransferHelper
& stgTransHlp
,
641 STGMEDIUM
& stgmedium
)
643 stgmedium
.pUnkForRelease
= NULL
;
645 if ( fetc
.cfFormat
== CF_METAFILEPICT
)
647 stgmedium
.tymed
= TYMED_MFPICT
;
648 stgmedium
.hMetaFilePict
= static_cast< HMETAFILEPICT
>( stgTransHlp
.getHGlobal( ) );
650 else if ( fetc
.cfFormat
== CF_ENHMETAFILE
)
652 stgmedium
.tymed
= TYMED_ENHMF
;
653 stgmedium
.hEnhMetaFile
= static_cast< HENHMETAFILE
>( stgTransHlp
.getHGlobal( ) );
655 else if ( fetc
.tymed
& TYMED_HGLOBAL
)
657 stgmedium
.tymed
= TYMED_HGLOBAL
;
658 stgmedium
.hGlobal
= stgTransHlp
.getHGlobal( );
660 else if ( fetc
.tymed
& TYMED_ISTREAM
)
662 stgmedium
.tymed
= TYMED_ISTREAM
;
663 stgTransHlp
.getIStream( &stgmedium
.pstm
);
666 OSL_ASSERT( sal_False
);
669 //------------------------------------------------------------------------
671 //------------------------------------------------------------------------
674 void SAL_CALL
CXTDataObject::invalidateStgMedium( STGMEDIUM
& stgmedium
) const
676 stgmedium
.tymed
= TYMED_NULL
;
679 //------------------------------------------------------------------------
681 //------------------------------------------------------------------------
684 HRESULT SAL_CALL
CXTDataObject::translateStgExceptionCode( HRESULT hr
) const
690 case STG_E_MEDIUMFULL
:
695 hrTransl
= E_UNEXPECTED
;
702 //------------------------------------------------------------------------
704 //------------------------------------------------------------------------
706 inline void SAL_CALL
CXTDataObject::InitializeFormatEtcContainer( )
708 if ( !m_bFormatEtcContainerInitialized
)
710 m_FormatRegistrar
.RegisterFormats( m_XTransferable
, m_FormatEtcContainer
);
711 m_bFormatEtcContainerInitialized
= sal_True
;
715 //============================================================================
717 //============================================================================
719 //----------------------------------------------------------------------------
721 //----------------------------------------------------------------------------
723 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter
, const CFormatEtcContainer
& aFormatEtcContainer
) :
725 m_lpUnkOuter( lpUnkOuter
),
726 m_FormatEtcContainer( aFormatEtcContainer
)
731 //----------------------------------------------------------------------------
732 // IUnknown->QueryInterface
733 //----------------------------------------------------------------------------
735 STDMETHODIMP
CEnumFormatEtc::QueryInterface( REFIID iid
, LPVOID
* ppvObject
)
737 if ( NULL
== ppvObject
)
740 HRESULT hr
= E_NOINTERFACE
;
744 if ( ( __uuidof( IUnknown
) == iid
) ||
745 ( __uuidof( IEnumFORMATETC
) == iid
) )
747 *ppvObject
= static_cast< IUnknown
* >( this );
748 static_cast< LPUNKNOWN
>( *ppvObject
)->AddRef( );
755 //----------------------------------------------------------------------------
757 //----------------------------------------------------------------------------
759 STDMETHODIMP_(ULONG
) CEnumFormatEtc::AddRef( )
761 // keep the dataobject alive
762 m_lpUnkOuter
->AddRef( );
763 return InterlockedIncrement( &m_nRefCnt
);
766 //----------------------------------------------------------------------------
768 //----------------------------------------------------------------------------
770 STDMETHODIMP_(ULONG
) CEnumFormatEtc::Release( )
772 // release the outer dataobject
773 m_lpUnkOuter
->Release( );
775 ULONG nRefCnt
= InterlockedDecrement( &m_nRefCnt
);
782 //----------------------------------------------------------------------------
783 // IEnumFORMATETC->Next
784 //----------------------------------------------------------------------------
786 STDMETHODIMP
CEnumFormatEtc::Next( ULONG nRequested
, LPFORMATETC lpDest
, ULONG
* lpFetched
)
788 if ( ( nRequested
< 1 ) ||
789 (( nRequested
> 1 ) && ( NULL
== lpFetched
)) ||
790 IsBadWritePtr( lpDest
, sizeof( FORMATETC
) * nRequested
) )
793 sal_uInt32 nFetched
= m_FormatEtcContainer
.nextFormatEtc( lpDest
, nRequested
);
795 if ( NULL
!= lpFetched
)
796 *lpFetched
= nFetched
;
798 return (nFetched
== nRequested
) ? S_OK
: S_FALSE
;
801 //----------------------------------------------------------------------------
802 // IEnumFORMATETC->Skip
803 //----------------------------------------------------------------------------
805 STDMETHODIMP
CEnumFormatEtc::Skip( ULONG celt
)
807 return m_FormatEtcContainer
.skipFormatEtc( celt
) ? S_OK
: S_FALSE
;
810 //----------------------------------------------------------------------------
811 // IEnumFORMATETC->Reset
812 //----------------------------------------------------------------------------
814 STDMETHODIMP
CEnumFormatEtc::Reset( )
816 m_FormatEtcContainer
.beginEnumFormatEtc( );
820 //----------------------------------------------------------------------------
821 // IEnumFORMATETC->Clone
822 //----------------------------------------------------------------------------
824 STDMETHODIMP
CEnumFormatEtc::Clone( IEnumFORMATETC
** ppenum
)
826 if ( NULL
== ppenum
)
829 *ppenum
= new CEnumFormatEtc( m_lpUnkOuter
, m_FormatEtcContainer
);
830 static_cast< LPUNKNOWN
>( *ppenum
)->AddRef( );
835 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */