1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef IEnumeFE_h__
7 #define IEnumeFE_h__
8 
9 /*
10  * CEnumFormatEtc - implements IEnumFORMATETC
11  */
12 
13 #include <ole2.h>
14 
15 #include "nsTArray.h"
16 #include "mozilla/Attributes.h"
17 
18 // FORMATETC container
19 class FormatEtc {
20  public:
FormatEtc()21   FormatEtc() { memset(&mFormat, 0, sizeof(FORMATETC)); }
FormatEtc(const FormatEtc & copy)22   FormatEtc(const FormatEtc &copy) { CopyIn(&copy.mFormat); }
~FormatEtc()23   ~FormatEtc() {
24     if (mFormat.ptd) CoTaskMemFree(mFormat.ptd);
25   }
26 
CopyIn(const FORMATETC * aSrc)27   void CopyIn(const FORMATETC *aSrc) {
28     if (!aSrc) {
29       memset(&mFormat, 0, sizeof(FORMATETC));
30       return;
31     }
32     mFormat = *aSrc;
33     if (aSrc->ptd) {
34       mFormat.ptd = (DVTARGETDEVICE *)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
35       *(mFormat.ptd) = *(aSrc->ptd);
36     }
37   }
38 
CopyOut(LPFORMATETC aDest)39   void CopyOut(LPFORMATETC aDest) {
40     if (!aDest) return;
41     *aDest = mFormat;
42     if (mFormat.ptd) {
43       aDest->ptd = (DVTARGETDEVICE *)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
44       *(aDest->ptd) = *(mFormat.ptd);
45     }
46   }
47 
48  private:
49   FORMATETC mFormat;
50 };
51 
52 /*
53  * CEnumFormatEtc is created within IDataObject::EnumFormatEtc. This object
54  * lives on its own, that is, QueryInterface only knows IUnknown and
55  * IEnumFormatEtc, nothing more.  We still use an outer unknown for reference
56  * counting, because as long as this enumerator lives, the data object should
57  * live, thereby keeping the application up.
58  */
59 
60 class CEnumFormatEtc final : public IEnumFORMATETC {
61  public:
62   explicit CEnumFormatEtc(nsTArray<FormatEtc> &aArray);
63   CEnumFormatEtc();
64   ~CEnumFormatEtc();
65 
66   // IUnknown impl.
67   STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
68   STDMETHODIMP_(ULONG) AddRef();
69   STDMETHODIMP_(ULONG) Release();
70 
71   // IEnumFORMATETC impl.
72   STDMETHODIMP Next(ULONG aMaxToFetch, FORMATETC *aResult, ULONG *aNumFetched);
73   STDMETHODIMP Skip(ULONG aSkipNum);
74   STDMETHODIMP Reset();
75   STDMETHODIMP Clone(LPENUMFORMATETC *aResult);  // Addrefs
76 
77   // Utils
78   void AddFormatEtc(LPFORMATETC aFormat);
79 
80  private:
81   nsTArray<FormatEtc> mFormatList;  // Formats
82   ULONG mRefCnt;                    // Object reference count
83   ULONG mCurrentIdx;                // Current element
84 
85   void SetIndex(uint32_t aIdx);
86 };
87 
88 #endif  //_IENUMFE_H_
89