Bug 1931425 - Limit how often moz-label's #setStyles runs r=reusable-components-revie...
[gecko.git] / widget / windows / IEnumFE.cpp
blobfd8ede0aadcadc3b401f47f114517bc9a906b5c0
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/. */
6 #include "IEnumFE.h"
7 #include <algorithm>
9 CEnumFormatEtc::CEnumFormatEtc() : mRefCnt(0), mCurrentIdx(0) {}
11 // Constructor used by Clone()
12 CEnumFormatEtc::CEnumFormatEtc(nsTArray<FormatEtc>& aArray)
13 : mRefCnt(0), mCurrentIdx(0) {
14 // a deep copy, calls FormatEtc's copy constructor on each
15 mFormatList.AppendElements(aArray);
18 CEnumFormatEtc::~CEnumFormatEtc() {}
20 /* IUnknown impl. */
22 STDMETHODIMP
23 CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID* ppv) {
24 *ppv = nullptr;
26 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC))
27 *ppv = (LPVOID)this;
29 if (*ppv == nullptr) return E_NOINTERFACE;
31 // AddRef any interface we'll return.
32 ((LPUNKNOWN)*ppv)->AddRef();
33 return S_OK;
36 STDMETHODIMP_(ULONG)
37 CEnumFormatEtc::AddRef() {
38 ++mRefCnt;
39 NS_LOG_ADDREF(this, mRefCnt, "CEnumFormatEtc", sizeof(*this));
40 return mRefCnt;
43 STDMETHODIMP_(ULONG)
44 CEnumFormatEtc::Release() {
45 uint32_t refReturn;
47 refReturn = --mRefCnt;
48 NS_LOG_RELEASE(this, mRefCnt, "CEnumFormatEtc");
50 if (mRefCnt == 0) delete this;
52 return refReturn;
55 /* IEnumFORMATETC impl. */
57 STDMETHODIMP
58 CEnumFormatEtc::Next(ULONG aMaxToFetch, FORMATETC* aResult,
59 ULONG* aNumFetched) {
60 // If the method retrieves the number of items requested, the return
61 // value is S_OK. Otherwise, it is S_FALSE.
63 if (aNumFetched) *aNumFetched = 0;
65 // aNumFetched can be null if aMaxToFetch is 1
66 if (!aNumFetched && aMaxToFetch > 1) return S_FALSE;
68 if (!aResult) return S_FALSE;
70 // We're done walking the list
71 if (mCurrentIdx >= mFormatList.Length()) return S_FALSE;
73 uint32_t left = mFormatList.Length() - mCurrentIdx;
75 if (!aMaxToFetch) return S_FALSE;
77 uint32_t count = std::min(static_cast<uint32_t>(aMaxToFetch), left);
79 uint32_t idx = 0;
80 while (count > 0) {
81 // Copy out to aResult
82 mFormatList[mCurrentIdx++].CopyOut(&aResult[idx++]);
83 count--;
86 if (aNumFetched) *aNumFetched = idx;
88 return S_OK;
91 STDMETHODIMP
92 CEnumFormatEtc::Skip(ULONG aSkipNum) {
93 // If the method skips the number of items requested, the return value is
94 // S_OK. Otherwise, it is S_FALSE.
96 if ((mCurrentIdx + aSkipNum) >= mFormatList.Length()) return S_FALSE;
98 mCurrentIdx += aSkipNum;
100 return S_OK;
103 STDMETHODIMP
104 CEnumFormatEtc::Reset(void) {
105 mCurrentIdx = 0;
106 return S_OK;
109 STDMETHODIMP
110 CEnumFormatEtc::Clone(LPENUMFORMATETC* aResult) {
111 // Must return a new IEnumFORMATETC interface with the same iterative state.
113 if (!aResult) return E_INVALIDARG;
115 CEnumFormatEtc* pEnumObj = new CEnumFormatEtc(mFormatList);
117 if (!pEnumObj) return E_OUTOFMEMORY;
119 pEnumObj->AddRef();
120 pEnumObj->SetIndex(mCurrentIdx);
122 *aResult = pEnumObj;
124 return S_OK;
127 /* utils */
129 void CEnumFormatEtc::AddFormatEtc(LPFORMATETC aFormat) {
130 if (!aFormat) return;
131 FormatEtc* etc = mFormatList.AppendElement();
132 // Make a copy of aFormat
133 if (etc) etc->CopyIn(aFormat);
136 /* private */
138 void CEnumFormatEtc::SetIndex(uint32_t aIdx) { mCurrentIdx = aIdx; }