Bumping manifests a=b2g-bump
[gecko.git] / xpcom / glue / nsEnumeratorUtils.cpp
blob407ddac5f5a1a7e1770f1ead8ab6984398c69e78
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) MOZ_OVERRIDE;
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) MOZ_OVERRIDE;
106 NS_IMETHOD GetNext(nsISupports** aResult) MOZ_OVERRIDE;
108 explicit nsSingletonEnumerator(nsISupports* aValue);
110 private:
111 ~nsSingletonEnumerator();
113 protected:
114 nsCOMPtr<nsISupports> mValue;
115 bool mConsumed;
118 nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
119 : mValue(aValue)
121 mConsumed = (mValue ? false : true);
124 nsSingletonEnumerator::~nsSingletonEnumerator()
128 NS_IMPL_ISUPPORTS(nsSingletonEnumerator, nsISimpleEnumerator)
130 NS_IMETHODIMP
131 nsSingletonEnumerator::HasMoreElements(bool* aResult)
133 NS_PRECONDITION(aResult != 0, "null ptr");
134 if (!aResult) {
135 return NS_ERROR_NULL_POINTER;
138 *aResult = !mConsumed;
139 return NS_OK;
143 NS_IMETHODIMP
144 nsSingletonEnumerator::GetNext(nsISupports** aResult)
146 NS_PRECONDITION(aResult != 0, "null ptr");
147 if (!aResult) {
148 return NS_ERROR_NULL_POINTER;
151 if (mConsumed) {
152 return NS_ERROR_UNEXPECTED;
155 mConsumed = true;
157 *aResult = mValue;
158 NS_ADDREF(*aResult);
159 return NS_OK;
162 nsresult
163 NS_NewSingletonEnumerator(nsISimpleEnumerator** aResult,
164 nsISupports* aSingleton)
166 nsSingletonEnumerator* enumer = new nsSingletonEnumerator(aSingleton);
167 if (!enumer) {
168 return NS_ERROR_OUT_OF_MEMORY;
170 *aResult = enumer;
171 NS_ADDREF(*aResult);
172 return NS_OK;
175 ////////////////////////////////////////////////////////////////////////////////
177 class nsUnionEnumerator MOZ_FINAL : public nsISimpleEnumerator
179 public:
180 NS_DECL_ISUPPORTS
182 // nsISimpleEnumerator methods
183 NS_IMETHOD HasMoreElements(bool* aResult) MOZ_OVERRIDE;
184 NS_IMETHOD GetNext(nsISupports** aResult) MOZ_OVERRIDE;
186 nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
187 nsISimpleEnumerator* aSecondEnumerator);
189 private:
190 ~nsUnionEnumerator();
192 protected:
193 nsCOMPtr<nsISimpleEnumerator> mFirstEnumerator, mSecondEnumerator;
194 bool mConsumed;
195 bool mAtSecond;
198 nsUnionEnumerator::nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
199 nsISimpleEnumerator* aSecondEnumerator)
200 : mFirstEnumerator(aFirstEnumerator)
201 , mSecondEnumerator(aSecondEnumerator)
202 , mConsumed(false)
203 , mAtSecond(false)
207 nsUnionEnumerator::~nsUnionEnumerator()
211 NS_IMPL_ISUPPORTS(nsUnionEnumerator, nsISimpleEnumerator)
213 NS_IMETHODIMP
214 nsUnionEnumerator::HasMoreElements(bool* aResult)
216 NS_PRECONDITION(aResult != 0, "null ptr");
217 if (!aResult) {
218 return NS_ERROR_NULL_POINTER;
221 nsresult rv;
223 if (mConsumed) {
224 *aResult = false;
225 return NS_OK;
228 if (!mAtSecond) {
229 rv = mFirstEnumerator->HasMoreElements(aResult);
230 if (NS_FAILED(rv)) {
231 return rv;
234 if (*aResult) {
235 return NS_OK;
238 mAtSecond = true;
241 rv = mSecondEnumerator->HasMoreElements(aResult);
242 if (NS_FAILED(rv)) {
243 return rv;
246 if (*aResult) {
247 return NS_OK;
250 *aResult = false;
251 mConsumed = true;
252 return NS_OK;
255 NS_IMETHODIMP
256 nsUnionEnumerator::GetNext(nsISupports** aResult)
258 NS_PRECONDITION(aResult != 0, "null ptr");
259 if (!aResult) {
260 return NS_ERROR_NULL_POINTER;
263 if (mConsumed) {
264 return NS_ERROR_UNEXPECTED;
267 if (!mAtSecond) {
268 return mFirstEnumerator->GetNext(aResult);
271 return mSecondEnumerator->GetNext(aResult);
274 nsresult
275 NS_NewUnionEnumerator(nsISimpleEnumerator** aResult,
276 nsISimpleEnumerator* aFirstEnumerator,
277 nsISimpleEnumerator* aSecondEnumerator)
279 *aResult = nullptr;
280 if (!aFirstEnumerator) {
281 *aResult = aSecondEnumerator;
282 } else if (!aSecondEnumerator) {
283 *aResult = aFirstEnumerator;
284 } else {
285 nsUnionEnumerator* enumer = new nsUnionEnumerator(aFirstEnumerator,
286 aSecondEnumerator);
287 if (!enumer) {
288 return NS_ERROR_OUT_OF_MEMORY;
290 *aResult = enumer;
292 NS_ADDREF(*aResult);
293 return NS_OK;