Bug 1860492 - Change file name in test @ toolkit/components/antitracking/test/browser...
[gecko.git] / xpcom / ds / nsEnumeratorUtils.cpp
blob69631818a3d14387c7122731847c6c7adc61069c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/Attributes.h"
9 #include "nsEnumeratorUtils.h"
11 #include "nsIStringEnumerator.h"
12 #include "nsSimpleEnumerator.h"
14 #include "nsCOMPtr.h"
15 #include "mozilla/RefPtr.h"
17 class EmptyEnumeratorImpl : public nsSimpleEnumerator,
18 public nsIUTF8StringEnumerator,
19 public nsIStringEnumerator {
20 public:
21 EmptyEnumeratorImpl() = default;
23 // nsISupports interface. Not really inherited, but no mRefCnt.
24 NS_DECL_ISUPPORTS_INHERITED
26 // nsISimpleEnumerator
27 NS_DECL_NSISIMPLEENUMERATOR
28 NS_DECL_NSIUTF8STRINGENUMERATOR
29 NS_DECL_NSISTRINGENUMERATORBASE
30 // can't use NS_DECL_NSISTRINGENUMERATOR because they share the
31 // HasMore() signature
33 NS_IMETHOD GetNext(nsAString& aResult) override;
35 static EmptyEnumeratorImpl* GetInstance() {
36 static const EmptyEnumeratorImpl kInstance;
37 return const_cast<EmptyEnumeratorImpl*>(&kInstance);
41 // nsISupports interface
42 NS_IMETHODIMP_(MozExternalRefCountType)
43 EmptyEnumeratorImpl::AddRef(void) { return 2; }
45 NS_IMETHODIMP_(MozExternalRefCountType)
46 EmptyEnumeratorImpl::Release(void) { return 1; }
48 NS_IMPL_QUERY_INTERFACE_INHERITED(EmptyEnumeratorImpl, nsSimpleEnumerator,
49 nsIUTF8StringEnumerator, nsIStringEnumerator)
51 // nsISimpleEnumerator interface
52 NS_IMETHODIMP
53 EmptyEnumeratorImpl::HasMoreElements(bool* aResult) {
54 *aResult = false;
55 return NS_OK;
58 NS_IMETHODIMP
59 EmptyEnumeratorImpl::HasMore(bool* aResult) {
60 *aResult = false;
61 return NS_OK;
64 NS_IMETHODIMP
65 EmptyEnumeratorImpl::GetNext(nsISupports** aResult) { return NS_ERROR_FAILURE; }
67 NS_IMETHODIMP
68 EmptyEnumeratorImpl::GetNext(nsACString& aResult) {
69 return NS_ERROR_UNEXPECTED;
72 NS_IMETHODIMP
73 EmptyEnumeratorImpl::GetNext(nsAString& aResult) { return NS_ERROR_UNEXPECTED; }
75 NS_IMETHODIMP
76 EmptyEnumeratorImpl::StringIterator(nsIJSEnumerator** aRetVal) {
77 return NS_ERROR_NOT_IMPLEMENTED;
80 nsresult NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult) {
81 *aResult = EmptyEnumeratorImpl::GetInstance();
82 return NS_OK;
85 ////////////////////////////////////////////////////////////////////////////////
87 class nsSingletonEnumerator final : public nsSimpleEnumerator {
88 public:
89 // nsISimpleEnumerator methods
90 NS_IMETHOD HasMoreElements(bool* aResult) override;
91 NS_IMETHOD GetNext(nsISupports** aResult) override;
93 explicit nsSingletonEnumerator(nsISupports* aValue);
95 private:
96 ~nsSingletonEnumerator() override;
98 protected:
99 nsCOMPtr<nsISupports> mValue;
100 bool mConsumed;
103 nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
104 : mValue(aValue) {
105 mConsumed = (mValue ? false : true);
108 nsSingletonEnumerator::~nsSingletonEnumerator() = default;
110 NS_IMETHODIMP
111 nsSingletonEnumerator::HasMoreElements(bool* aResult) {
112 MOZ_ASSERT(aResult != 0, "null ptr");
113 if (!aResult) {
114 return NS_ERROR_NULL_POINTER;
117 *aResult = !mConsumed;
118 return NS_OK;
121 NS_IMETHODIMP
122 nsSingletonEnumerator::GetNext(nsISupports** aResult) {
123 MOZ_ASSERT(aResult != 0, "null ptr");
124 if (!aResult) {
125 return NS_ERROR_NULL_POINTER;
128 if (mConsumed) {
129 return NS_ERROR_FAILURE;
132 mConsumed = true;
134 *aResult = mValue;
135 NS_ADDREF(*aResult);
136 return NS_OK;
139 nsresult NS_NewSingletonEnumerator(nsISimpleEnumerator** aResult,
140 nsISupports* aSingleton) {
141 RefPtr<nsSingletonEnumerator> enumer = new nsSingletonEnumerator(aSingleton);
142 enumer.forget(aResult);
143 return NS_OK;
146 ////////////////////////////////////////////////////////////////////////////////
148 class nsUnionEnumerator final : public nsSimpleEnumerator {
149 public:
150 // nsISimpleEnumerator methods
151 NS_IMETHOD HasMoreElements(bool* aResult) override;
152 NS_IMETHOD GetNext(nsISupports** aResult) override;
154 nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
155 nsISimpleEnumerator* aSecondEnumerator);
157 private:
158 ~nsUnionEnumerator() override;
160 protected:
161 nsCOMPtr<nsISimpleEnumerator> mFirstEnumerator, mSecondEnumerator;
162 bool mConsumed;
163 bool mAtSecond;
166 nsUnionEnumerator::nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
167 nsISimpleEnumerator* aSecondEnumerator)
168 : mFirstEnumerator(aFirstEnumerator),
169 mSecondEnumerator(aSecondEnumerator),
170 mConsumed(false),
171 mAtSecond(false) {}
173 nsUnionEnumerator::~nsUnionEnumerator() = default;
175 NS_IMETHODIMP
176 nsUnionEnumerator::HasMoreElements(bool* aResult) {
177 MOZ_ASSERT(aResult != 0, "null ptr");
178 if (!aResult) {
179 return NS_ERROR_NULL_POINTER;
182 nsresult rv;
184 if (mConsumed) {
185 *aResult = false;
186 return NS_OK;
189 if (!mAtSecond) {
190 rv = mFirstEnumerator->HasMoreElements(aResult);
191 if (NS_FAILED(rv)) {
192 return rv;
195 if (*aResult) {
196 return NS_OK;
199 mAtSecond = true;
202 rv = mSecondEnumerator->HasMoreElements(aResult);
203 if (NS_FAILED(rv)) {
204 return rv;
207 if (*aResult) {
208 return NS_OK;
211 *aResult = false;
212 mConsumed = true;
213 return NS_OK;
216 NS_IMETHODIMP
217 nsUnionEnumerator::GetNext(nsISupports** aResult) {
218 MOZ_ASSERT(aResult != 0, "null ptr");
219 if (!aResult) {
220 return NS_ERROR_NULL_POINTER;
223 if (mConsumed) {
224 return NS_ERROR_FAILURE;
227 if (!mAtSecond) {
228 return mFirstEnumerator->GetNext(aResult);
231 return mSecondEnumerator->GetNext(aResult);
234 nsresult NS_NewUnionEnumerator(nsISimpleEnumerator** aResult,
235 nsISimpleEnumerator* aFirstEnumerator,
236 nsISimpleEnumerator* aSecondEnumerator) {
237 *aResult = nullptr;
238 if (!aFirstEnumerator) {
239 *aResult = aSecondEnumerator;
240 } else if (!aSecondEnumerator) {
241 *aResult = aFirstEnumerator;
242 } else {
243 auto* enumer = new nsUnionEnumerator(aFirstEnumerator, aSecondEnumerator);
244 *aResult = enumer;
246 NS_ADDREF(*aResult);
247 return NS_OK;