summaryrefslogtreecommitdiffstats
path: root/widget/windows/IEnumFE.h
blob: b8cb6ad9d0379b8e8a96861bd0f13ddf3ff4b93a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef IEnumeFE_h__
#define IEnumeFE_h__

/*
 * CEnumFormatEtc - implements IEnumFORMATETC
 */

#include <ole2.h>

#include "nsTArray.h"
#include "mozilla/Attributes.h"

// FORMATETC container
class FormatEtc {
 public:
  FormatEtc() { memset(&mFormat, 0, sizeof(FORMATETC)); }
  FormatEtc(const FormatEtc& copy) { CopyIn(&copy.mFormat); }
  ~FormatEtc() {
    if (mFormat.ptd) CoTaskMemFree(mFormat.ptd);
  }

  void CopyIn(const FORMATETC* aSrc) {
    if (!aSrc) {
      memset(&mFormat, 0, sizeof(FORMATETC));
      return;
    }
    mFormat = *aSrc;
    if (aSrc->ptd) {
      mFormat.ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
      *(mFormat.ptd) = *(aSrc->ptd);
    }
  }

  void CopyOut(LPFORMATETC aDest) {
    if (!aDest) return;
    *aDest = mFormat;
    if (mFormat.ptd) {
      aDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
      *(aDest->ptd) = *(mFormat.ptd);
    }
  }

 private:
  FORMATETC mFormat;
};

/*
 * CEnumFormatEtc is created within IDataObject::EnumFormatEtc. This object
 * lives on its own, that is, QueryInterface only knows IUnknown and
 * IEnumFormatEtc, nothing more.  We still use an outer unknown for reference
 * counting, because as long as this enumerator lives, the data object should
 * live, thereby keeping the application up.
 */

class CEnumFormatEtc final : public IEnumFORMATETC {
 public:
  explicit CEnumFormatEtc(nsTArray<FormatEtc>& aArray);
  CEnumFormatEtc();
  ~CEnumFormatEtc();

  // IUnknown impl.
  STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppv);
  STDMETHODIMP_(ULONG) AddRef();
  STDMETHODIMP_(ULONG) Release();

  // IEnumFORMATETC impl.
  STDMETHODIMP Next(ULONG aMaxToFetch, FORMATETC* aResult, ULONG* aNumFetched);
  STDMETHODIMP Skip(ULONG aSkipNum);
  STDMETHODIMP Reset();
  STDMETHODIMP Clone(LPENUMFORMATETC* aResult);  // Addrefs

  // Utils
  void AddFormatEtc(LPFORMATETC aFormat);

 private:
  nsTArray<FormatEtc> mFormatList;  // Formats
  ULONG mRefCnt;                    // Object reference count
  ULONG mCurrentIdx;                // Current element

  void SetIndex(uint32_t aIdx);
};

#endif  //_IENUMFE_H_