From baad25e39733dfc3dd310198fdcced00ffbef68b Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Tue, 23 Nov 2021 00:13:32 -0500 Subject: Issue %3005 - Move widget/ to system/interface --- system/interface/windows/IEnumFE.cpp | 173 +++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 system/interface/windows/IEnumFE.cpp (limited to 'system/interface/windows/IEnumFE.cpp') diff --git a/system/interface/windows/IEnumFE.cpp b/system/interface/windows/IEnumFE.cpp new file mode 100644 index 000000000..4fa76258b --- /dev/null +++ b/system/interface/windows/IEnumFE.cpp @@ -0,0 +1,173 @@ +/* -*- 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/. */ + +#include "IEnumFE.h" +#include "nsAlgorithm.h" +#include + +CEnumFormatEtc::CEnumFormatEtc() : + mRefCnt(0), + mCurrentIdx(0) +{ +} + +// Constructor used by Clone() +CEnumFormatEtc::CEnumFormatEtc(nsTArray& aArray) : + mRefCnt(0), + mCurrentIdx(0) +{ + // a deep copy, calls FormatEtc's copy constructor on each + mFormatList.AppendElements(aArray); +} + +CEnumFormatEtc::~CEnumFormatEtc() +{ +} + +/* IUnknown impl. */ + +STDMETHODIMP +CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID *ppv) +{ + *ppv = nullptr; + + if (IsEqualIID(riid, IID_IUnknown) || + IsEqualIID(riid, IID_IEnumFORMATETC)) + *ppv = (LPVOID)this; + + if (*ppv == nullptr) + return E_NOINTERFACE; + + // AddRef any interface we'll return. + ((LPUNKNOWN)*ppv)->AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) +CEnumFormatEtc::AddRef() +{ + ++mRefCnt; + NS_LOG_ADDREF(this, mRefCnt, "CEnumFormatEtc",sizeof(*this)); + return mRefCnt; +} + +STDMETHODIMP_(ULONG) +CEnumFormatEtc::Release() +{ + uint32_t refReturn; + + refReturn = --mRefCnt; + NS_LOG_RELEASE(this, mRefCnt, "CEnumFormatEtc"); + + if (mRefCnt == 0) + delete this; + + return refReturn; +} + +/* IEnumFORMATETC impl. */ + +STDMETHODIMP +CEnumFormatEtc::Next(ULONG aMaxToFetch, FORMATETC *aResult, ULONG *aNumFetched) +{ + // If the method retrieves the number of items requested, the return + // value is S_OK. Otherwise, it is S_FALSE. + + if (aNumFetched) + *aNumFetched = 0; + + // aNumFetched can be null if aMaxToFetch is 1 + if (!aNumFetched && aMaxToFetch > 1) + return S_FALSE; + + if (!aResult) + return S_FALSE; + + // We're done walking the list + if (mCurrentIdx >= mFormatList.Length()) + return S_FALSE; + + uint32_t left = mFormatList.Length() - mCurrentIdx; + + if (!aMaxToFetch) + return S_FALSE; + + uint32_t count = std::min(static_cast(aMaxToFetch), left); + + uint32_t idx = 0; + while (count > 0) { + // Copy out to aResult + mFormatList[mCurrentIdx++].CopyOut(&aResult[idx++]); + count--; + } + + if (aNumFetched) + *aNumFetched = idx; + + return S_OK; +} + +STDMETHODIMP +CEnumFormatEtc::Skip(ULONG aSkipNum) +{ + // If the method skips the number of items requested, the return value is S_OK. + // Otherwise, it is S_FALSE. + + if ((mCurrentIdx + aSkipNum) >= mFormatList.Length()) + return S_FALSE; + + mCurrentIdx += aSkipNum; + + return S_OK; +} + +STDMETHODIMP +CEnumFormatEtc::Reset(void) +{ + mCurrentIdx = 0; + return S_OK; +} + +STDMETHODIMP +CEnumFormatEtc::Clone(LPENUMFORMATETC *aResult) +{ + // Must return a new IEnumFORMATETC interface with the same iterative state. + + if (!aResult) + return E_INVALIDARG; + + CEnumFormatEtc * pEnumObj = new CEnumFormatEtc(mFormatList); + + if (!pEnumObj) + return E_OUTOFMEMORY; + + pEnumObj->AddRef(); + pEnumObj->SetIndex(mCurrentIdx); + + *aResult = pEnumObj; + + return S_OK; +} + +/* utils */ + +void +CEnumFormatEtc::AddFormatEtc(LPFORMATETC aFormat) +{ + if (!aFormat) + return; + FormatEtc * etc = mFormatList.AppendElement(); + // Make a copy of aFormat + if (etc) + etc->CopyIn(aFormat); +} + +/* private */ + +void +CEnumFormatEtc::SetIndex(uint32_t aIdx) +{ + mCurrentIdx = aIdx; +} -- cgit v1.2.3