Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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"
13 //
14 // nsStringEnumerator
15 //
17 class nsStringEnumerator MOZ_FINAL : public nsIStringEnumerator,
18 public nsIUTF8StringEnumerator,
19 public nsISimpleEnumerator
20 {
21 public:
22 nsStringEnumerator(const nsTArray<nsString>* aArray, bool aOwnsArray) :
23 mArray(aArray), mIndex(0), mOwnsArray(aOwnsArray), mIsUnicode(true)
24 {}
26 nsStringEnumerator(const nsTArray<nsCString>* aArray, bool aOwnsArray) :
27 mCArray(aArray), mIndex(0), mOwnsArray(aOwnsArray), mIsUnicode(false)
28 {}
30 nsStringEnumerator(const nsTArray<nsString>* aArray, nsISupports* aOwner) :
31 mArray(aArray), mIndex(0), mOwner(aOwner), mOwnsArray(false), mIsUnicode(true)
32 {}
34 nsStringEnumerator(const nsTArray<nsCString>* aArray, nsISupports* aOwner) :
35 mCArray(aArray), mIndex(0), mOwner(aOwner), mOwnsArray(false), mIsUnicode(false)
36 {}
38 NS_DECL_ISUPPORTS
39 NS_DECL_NSIUTF8STRINGENUMERATOR
41 // have to declare nsIStringEnumerator manually, because of
42 // overlapping method names
43 NS_IMETHOD GetNext(nsAString& aResult);
44 NS_DECL_NSISIMPLEENUMERATOR
46 private:
47 ~nsStringEnumerator() {
48 if (mOwnsArray) {
49 // const-casting is safe here, because the NS_New*
50 // constructors make sure mOwnsArray is consistent with
51 // the constness of the objects
52 if (mIsUnicode)
53 delete const_cast<nsTArray<nsString>*>(mArray);
54 else
55 delete const_cast<nsTArray<nsCString>*>(mCArray);
56 }
57 }
59 union {
60 const nsTArray<nsString>* mArray;
61 const nsTArray<nsCString>* mCArray;
62 };
64 inline uint32_t Count() {
65 return mIsUnicode ? mArray->Length() : mCArray->Length();
66 }
68 uint32_t mIndex;
70 // the owner allows us to hold a strong reference to the object
71 // that owns the array. Having a non-null value in mOwner implies
72 // that mOwnsArray is false, because we rely on the real owner
73 // to release the array
74 nsCOMPtr<nsISupports> mOwner;
75 bool mOwnsArray;
76 bool mIsUnicode;
77 };
79 NS_IMPL_ISUPPORTS(nsStringEnumerator,
80 nsIStringEnumerator,
81 nsIUTF8StringEnumerator,
82 nsISimpleEnumerator)
84 NS_IMETHODIMP
85 nsStringEnumerator::HasMore(bool* aResult)
86 {
87 *aResult = mIndex < Count();
88 return NS_OK;
89 }
91 NS_IMETHODIMP
92 nsStringEnumerator::HasMoreElements(bool* aResult)
93 {
94 return HasMore(aResult);
95 }
97 NS_IMETHODIMP
98 nsStringEnumerator::GetNext(nsISupports** aResult)
99 {
100 if (mIsUnicode) {
101 nsSupportsStringImpl* stringImpl = new nsSupportsStringImpl();
102 if (!stringImpl) return NS_ERROR_OUT_OF_MEMORY;
104 stringImpl->SetData(mArray->ElementAt(mIndex++));
105 *aResult = stringImpl;
106 }
107 else {
108 nsSupportsCStringImpl* cstringImpl = new nsSupportsCStringImpl();
109 if (!cstringImpl) return NS_ERROR_OUT_OF_MEMORY;
111 cstringImpl->SetData(mCArray->ElementAt(mIndex++));
112 *aResult = cstringImpl;
113 }
114 NS_ADDREF(*aResult);
115 return NS_OK;
116 }
118 NS_IMETHODIMP
119 nsStringEnumerator::GetNext(nsAString& aResult)
120 {
121 if (NS_WARN_IF(mIndex >= Count()))
122 return NS_ERROR_UNEXPECTED;
124 if (mIsUnicode)
125 aResult = mArray->ElementAt(mIndex++);
126 else
127 CopyUTF8toUTF16(mCArray->ElementAt(mIndex++), aResult);
129 return NS_OK;
130 }
132 NS_IMETHODIMP
133 nsStringEnumerator::GetNext(nsACString& aResult)
134 {
135 if (NS_WARN_IF(mIndex >= Count()))
136 return NS_ERROR_UNEXPECTED;
138 if (mIsUnicode)
139 CopyUTF16toUTF8(mArray->ElementAt(mIndex++), aResult);
140 else
141 aResult = mCArray->ElementAt(mIndex++);
143 return NS_OK;
144 }
146 template<class T>
147 static inline nsresult
148 StringEnumeratorTail(T** aResult)
149 {
150 if (!*aResult)
151 return NS_ERROR_OUT_OF_MEMORY;
152 NS_ADDREF(*aResult);
153 return NS_OK;
154 }
156 //
157 // constructors
158 //
160 nsresult
161 NS_NewStringEnumerator(nsIStringEnumerator** aResult,
162 const nsTArray<nsString>* aArray, nsISupports* aOwner)
163 {
164 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
165 return NS_ERROR_INVALID_ARG;
167 *aResult = new nsStringEnumerator(aArray, aOwner);
168 return StringEnumeratorTail(aResult);
169 }
172 nsresult
173 NS_NewUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
174 const nsTArray<nsCString>* aArray, nsISupports* aOwner)
175 {
176 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
177 return NS_ERROR_INVALID_ARG;
179 *aResult = new nsStringEnumerator(aArray, aOwner);
180 return StringEnumeratorTail(aResult);
181 }
183 nsresult
184 NS_NewAdoptingStringEnumerator(nsIStringEnumerator** aResult,
185 nsTArray<nsString>* aArray)
186 {
187 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
188 return NS_ERROR_INVALID_ARG;
190 *aResult = new nsStringEnumerator(aArray, true);
191 return StringEnumeratorTail(aResult);
192 }
194 nsresult
195 NS_NewAdoptingUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
196 nsTArray<nsCString>* aArray)
197 {
198 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
199 return NS_ERROR_INVALID_ARG;
201 *aResult = new nsStringEnumerator(aArray, true);
202 return StringEnumeratorTail(aResult);
203 }
205 // const ones internally just forward to the non-const equivalents
206 nsresult
207 NS_NewStringEnumerator(nsIStringEnumerator** aResult,
208 const nsTArray<nsString>* aArray)
209 {
210 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
211 return NS_ERROR_INVALID_ARG;
213 *aResult = new nsStringEnumerator(aArray, false);
214 return StringEnumeratorTail(aResult);
215 }
217 nsresult
218 NS_NewUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
219 const nsTArray<nsCString>* aArray)
220 {
221 if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
222 return NS_ERROR_INVALID_ARG;
224 *aResult = new nsStringEnumerator(aArray, false);
225 return StringEnumeratorTail(aResult);
226 }