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/. */
7 #include "nsAlgorithm.h"
10 CEnumFormatEtc::CEnumFormatEtc() : mRefCnt(0), mCurrentIdx(0) {}
12 // Constructor used by Clone()
13 CEnumFormatEtc::CEnumFormatEtc(nsTArray
<FormatEtc
>& aArray
)
14 : mRefCnt(0), mCurrentIdx(0) {
15 // a deep copy, calls FormatEtc's copy constructor on each
16 mFormatList
.AppendElements(aArray
);
19 CEnumFormatEtc::~CEnumFormatEtc() {}
24 CEnumFormatEtc::QueryInterface(REFIID riid
, LPVOID
* ppv
) {
27 if (IsEqualIID(riid
, IID_IUnknown
) || IsEqualIID(riid
, IID_IEnumFORMATETC
))
30 if (*ppv
== nullptr) return E_NOINTERFACE
;
32 // AddRef any interface we'll return.
33 ((LPUNKNOWN
)*ppv
)->AddRef();
38 CEnumFormatEtc::AddRef() {
40 NS_LOG_ADDREF(this, mRefCnt
, "CEnumFormatEtc", sizeof(*this));
45 CEnumFormatEtc::Release() {
48 refReturn
= --mRefCnt
;
49 NS_LOG_RELEASE(this, mRefCnt
, "CEnumFormatEtc");
51 if (mRefCnt
== 0) delete this;
56 /* IEnumFORMATETC impl. */
59 CEnumFormatEtc::Next(ULONG aMaxToFetch
, FORMATETC
* aResult
,
61 // If the method retrieves the number of items requested, the return
62 // value is S_OK. Otherwise, it is S_FALSE.
64 if (aNumFetched
) *aNumFetched
= 0;
66 // aNumFetched can be null if aMaxToFetch is 1
67 if (!aNumFetched
&& aMaxToFetch
> 1) return S_FALSE
;
69 if (!aResult
) return S_FALSE
;
71 // We're done walking the list
72 if (mCurrentIdx
>= mFormatList
.Length()) return S_FALSE
;
74 uint32_t left
= mFormatList
.Length() - mCurrentIdx
;
76 if (!aMaxToFetch
) return S_FALSE
;
78 uint32_t count
= std::min(static_cast<uint32_t>(aMaxToFetch
), left
);
82 // Copy out to aResult
83 mFormatList
[mCurrentIdx
++].CopyOut(&aResult
[idx
++]);
87 if (aNumFetched
) *aNumFetched
= idx
;
93 CEnumFormatEtc::Skip(ULONG aSkipNum
) {
94 // If the method skips the number of items requested, the return value is
95 // S_OK. Otherwise, it is S_FALSE.
97 if ((mCurrentIdx
+ aSkipNum
) >= mFormatList
.Length()) return S_FALSE
;
99 mCurrentIdx
+= aSkipNum
;
105 CEnumFormatEtc::Reset(void) {
111 CEnumFormatEtc::Clone(LPENUMFORMATETC
* aResult
) {
112 // Must return a new IEnumFORMATETC interface with the same iterative state.
114 if (!aResult
) return E_INVALIDARG
;
116 CEnumFormatEtc
* pEnumObj
= new CEnumFormatEtc(mFormatList
);
118 if (!pEnumObj
) return E_OUTOFMEMORY
;
121 pEnumObj
->SetIndex(mCurrentIdx
);
130 void CEnumFormatEtc::AddFormatEtc(LPFORMATETC aFormat
) {
131 if (!aFormat
) return;
132 FormatEtc
* etc
= mFormatList
.AppendElement();
133 // Make a copy of aFormat
134 if (etc
) etc
->CopyIn(aFormat
);
139 void CEnumFormatEtc::SetIndex(uint32_t aIdx
) { mCurrentIdx
= aIdx
; }