1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/windows/IEnumFE.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,173 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "IEnumFE.h" 1.10 +#include "nsAlgorithm.h" 1.11 +#include <algorithm> 1.12 + 1.13 +CEnumFormatEtc::CEnumFormatEtc() : 1.14 + mRefCnt(0), 1.15 + mCurrentIdx(0) 1.16 +{ 1.17 +} 1.18 + 1.19 +// Constructor used by Clone() 1.20 +CEnumFormatEtc::CEnumFormatEtc(nsTArray<FormatEtc>& aArray) : 1.21 + mRefCnt(0), 1.22 + mCurrentIdx(0) 1.23 +{ 1.24 + // a deep copy, calls FormatEtc's copy constructor on each 1.25 + mFormatList.AppendElements(aArray); 1.26 +} 1.27 + 1.28 +CEnumFormatEtc::~CEnumFormatEtc() 1.29 +{ 1.30 +} 1.31 + 1.32 +/* IUnknown impl. */ 1.33 + 1.34 +STDMETHODIMP 1.35 +CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID *ppv) 1.36 +{ 1.37 + *ppv = nullptr; 1.38 + 1.39 + if (IsEqualIID(riid, IID_IUnknown) || 1.40 + IsEqualIID(riid, IID_IEnumFORMATETC)) 1.41 + *ppv = (LPVOID)this; 1.42 + 1.43 + if (*ppv == nullptr) 1.44 + return E_NOINTERFACE; 1.45 + 1.46 + // AddRef any interface we'll return. 1.47 + ((LPUNKNOWN)*ppv)->AddRef(); 1.48 + return S_OK; 1.49 +} 1.50 + 1.51 +STDMETHODIMP_(ULONG) 1.52 +CEnumFormatEtc::AddRef() 1.53 +{ 1.54 + ++mRefCnt; 1.55 + NS_LOG_ADDREF(this, mRefCnt, "CEnumFormatEtc",sizeof(*this)); 1.56 + return mRefCnt; 1.57 +} 1.58 + 1.59 +STDMETHODIMP_(ULONG) 1.60 +CEnumFormatEtc::Release() 1.61 +{ 1.62 + uint32_t refReturn; 1.63 + 1.64 + refReturn = --mRefCnt; 1.65 + NS_LOG_RELEASE(this, mRefCnt, "CEnumFormatEtc"); 1.66 + 1.67 + if (mRefCnt == 0) 1.68 + delete this; 1.69 + 1.70 + return refReturn; 1.71 +} 1.72 + 1.73 +/* IEnumFORMATETC impl. */ 1.74 + 1.75 +STDMETHODIMP 1.76 +CEnumFormatEtc::Next(ULONG aMaxToFetch, FORMATETC *aResult, ULONG *aNumFetched) 1.77 +{ 1.78 + // If the method retrieves the number of items requested, the return 1.79 + // value is S_OK. Otherwise, it is S_FALSE. 1.80 + 1.81 + if (aNumFetched) 1.82 + *aNumFetched = 0; 1.83 + 1.84 + // aNumFetched can be null if aMaxToFetch is 1 1.85 + if (!aNumFetched && aMaxToFetch > 1) 1.86 + return S_FALSE; 1.87 + 1.88 + if (!aResult) 1.89 + return S_FALSE; 1.90 + 1.91 + // We're done walking the list 1.92 + if (mCurrentIdx >= mFormatList.Length()) 1.93 + return S_FALSE; 1.94 + 1.95 + uint32_t left = mFormatList.Length() - mCurrentIdx; 1.96 + 1.97 + if (!aMaxToFetch) 1.98 + return S_FALSE; 1.99 + 1.100 + uint32_t count = std::min(static_cast<uint32_t>(aMaxToFetch), left); 1.101 + 1.102 + uint32_t idx = 0; 1.103 + while (count > 0) { 1.104 + // Copy out to aResult 1.105 + mFormatList[mCurrentIdx++].CopyOut(&aResult[idx++]); 1.106 + count--; 1.107 + } 1.108 + 1.109 + if (aNumFetched) 1.110 + *aNumFetched = idx; 1.111 + 1.112 + return S_OK; 1.113 +} 1.114 + 1.115 +STDMETHODIMP 1.116 +CEnumFormatEtc::Skip(ULONG aSkipNum) 1.117 +{ 1.118 + // If the method skips the number of items requested, the return value is S_OK. 1.119 + // Otherwise, it is S_FALSE. 1.120 + 1.121 + if ((mCurrentIdx + aSkipNum) >= mFormatList.Length()) 1.122 + return S_FALSE; 1.123 + 1.124 + mCurrentIdx += aSkipNum; 1.125 + 1.126 + return S_OK; 1.127 +} 1.128 + 1.129 +STDMETHODIMP 1.130 +CEnumFormatEtc::Reset(void) 1.131 +{ 1.132 + mCurrentIdx = 0; 1.133 + return S_OK; 1.134 +} 1.135 + 1.136 +STDMETHODIMP 1.137 +CEnumFormatEtc::Clone(LPENUMFORMATETC *aResult) 1.138 +{ 1.139 + // Must return a new IEnumFORMATETC interface with the same iterative state. 1.140 + 1.141 + if (!aResult) 1.142 + return E_INVALIDARG; 1.143 + 1.144 + CEnumFormatEtc * pEnumObj = new CEnumFormatEtc(mFormatList); 1.145 + 1.146 + if (!pEnumObj) 1.147 + return E_OUTOFMEMORY; 1.148 + 1.149 + pEnumObj->AddRef(); 1.150 + pEnumObj->SetIndex(mCurrentIdx); 1.151 + 1.152 + *aResult = pEnumObj; 1.153 + 1.154 + return S_OK; 1.155 +} 1.156 + 1.157 +/* utils */ 1.158 + 1.159 +void 1.160 +CEnumFormatEtc::AddFormatEtc(LPFORMATETC aFormat) 1.161 +{ 1.162 + if (!aFormat) 1.163 + return; 1.164 + FormatEtc * etc = mFormatList.AppendElement(); 1.165 + // Make a copy of aFormat 1.166 + if (etc) 1.167 + etc->CopyIn(aFormat); 1.168 +} 1.169 + 1.170 +/* private */ 1.171 + 1.172 +void 1.173 +CEnumFormatEtc::SetIndex(uint32_t aIdx) 1.174 +{ 1.175 + mCurrentIdx = aIdx; 1.176 +}