Bumping manifests a=b2g-bump
[gecko.git] / xpcom / glue / nsEnumeratorUtils.cpp
blobdf7d61e42623f4575973bfe3e764602d1c761a66
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 "nsISimpleEnumerator.h"
12 #include "nsIStringEnumerator.h"
14 #include "nsCOMPtr.h"
16 class EmptyEnumeratorImpl
17 : public nsISimpleEnumerator
18 , public nsIUTF8StringEnumerator
19 , public nsIStringEnumerator
21 public:
22 EmptyEnumeratorImpl() {}
24 // nsISupports interface
25 NS_DECL_ISUPPORTS_INHERITED // not really inherited, but no mRefCnt
27 // nsISimpleEnumerator
28 NS_DECL_NSISIMPLEENUMERATOR
29 NS_DECL_NSIUTF8STRINGENUMERATOR
30 // can't use NS_DECL_NSISTRINGENUMERATOR because they share the
31 // HasMore() signature
32 NS_IMETHOD GetNext(nsAString& aResult);
34 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)
45 return 2;
48 NS_IMETHODIMP_(MozExternalRefCountType)
49 EmptyEnumeratorImpl::Release(void)
51 return 1;
54 NS_IMPL_QUERY_INTERFACE(EmptyEnumeratorImpl, nsISimpleEnumerator,
55 nsIUTF8StringEnumerator, nsIStringEnumerator)
57 // nsISimpleEnumerator interface
58 NS_IMETHODIMP
59 EmptyEnumeratorImpl::HasMoreElements(bool* aResult)
61 *aResult = false;
62 return NS_OK;
65 NS_IMETHODIMP
66 EmptyEnumeratorImpl::HasMore(bool* aResult)
68 *aResult = false;
69 return NS_OK;
72 NS_IMETHODIMP
73 EmptyEnumeratorImpl::GetNext(nsISupports** aResult)
75 return NS_ERROR_UNEXPECTED;
78 NS_IMETHODIMP
79 EmptyEnumeratorImpl::GetNext(nsACString& aResult)
81 return NS_ERROR_UNEXPECTED;
84 NS_IMETHODIMP
85 EmptyEnumeratorImpl::GetNext(nsAString& aResult)
87 return NS_ERROR_UNEXPECTED;
90 nsresult
91 NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult)
93 *aResult = EmptyEnumeratorImpl::GetInstance();
94 return NS_OK;
97 ////////////////////////////////////////////////////////////////////////////////
99 class nsSingletonEnumerator MOZ_FINAL : public nsISimpleEnumerator
101 public:
102 NS_DECL_ISUPPORTS
104 // nsISimpleEnumerator methods
105 NS_IMETHOD HasMoreElements(bool* aResult);
106 NS_IMETHOD GetNext(nsISupports** aResult);
108 explicit nsSingletonEnumerator(nsISupports* aValue);
110 private:
111 ~nsSingletonEnumerator();
113 protected:
114 nsISupports* mValue;
115 bool mConsumed;
118 nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
119 : mValue(aValue)
121 NS_IF_ADDREF(mValue);
122 mConsumed = (mValue ? false : true);
125 nsSingletonEnumerator::~nsSingletonEnumerator()
127 NS_IF_RELEASE(mValue);
130 NS_IMPL_ISUPPORTS(nsSingletonEnumerator, nsISimpleEnumerator)
132 NS_IMETHODIMP
133 nsSingletonEnumerator::HasMoreElements(bool* aResult)
135 NS_PRECONDITION(aResult != 0, "null ptr");
136 if (!aResult) {
137 return NS_ERROR_NULL_POINTER;
140 *aResult = !mConsumed;
141 return NS_OK;
145 NS_IMETHODIMP
146 nsSingletonEnumerator::GetNext(nsISupports** aResult)
148 NS_PRECONDITION(aResult != 0, "null ptr");
149 if (!aResult) {
150 return NS_ERROR_NULL_POINTER;
153 if (mConsumed) {
154 return NS_ERROR_UNEXPECTED;
157 mConsumed = true;
159 *aResult = mValue;
160 NS_ADDREF(*aResult);
161 return NS_OK;
164 nsresult
165 NS_NewSingletonEnumerator(nsISimpleEnumerator** aResult,
166 nsISupports* aSingleton)
168 nsSingletonEnumerator* enumer = new nsSingletonEnumerator(aSingleton);
169 if (!enumer) {
170 return NS_ERROR_OUT_OF_MEMORY;
172 *aResult = enumer;
173 NS_ADDREF(*aResult);
174 return NS_OK;
177 ////////////////////////////////////////////////////////////////////////////////
179 class nsUnionEnumerator MOZ_FINAL : public nsISimpleEnumerator
181 public:
182 NS_DECL_ISUPPORTS
184 // nsISimpleEnumerator methods
185 NS_IMETHOD HasMoreElements(bool* aResult);
186 NS_IMETHOD GetNext(nsISupports** aResult);
188 nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
189 nsISimpleEnumerator* aSecondEnumerator);
191 private:
192 ~nsUnionEnumerator();
194 protected:
195 nsCOMPtr<nsISimpleEnumerator> mFirstEnumerator, mSecondEnumerator;
196 bool mConsumed;
197 bool mAtSecond;
200 nsUnionEnumerator::nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
201 nsISimpleEnumerator* aSecondEnumerator)
202 : mFirstEnumerator(aFirstEnumerator)
203 , mSecondEnumerator(aSecondEnumerator)
204 , mConsumed(false)
205 , mAtSecond(false)
209 nsUnionEnumerator::~nsUnionEnumerator()
213 NS_IMPL_ISUPPORTS(nsUnionEnumerator, nsISimpleEnumerator)
215 NS_IMETHODIMP
216 nsUnionEnumerator::HasMoreElements(bool* aResult)
218 NS_PRECONDITION(aResult != 0, "null ptr");
219 if (!aResult) {
220 return NS_ERROR_NULL_POINTER;
223 nsresult rv;
225 if (mConsumed) {
226 *aResult = false;
227 return NS_OK;
230 if (!mAtSecond) {
231 rv = mFirstEnumerator->HasMoreElements(aResult);
232 if (NS_FAILED(rv)) {
233 return rv;
236 if (*aResult) {
237 return NS_OK;
240 mAtSecond = true;
243 rv = mSecondEnumerator->HasMoreElements(aResult);
244 if (NS_FAILED(rv)) {
245 return rv;
248 if (*aResult) {
249 return NS_OK;
252 *aResult = false;
253 mConsumed = true;
254 return NS_OK;
257 NS_IMETHODIMP
258 nsUnionEnumerator::GetNext(nsISupports** aResult)
260 NS_PRECONDITION(aResult != 0, "null ptr");
261 if (!aResult) {
262 return NS_ERROR_NULL_POINTER;
265 if (mConsumed) {
266 return NS_ERROR_UNEXPECTED;
269 if (!mAtSecond) {
270 return mFirstEnumerator->GetNext(aResult);
273 return mSecondEnumerator->GetNext(aResult);
276 nsresult
277 NS_NewUnionEnumerator(nsISimpleEnumerator** aResult,
278 nsISimpleEnumerator* aFirstEnumerator,
279 nsISimpleEnumerator* aSecondEnumerator)
281 *aResult = nullptr;
282 if (!aFirstEnumerator) {
283 *aResult = aSecondEnumerator;
284 } else if (!aSecondEnumerator) {
285 *aResult = aFirstEnumerator;
286 } else {
287 nsUnionEnumerator* enumer = new nsUnionEnumerator(aFirstEnumerator,
288 aSecondEnumerator);
289 if (!enumer) {
290 return NS_ERROR_OUT_OF_MEMORY;
292 *aResult = enumer;
294 NS_ADDREF(*aResult);
295 return NS_OK;