Bumping manifests a=b2g-bump
[gecko.git] / xpcom / ds / nsStringEnumerator.cpp
blob94baa8d9b2b71ac4ad9e4fd3926f1d2f22fc7bb6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
7 #include "nsStringEnumerator.h"
8 #include "nsISimpleEnumerator.h"
9 #include "nsSupportsPrimitives.h"
10 #include "mozilla/Attributes.h"
11 #include "nsTArray.h"
14 // nsStringEnumerator
17 class nsStringEnumerator MOZ_FINAL
18 : public nsIStringEnumerator
19 , public nsIUTF8StringEnumerator
20 , public nsISimpleEnumerator
22 public:
23 nsStringEnumerator(const nsTArray<nsString>* aArray, bool aOwnsArray)
24 : mArray(aArray)
25 , mIndex(0)
26 , mOwnsArray(aOwnsArray)
27 , mIsUnicode(true)
30 nsStringEnumerator(const nsTArray<nsCString>* aArray, bool aOwnsArray)
31 : mCArray(aArray)
32 , mIndex(0)
33 , mOwnsArray(aOwnsArray)
34 , mIsUnicode(false)
37 nsStringEnumerator(const nsTArray<nsString>* aArray, nsISupports* aOwner)
38 : mArray(aArray)
39 , mIndex(0)
40 , mOwner(aOwner)
41 , mOwnsArray(false)
42 , mIsUnicode(true)
45 nsStringEnumerator(const nsTArray<nsCString>* aArray, nsISupports* aOwner)
46 : mCArray(aArray)
47 , mIndex(0)
48 , mOwner(aOwner)
49 , mOwnsArray(false)
50 , mIsUnicode(false)
53 NS_DECL_ISUPPORTS
54 NS_DECL_NSIUTF8STRINGENUMERATOR
56 // have to declare nsIStringEnumerator manually, because of
57 // overlapping method names
58 NS_IMETHOD GetNext(nsAString& aResult);
59 NS_DECL_NSISIMPLEENUMERATOR
61 private:
62 ~nsStringEnumerator()
64 if (mOwnsArray) {
65 // const-casting is safe here, because the NS_New*
66 // constructors make sure mOwnsArray is consistent with
67 // the constness of the objects
68 if (mIsUnicode) {
69 delete const_cast<nsTArray<nsString>*>(mArray);
70 } else {
71 delete const_cast<nsTArray<nsCString>*>(mCArray);
76 union
78 const nsTArray<nsString>* mArray;
79 const nsTArray<nsCString>* mCArray;
82 inline uint32_t Count()
84 return mIsUnicode ? mArray->Length() : mCArray->Length();
87 uint32_t mIndex;
89 // the owner allows us to hold a strong reference to the object
90 // that owns the array. Having a non-null value in mOwner implies
91 // that mOwnsArray is false, because we rely on the real owner
92 // to release the array
93 nsCOMPtr<nsISupports> mOwner;
94 bool mOwnsArray;
95 bool mIsUnicode;
98 NS_IMPL_ISUPPORTS(nsStringEnumerator,
99 nsIStringEnumerator,
100 nsIUTF8StringEnumerator,
101 nsISimpleEnumerator)
103 NS_IMETHODIMP
104 nsStringEnumerator::HasMore(bool* aResult)
106 *aResult = mIndex < Count();
107 return NS_OK;
110 NS_IMETHODIMP
111 nsStringEnumerator::HasMoreElements(bool* aResult)
113 return HasMore(aResult);
116 NS_IMETHODIMP
117 nsStringEnumerator::GetNext(nsISupports** aResult)
119 if (mIsUnicode) {
120 nsSupportsStringImpl* stringImpl = new nsSupportsStringImpl();
121 if (!stringImpl) {
122 return NS_ERROR_OUT_OF_MEMORY;
125 stringImpl->SetData(mArray->ElementAt(mIndex++));
126 *aResult = stringImpl;
127 } else {
128 nsSupportsCStringImpl* cstringImpl = new nsSupportsCStringImpl();
129 if (!cstringImpl) {
130 return NS_ERROR_OUT_OF_MEMORY;
133 cstringImpl->SetData(mCArray->ElementAt(mIndex++));
134 *aResult = cstringImpl;
136 NS_ADDREF(*aResult);
137 return NS_OK;
140 NS_IMETHODIMP
141 nsStringEnumerator::GetNext(nsAString& aResult)
143 if (NS_WARN_IF(mIndex >= Count())) {
144 return NS_ERROR_UNEXPECTED;
147 if (mIsUnicode) {
148 aResult = mArray->ElementAt(mIndex++);
149 } else {
150 CopyUTF8toUTF16(mCArray->ElementAt(mIndex++), aResult);
153 return NS_OK;
156 NS_IMETHODIMP
157 nsStringEnumerator::GetNext(nsACString& aResult)
159 if (NS_WARN_IF(mIndex >= Count())) {
160 return NS_ERROR_UNEXPECTED;
163 if (mIsUnicode) {
164 CopyUTF16toUTF8(mArray->ElementAt(mIndex++), aResult);
165 } else {
166 aResult = mCArray->ElementAt(mIndex++);
169 return NS_OK;
172 template<class T>
173 static inline nsresult
174 StringEnumeratorTail(T** aResult)
176 if (!*aResult) {
177 return NS_ERROR_OUT_OF_MEMORY;
179 NS_ADDREF(*aResult);
180 return NS_OK;
184 // constructors
187 nsresult
188 NS_NewStringEnumerator(nsIStringEnumerator** aResult,
189 const nsTArray<nsString>* aArray, nsISupports* aOwner)
191 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray)) {
192 return NS_ERROR_INVALID_ARG;
195 *aResult = new nsStringEnumerator(aArray, aOwner);
196 return StringEnumeratorTail(aResult);
200 nsresult
201 NS_NewUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
202 const nsTArray<nsCString>* aArray,
203 nsISupports* aOwner)
205 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray)) {
206 return NS_ERROR_INVALID_ARG;
209 *aResult = new nsStringEnumerator(aArray, aOwner);
210 return StringEnumeratorTail(aResult);
213 nsresult
214 NS_NewAdoptingStringEnumerator(nsIStringEnumerator** aResult,
215 nsTArray<nsString>* aArray)
217 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray)) {
218 return NS_ERROR_INVALID_ARG;
221 *aResult = new nsStringEnumerator(aArray, true);
222 return StringEnumeratorTail(aResult);
225 nsresult
226 NS_NewAdoptingUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
227 nsTArray<nsCString>* aArray)
229 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray)) {
230 return NS_ERROR_INVALID_ARG;
233 *aResult = new nsStringEnumerator(aArray, true);
234 return StringEnumeratorTail(aResult);
237 // const ones internally just forward to the non-const equivalents
238 nsresult
239 NS_NewStringEnumerator(nsIStringEnumerator** aResult,
240 const nsTArray<nsString>* aArray)
242 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray)) {
243 return NS_ERROR_INVALID_ARG;
246 *aResult = new nsStringEnumerator(aArray, false);
247 return StringEnumeratorTail(aResult);
250 nsresult
251 NS_NewUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
252 const nsTArray<nsCString>* aArray)
254 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray)) {
255 return NS_ERROR_INVALID_ARG;
258 *aResult = new nsStringEnumerator(aArray, false);
259 return StringEnumeratorTail(aResult);