Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/ds/nsEnumeratorUtils.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#include "mozilla/Attributes.h"
8
9
#include "nsEnumeratorUtils.h"
10
11
#include "nsIStringEnumerator.h"
12
#include "nsSimpleEnumerator.h"
13
14
#include "nsCOMPtr.h"
15
#include "mozilla/RefPtr.h"
16
17
class EmptyEnumeratorImpl
18
  : public nsSimpleEnumerator
19
  , public nsIUTF8StringEnumerator
20
  , public nsIStringEnumerator
21
{
22
public:
23
3
  EmptyEnumeratorImpl() {}
24
25
  // nsISupports interface
26
  NS_DECL_ISUPPORTS_INHERITED  // not really inherited, but no mRefCnt
27
28
  // nsISimpleEnumerator
29
  NS_DECL_NSISIMPLEENUMERATOR
30
  NS_DECL_NSIUTF8STRINGENUMERATOR
31
  NS_DECL_NSISTRINGENUMERATORBASE
32
  // can't use NS_DECL_NSISTRINGENUMERATOR because they share the
33
  // HasMore() signature
34
  NS_IMETHOD GetNext(nsAString& aResult) override;
35
36
  static EmptyEnumeratorImpl* GetInstance()
37
7
  {
38
7
    static const EmptyEnumeratorImpl kInstance;
39
7
    return const_cast<EmptyEnumeratorImpl*>(&kInstance);
40
7
  }
41
};
42
43
// nsISupports interface
44
NS_IMETHODIMP_(MozExternalRefCountType)
45
EmptyEnumeratorImpl::AddRef(void)
46
14
{
47
14
  return 2;
48
14
}
49
50
NS_IMETHODIMP_(MozExternalRefCountType)
51
EmptyEnumeratorImpl::Release(void)
52
21
{
53
21
  return 1;
54
21
}
55
56
NS_IMPL_QUERY_INTERFACE_INHERITED(EmptyEnumeratorImpl, nsSimpleEnumerator,
57
                        nsIUTF8StringEnumerator, nsIStringEnumerator)
58
59
// nsISimpleEnumerator interface
60
NS_IMETHODIMP
61
EmptyEnumeratorImpl::HasMoreElements(bool* aResult)
62
0
{
63
0
  *aResult = false;
64
0
  return NS_OK;
65
0
}
66
67
NS_IMETHODIMP
68
EmptyEnumeratorImpl::HasMore(bool* aResult)
69
0
{
70
0
  *aResult = false;
71
0
  return NS_OK;
72
0
}
73
74
NS_IMETHODIMP
75
EmptyEnumeratorImpl::GetNext(nsISupports** aResult)
76
7
{
77
7
  return NS_ERROR_FAILURE;
78
7
}
79
80
NS_IMETHODIMP
81
EmptyEnumeratorImpl::GetNext(nsACString& aResult)
82
0
{
83
0
  return NS_ERROR_UNEXPECTED;
84
0
}
85
86
NS_IMETHODIMP
87
EmptyEnumeratorImpl::GetNext(nsAString& aResult)
88
0
{
89
0
  return NS_ERROR_UNEXPECTED;
90
0
}
91
92
NS_IMETHODIMP
93
EmptyEnumeratorImpl::StringIterator(nsIJSEnumerator** aRetVal)
94
0
{
95
0
  return NS_ERROR_NOT_IMPLEMENTED;
96
0
}
97
98
nsresult
99
NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult)
100
7
{
101
7
  *aResult = EmptyEnumeratorImpl::GetInstance();
102
7
  return NS_OK;
103
7
}
104
105
////////////////////////////////////////////////////////////////////////////////
106
107
class nsSingletonEnumerator final : public nsSimpleEnumerator
108
{
109
public:
110
  // nsISimpleEnumerator methods
111
  NS_IMETHOD HasMoreElements(bool* aResult) override;
112
  NS_IMETHOD GetNext(nsISupports** aResult) override;
113
114
  explicit nsSingletonEnumerator(nsISupports* aValue);
115
116
private:
117
  ~nsSingletonEnumerator() override;
118
119
protected:
120
  nsCOMPtr<nsISupports> mValue;
121
  bool mConsumed;
122
};
123
124
nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
125
  : mValue(aValue)
126
0
{
127
0
  mConsumed = (mValue ? false : true);
128
0
}
129
130
0
nsSingletonEnumerator::~nsSingletonEnumerator() = default;
131
132
NS_IMETHODIMP
133
nsSingletonEnumerator::HasMoreElements(bool* aResult)
134
0
{
135
0
  MOZ_ASSERT(aResult != 0, "null ptr");
136
0
  if (!aResult) {
137
0
    return NS_ERROR_NULL_POINTER;
138
0
  }
139
0
140
0
  *aResult = !mConsumed;
141
0
  return NS_OK;
142
0
}
143
144
145
NS_IMETHODIMP
146
nsSingletonEnumerator::GetNext(nsISupports** aResult)
147
0
{
148
0
  MOZ_ASSERT(aResult != 0, "null ptr");
149
0
  if (!aResult) {
150
0
    return NS_ERROR_NULL_POINTER;
151
0
  }
152
0
153
0
  if (mConsumed) {
154
0
    return NS_ERROR_FAILURE;
155
0
  }
156
0
157
0
  mConsumed = true;
158
0
159
0
  *aResult = mValue;
160
0
  NS_ADDREF(*aResult);
161
0
  return NS_OK;
162
0
}
163
164
nsresult
165
NS_NewSingletonEnumerator(nsISimpleEnumerator** aResult,
166
                          nsISupports* aSingleton)
