michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef IEnumeFE_h__ michael@0: #define IEnumeFE_h__ michael@0: michael@0: /* michael@0: * CEnumFormatEtc - implements IEnumFORMATETC michael@0: */ michael@0: michael@0: #include michael@0: michael@0: #include "nsTArray.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: // FORMATETC container michael@0: class FormatEtc michael@0: { michael@0: public: michael@0: FormatEtc() { memset(&mFormat, 0, sizeof(FORMATETC)); } michael@0: FormatEtc(const FormatEtc& copy) { CopyIn(©.mFormat); } michael@0: ~FormatEtc() { if (mFormat.ptd) CoTaskMemFree(mFormat.ptd); } michael@0: michael@0: void CopyIn(const FORMATETC *aSrc) { michael@0: if (!aSrc) { michael@0: memset(&mFormat, 0, sizeof(FORMATETC)); michael@0: return; michael@0: } michael@0: mFormat = *aSrc; michael@0: if (aSrc->ptd) { michael@0: mFormat.ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE)); michael@0: *(mFormat.ptd) = *(aSrc->ptd); michael@0: } michael@0: } michael@0: michael@0: void CopyOut(LPFORMATETC aDest) { michael@0: if (!aDest) michael@0: return; michael@0: *aDest = mFormat; michael@0: if (mFormat.ptd) { michael@0: aDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE)); michael@0: *(aDest->ptd) = *(mFormat.ptd); michael@0: } michael@0: } michael@0: michael@0: private: michael@0: FORMATETC mFormat; michael@0: }; michael@0: michael@0: /* michael@0: * CEnumFormatEtc is created within IDataObject::EnumFormatEtc. This object lives michael@0: * on its own, that is, QueryInterface only knows IUnknown and IEnumFormatEtc, michael@0: * nothing more. We still use an outer unknown for reference counting, because as michael@0: * long as this enumerator lives, the data object should live, thereby keeping the michael@0: * application up. michael@0: */ michael@0: michael@0: class CEnumFormatEtc MOZ_FINAL : public IEnumFORMATETC michael@0: { michael@0: public: michael@0: CEnumFormatEtc(nsTArray& aArray); michael@0: CEnumFormatEtc(); michael@0: ~CEnumFormatEtc(); michael@0: michael@0: // IUnknown impl. michael@0: STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv); michael@0: STDMETHODIMP_(ULONG) AddRef(); michael@0: STDMETHODIMP_(ULONG) Release(); michael@0: michael@0: // IEnumFORMATETC impl. michael@0: STDMETHODIMP Next(ULONG aMaxToFetch, FORMATETC *aResult, ULONG *aNumFetched); michael@0: STDMETHODIMP Skip(ULONG aSkipNum); michael@0: STDMETHODIMP Reset(); michael@0: STDMETHODIMP Clone(LPENUMFORMATETC *aResult); // Addrefs michael@0: michael@0: // Utils michael@0: void AddFormatEtc(LPFORMATETC aFormat); michael@0: michael@0: private: michael@0: nsTArray mFormatList; // Formats michael@0: ULONG mRefCnt; // Object reference count michael@0: ULONG mCurrentIdx; // Current element michael@0: michael@0: void SetIndex(uint32_t aIdx); michael@0: }; michael@0: michael@0: michael@0: #endif //_IENUMFE_H_