nsEnumeratorUtils.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "mozilla/Attributes.h"
  6. #include "nsEnumeratorUtils.h"
  7. #include "nsISimpleEnumerator.h"
  8. #include "nsIStringEnumerator.h"
  9. #include "nsCOMPtr.h"
  10. #include "mozilla/RefPtr.h"
  11. class EmptyEnumeratorImpl
  12. : public nsISimpleEnumerator
  13. , public nsIUTF8StringEnumerator
  14. , public nsIStringEnumerator
  15. {
  16. public:
  17. EmptyEnumeratorImpl() {}
  18. // nsISupports interface
  19. NS_DECL_ISUPPORTS_INHERITED // not really inherited, but no mRefCnt
  20. // nsISimpleEnumerator
  21. NS_DECL_NSISIMPLEENUMERATOR
  22. NS_DECL_NSIUTF8STRINGENUMERATOR
  23. // can't use NS_DECL_NSISTRINGENUMERATOR because they share the
  24. // HasMore() signature
  25. NS_IMETHOD GetNext(nsAString& aResult) override;
  26. static EmptyEnumeratorImpl* GetInstance()
  27. {
  28. static const EmptyEnumeratorImpl kInstance;
  29. return const_cast<EmptyEnumeratorImpl*>(&kInstance);
  30. }
  31. };
  32. // nsISupports interface
  33. NS_IMETHODIMP_(MozExternalRefCountType)
  34. EmptyEnumeratorImpl::AddRef(void)
  35. {
  36. return 2;
  37. }
  38. NS_IMETHODIMP_(MozExternalRefCountType)
  39. EmptyEnumeratorImpl::Release(void)
  40. {
  41. return 1;
  42. }
  43. NS_IMPL_QUERY_INTERFACE(EmptyEnumeratorImpl, nsISimpleEnumerator,
  44. nsIUTF8StringEnumerator, nsIStringEnumerator)
  45. // nsISimpleEnumerator interface
  46. NS_IMETHODIMP
  47. EmptyEnumeratorImpl::HasMoreElements(bool* aResult)
  48. {
  49. *aResult = false;
  50. return NS_OK;
  51. }
  52. NS_IMETHODIMP
  53. EmptyEnumeratorImpl::HasMore(bool* aResult)
  54. {
  55. *aResult = false;
  56. return NS_OK;
  57. }
  58. NS_IMETHODIMP
  59. EmptyEnumeratorImpl::GetNext(nsISupports** aResult)
  60. {
  61. return NS_ERROR_UNEXPECTED;
  62. }
  63. NS_IMETHODIMP
  64. EmptyEnumeratorImpl::GetNext(nsACString& aResult)
  65. {
  66. return NS_ERROR_UNEXPECTED;
  67. }
  68. NS_IMETHODIMP
  69. EmptyEnumeratorImpl::GetNext(nsAString& aResult)
  70. {
  71. return NS_ERROR_UNEXPECTED;
  72. }
  73. nsresult
  74. NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult)
  75. {
  76. *aResult = EmptyEnumeratorImpl::GetInstance();
  77. return NS_OK;
  78. }
  79. ////////////////////////////////////////////////////////////////////////////////
  80. class nsSingletonEnumerator final : public nsISimpleEnumerator
  81. {
  82. public:
  83. NS_DECL_ISUPPORTS
  84. // nsISimpleEnumerator methods
  85. NS_IMETHOD HasMoreElements(bool* aResult) override;
  86. NS_IMETHOD GetNext(nsISupports** aResult) override;
  87. explicit nsSingletonEnumerator(nsISupports* aValue);
  88. private:
  89. ~nsSingletonEnumerator();
  90. protected:
  91. nsCOMPtr<nsISupports> mValue;
  92. bool mConsumed;
  93. };
  94. nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
  95. : mValue(aValue)
  96. {
  97. mConsumed = (mValue ? false : true);
  98. }
  99. nsSingletonEnumerator::~nsSingletonEnumerator()
  100. {
  101. }
  102. NS_IMPL_ISUPPORTS(nsSingletonEnumerator, nsISimpleEnumerator)
  103. NS_IMETHODIMP
  104. nsSingletonEnumerator::HasMoreElements(bool* aResult)
  105. {
  106. NS_PRECONDITION(aResult != 0, "null ptr");
  107. if (!aResult) {
  108. return NS_ERROR_NULL_POINTER;
  109. }
  110. *aResult = !mConsumed;
  111. return NS_OK;
  112. }
  113. NS_IMETHODIMP
  114. nsSingletonEnumerator::GetNext(nsISupports** aResult)
  115. {
  116. NS_PRECONDITION(aResult != 0, "null ptr");
  117. if (!aResult) {
  118. return NS_ERROR_NULL_POINTER;
  119. }
  120. if (mConsumed) {
  121. return NS_ERROR_UNEXPECTED;
  122. }
  123. mConsumed = true;
  124. *aResult = mValue;
  125. NS_ADDREF(*aResult);
  126. return NS_OK;
  127. }
  128. nsresult
  129. NS_NewSingletonEnumerator(nsISimpleEnumerator** aResult,
  130. nsISupports* aSingleton)
  131. {
  132. RefPtr<nsSingletonEnumerator> enumer = new nsSingletonEnumerator(aSingleton);
  133. enumer.forget(aResult);
  134. return NS_OK;
  135. }
  136. ////////////////////////////////////////////////////////////////////////////////
  137. class nsUnionEnumerator final : public nsISimpleEnumerator
  138. {
  139. public:
  140. NS_DECL_ISUPPORTS
  141. // nsISimpleEnumerator methods
  142. NS_IMETHOD HasMoreElements(bool* aResult) override;
  143. NS_IMETHOD GetNext(nsISupports** aResult) override;
  144. nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
  145. nsISimpleEnumerator* aSecondEnumerator);
  146. private:
  147. ~nsUnionEnumerator();
  148. protected:
  149. nsCOMPtr<nsISimpleEnumerator> mFirstEnumerator, mSecondEnumerator;
  150. bool mConsumed;
  151. bool mAtSecond;
  152. };
  153. nsUnionEnumerator::nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
  154. nsISimpleEnumerator* aSecondEnumerator)
  155. : mFirstEnumerator(aFirstEnumerator)
  156. , mSecondEnumerator(aSecondEnumerator)
  157. , mConsumed(false)
  158. , mAtSecond(false)
  159. {
  160. }
  161. nsUnionEnumerator::~nsUnionEnumerator()
  162. {
  163. }
  164. NS_IMPL_ISUPPORTS(nsUnionEnumerator, nsISimpleEnumerator)
  165. NS_IMETHODIMP
  166. nsUnionEnumerator::HasMoreElements(bool* aResult)
  167. {
  168. NS_PRECONDITION(aResult != 0, "null ptr");
  169. if (!aResult) {
  170. return NS_ERROR_NULL_POINTER;
  171. }
  172. nsresult rv;
  173. if (mConsumed) {
  174. *aResult = false;
  175. return NS_OK;
  176. }
  177. if (!mAtSecond) {
  178. rv = mFirstEnumerator->HasMoreElements(aResult);
  179. if (NS_FAILED(rv)) {
  180. return rv;
  181. }
  182. if (*aResult) {
  183. return NS_OK;
  184. }
  185. mAtSecond = true;
  186. }
  187. rv = mSecondEnumerator->HasMoreElements(aResult);
  188. if (NS_FAILED(rv)) {
  189. return rv;
  190. }
  191. if (*aResult) {
  192. return NS_OK;
  193. }
  194. *aResult = false;
  195. mConsumed = true;
  196. return NS_OK;
  197. }
  198. NS_IMETHODIMP
  199. nsUnionEnumerator::GetNext(nsISupports** aResult)
  200. {
  201. NS_PRECONDITION(aResult != 0, "null ptr");
  202. if (!aResult) {
  203. return NS_ERROR_NULL_POINTER;
  204. }
  205. if (mConsumed) {
  206. return NS_ERROR_UNEXPECTED;
  207. }
  208. if (!mAtSecond) {
  209. return mFirstEnumerator->GetNext(aResult);
  210. }
  211. return mSecondEnumerator->GetNext(aResult);
  212. }
  213. nsresult
  214. NS_NewUnionEnumerator(nsISimpleEnumerator** aResult,
  215. nsISimpleEnumerator* aFirstEnumerator,
  216. nsISimpleEnumerator* aSecondEnumerator)
  217. {
  218. *aResult = nullptr;
  219. if (!aFirstEnumerator) {
  220. *aResult = aSecondEnumerator;
  221. } else if (!aSecondEnumerator) {
  222. *aResult = aFirstEnumerator;
  223. } else {
  224. nsUnionEnumerator* enumer = new nsUnionEnumerator(aFirstEnumerator,
  225. aSecondEnumerator);
  226. if (!enumer) {
  227. return NS_ERROR_OUT_OF_MEMORY;
  228. }
  229. *aResult = enumer;
  230. }
  231. NS_ADDREF(*aResult);
  232. return NS_OK;
  233. }