167
0
{
168
0
  RefPtr<nsSingletonEnumerator> enumer = new nsSingletonEnumerator(aSingleton);
169
0
  enumer.forget(aResult);
170
0
  return NS_OK;
171
0
}
172
173
////////////////////////////////////////////////////////////////////////////////
174
175
class nsUnionEnumerator final : public nsSimpleEnumerator
176
{
177
public:
178
  // nsISimpleEnumerator methods
179
  NS_IMETHOD HasMoreElements(bool* aResult) override;
180
  NS_IMETHOD GetNext(nsISupports** aResult) override;
181
182
  nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
183
                    nsISimpleEnumerator* aSecondEnumerator);
184
185
private:
186
  ~nsUnionEnumerator() override;
187
188
protected:
189
  nsCOMPtr<nsISimpleEnumerator> mFirstEnumerator, mSecondEnumerator;
190
  bool mConsumed;
191
  bool mAtSecond;
192
};
193
194
nsUnionEnumerator::nsUnionEnumerator(nsISimpleEnumerator* aFirstEnumerator,
195
                                     nsISimpleEnumerator* aSecondEnumerator)
196
  : mFirstEnumerator(aFirstEnumerator)
197
  , mSecondEnumerator(aSecondEnumerator)
198
  , mConsumed(false)
199
  , mAtSecond(false)
200
0
{
201
0
}
202
203
0
nsUnionEnumerator::~nsUnionEnumerator() = default;
204
205
NS_IMETHODIMP
206
nsUnionEnumerator::HasMoreElements(bool* aResult)
207
0
{
208
0
  MOZ_ASSERT(aResult != 0, "null ptr");
209
0
  if (!aResult) {
210
0
    return NS_ERROR_NULL_POINTER;
211
0
  }
212
0
213
0
  nsresult rv;
214
0
215
0
  if (mConsumed) {
216
0
    *aResult = false;
217
0
    return NS_OK;
218
0
  }
219
0
220
0
  if (!mAtSecond) {
221
0
    rv = mFirstEnumerator->HasMoreElements(aResult);
222
0
    if (NS_FAILED(rv)) {
223
0
      return rv;
224
0
    }
225
0
226
0
    if (*aResult) {
227
0
      return NS_OK;
228
0
    }
229
0
230
0
    mAtSecond = true;
231
0
  }
232
0
233
0
  rv = mSecondEnumerator->HasMoreElements(aResult);
234
0
  if (NS_FAILED(rv)) {
235
0
    return rv;
236
0
  }
237
0
238
0
  if (*aResult) {
239
0
    return NS_OK;
240
0
  }
241
0
242
0
  *aResult = false;
243
0
  mConsumed = true;
244
0
  return NS_OK;
245
0
}
246
247
NS_IMETHODIMP
248
nsUnionEnumerator::GetNext(nsISupports** aResult)
249
0
{
250
0
  MOZ_ASSERT(aResult != 0, "null ptr");
251
0
  if (!aResult) {
252
0
    return NS_ERROR_NULL_POINTER;
253
0
  }
254
0
255
0
  if (mConsumed) {
256
0
    return NS_ERROR_FAILURE;
257
0
  }
258
0
259
0
  if (!mAtSecond) {
260
0
    return mFirstEnumerator->GetNext(aResult);
261
0
  }
262
0
263
0
  return mSecondEnumerator->GetNext(aResult);
264
0
}
265
266
nsresult
267
NS_NewUnionEnumerator(nsISimpleEnumerator** aResult,
268
                      nsISimpleEnumerator* aFirstEnumerator,
269
                      nsISimpleEnumerator* aSecondEnumerator)
270
0
{
271
0
  *aResult = nullptr;
272
0
  if (!aFirstEnumerator) {
273
0
    *aResult = aSecondEnumerator;
274
0
  } else if (!aSecondEnumerator) {
275
0
    *aResult = aFirstEnumerator;
276
0
  } else {
277
0
    auto* enumer = new nsUnionEnumerator(aFirstEnumerator,
278
0
                                         aSecondEnumerator);
279
0
    if (!enumer) {
280
0
      return NS_ERROR_OUT_OF_MEMORY;
281
0
    }
282
0
    *aResult = enumer;
283
0
  }
284
0
  NS_ADDREF(*aResult);
285
0
  return NS_OK;
286
0
}