/src/mozilla-central/toolkit/mozapps/extensions/AddonManagerStartup-inlines.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; 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 | | |
6 | | #ifndef AddonManagerStartup_inlines_h |
7 | | #define AddonManagerStartup_inlines_h |
8 | | |
9 | | #include "jsapi.h" |
10 | | #include "nsJSUtils.h" |
11 | | |
12 | | #include "mozilla/Maybe.h" |
13 | | #include "mozilla/Move.h" |
14 | | |
15 | | namespace mozilla { |
16 | | |
17 | | class ArrayIterElem; |
18 | | class PropertyIterElem; |
19 | | |
20 | | |
21 | | /***************************************************************************** |
22 | | * Object iterator base classes |
23 | | *****************************************************************************/ |
24 | | |
25 | | template<class T, class PropertyType> |
26 | | class MOZ_STACK_CLASS BaseIter { |
27 | | public: |
28 | | typedef T SelfType; |
29 | | |
30 | | PropertyType begin() const |
31 | 0 | { |
32 | 0 | PropertyType elem(Self()); |
33 | 0 | return std::move(elem); |
34 | 0 | } Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::begin() const Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::begin() const |
35 | | |
36 | | PropertyType end() const |
37 | 0 | { |
38 | 0 | PropertyType elem(Self()); |
39 | 0 | return elem.End(); |
40 | 0 | } Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::end() const Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::end() const |
41 | | |
42 | 0 | void* Context() const { return mContext; } |
43 | | |
44 | | protected: |
45 | | BaseIter(JSContext* cx, JS::HandleObject object, void* context = nullptr) |
46 | | : mCx(cx) |
47 | | , mObject(object) |
48 | | , mContext(context) |
49 | 0 | {} Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::BaseIter(JSContext*, JS::Handle<JSObject*>, void*) Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::BaseIter(JSContext*, JS::Handle<JSObject*>, void*) |
50 | | |
51 | | const SelfType& Self() const |
52 | 0 | { |
53 | 0 | return *static_cast<const SelfType*>(this); |
54 | 0 | } Unexecuted instantiation: mozilla::BaseIter<mozilla::PropertyIter, mozilla::PropertyIterElem>::Self() const Unexecuted instantiation: mozilla::BaseIter<mozilla::ArrayIter, mozilla::ArrayIterElem>::Self() const |
55 | | SelfType& Self() |
56 | | { |
57 | | return *static_cast<SelfType*>(this); |
58 | | } |
59 | | |
60 | | JSContext* mCx; |
61 | | |
62 | | JS::HandleObject mObject; |
63 | | |
64 | | void* mContext; |
65 | | }; |
66 | | |
67 | | template<class T, class IterType> |
68 | | class MOZ_STACK_CLASS BaseIterElem { |
69 | | public: |
70 | | typedef T SelfType; |
71 | | |
72 | | explicit BaseIterElem(const IterType& iter, uint32_t index = 0) |
73 | | : mIter(iter) |
74 | | , mIndex(index) |
75 | 0 | {} Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::BaseIterElem(mozilla::PropertyIter const&, unsigned int) Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::BaseIterElem(mozilla::ArrayIter const&, unsigned int) |
76 | | |
77 | | uint32_t Length() const |
78 | 0 | { |
79 | 0 | return mIter.Length(); |
80 | 0 | } Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::Length() const Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::Length() const |
81 | | |
82 | | JS::Value Value() |
83 | 0 | { |
84 | 0 | JS::RootedValue value(mIter.mCx, JS::UndefinedValue()); |
85 | 0 |
|
86 | 0 | auto& self = Self(); |
87 | 0 | if (!self.GetValue(&value)) { |
88 | 0 | JS_ClearPendingException(mIter.mCx); |
89 | 0 | } |
90 | 0 |
|
91 | 0 | return value; |
92 | 0 | } Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::Value() Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::Value() |
93 | | |
94 | 0 | SelfType& operator*() { return Self(); } Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::operator*() Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::operator*() |
95 | | |
96 | | SelfType& operator++() |
97 | 0 | { |
98 | 0 | MOZ_ASSERT(mIndex < Length()); |
99 | 0 | mIndex++; |
100 | 0 | return Self(); |
101 | 0 | } Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::operator++() Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::operator++() |
102 | | |
103 | | bool operator!=(const SelfType& other) const |
104 | 0 | { |
105 | 0 | return &mIter != &other.mIter || mIndex != other.mIndex; |
106 | 0 | } Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::operator!=(mozilla::PropertyIterElem const&) const Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::operator!=(mozilla::ArrayIterElem const&) const |
107 | | |
108 | | |
109 | | SelfType End() const |
110 | 0 | { |
111 | 0 | SelfType end(mIter); |
112 | 0 | end.mIndex = Length(); |
113 | 0 | return std::move(end); |
114 | 0 | } Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::End() const Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::End() const |
115 | | |
116 | 0 | void* Context() const { return mIter.Context(); } |
117 | | |
118 | | protected: |
119 | | const SelfType& Self() const |
120 | | { |
121 | | return *static_cast<const SelfType*>(this); |
122 | | } |
123 | 0 | SelfType& Self() { |
124 | 0 | return *static_cast<SelfType*>(this); |
125 | 0 | } Unexecuted instantiation: mozilla::BaseIterElem<mozilla::PropertyIterElem, mozilla::PropertyIter>::Self() Unexecuted instantiation: mozilla::BaseIterElem<mozilla::ArrayIterElem, mozilla::ArrayIter>::Self() |
126 | | |
127 | | const IterType& mIter; |
128 | | |
129 | | uint32_t mIndex; |
130 | | }; |
131 | | |
132 | | |
133 | | /***************************************************************************** |
134 | | * Property iteration |
135 | | *****************************************************************************/ |
136 | | |
137 | | class MOZ_STACK_CLASS PropertyIter |
138 | | : public BaseIter<PropertyIter, PropertyIterElem> |
139 | | { |
140 | | friend class PropertyIterElem; |
141 | | friend class BaseIterElem<PropertyIterElem, PropertyIter>; |
142 | | |
143 | | public: |
144 | | PropertyIter(JSContext* cx, JS::HandleObject object, void* context = nullptr) |
145 | | : BaseIter(cx, object, context) |
146 | | , mIds(cx, JS::IdVector(cx)) |
147 | 0 | { |
148 | 0 | if (!JS_Enumerate(cx, object, &mIds)) { |
149 | 0 | JS_ClearPendingException(cx); |
150 | 0 | } |
151 | 0 | } |
152 | | |
153 | | PropertyIter(const PropertyIter& other) |
154 | | : PropertyIter(other.mCx, other.mObject, other.mContext) |
155 | 0 | {} |
156 | | |
157 | | PropertyIter& operator=(const PropertyIter& other) |
158 | 0 | { |
159 | 0 | MOZ_ASSERT(other.mObject == mObject); |
160 | 0 | mCx = other.mCx; |
161 | 0 | mContext = other.mContext; |
162 | 0 |
|
163 | 0 | mIds.clear(); |
164 | 0 | if (!JS_Enumerate(mCx, mObject, &mIds)) { |
165 | 0 | JS_ClearPendingException(mCx); |
166 | 0 | } |
167 | 0 | return *this; |
168 | 0 | } |
169 | | |
170 | | int32_t Length() const |
171 | 0 | { |
172 | 0 | return mIds.length(); |
173 | 0 | } |
174 | | |
175 | | protected: |
176 | | JS::Rooted<JS::IdVector> mIds; |
177 | | }; |
178 | | |
179 | | class MOZ_STACK_CLASS PropertyIterElem |
180 | | : public BaseIterElem<PropertyIterElem, PropertyIter> |
181 | | { |
182 | | friend class BaseIterElem<PropertyIterElem, PropertyIter>; |
183 | | |
184 | | public: |
185 | | using BaseIterElem::BaseIterElem; |
186 | | |
187 | | PropertyIterElem(const PropertyIterElem& other) |
188 | | : BaseIterElem(other.mIter, other.mIndex) |
189 | 0 | {} |
190 | | |
191 | | jsid Id() |
192 | 0 | { |
193 | 0 | MOZ_ASSERT(mIndex < mIter.mIds.length()); |
194 | 0 |
|
195 | 0 | return mIter.mIds[mIndex]; |
196 | 0 | } |
197 | | |
198 | | const nsAString& Name() |
199 | 0 | { |
200 | 0 | if(mName.isNothing()) { |
201 | 0 | mName.emplace(); |
202 | 0 | mName.ref().init(mIter.mCx, Id()); |
203 | 0 | } |
204 | 0 | return mName.ref(); |
205 | 0 | } |
206 | | |
207 | 0 | JSContext* Cx() { return mIter.mCx; } |
208 | | |
209 | | protected: |
210 | | bool GetValue(JS::MutableHandleValue value) |
211 | 0 | { |
212 | 0 | MOZ_ASSERT(mIndex < Length()); |
213 | 0 | JS::Rooted<jsid> id(mIter.mCx, Id()); |
214 | 0 |
|
215 | 0 | return JS_GetPropertyById(mIter.mCx, mIter.mObject, id, value); |
216 | 0 | } |
217 | | |
218 | | private: |
219 | | Maybe<nsAutoJSString> mName; |
220 | | }; |
221 | | |
222 | | |
223 | | /***************************************************************************** |
224 | | * Array iteration |
225 | | *****************************************************************************/ |
226 | | |
227 | | class MOZ_STACK_CLASS ArrayIter |
228 | | : public BaseIter<ArrayIter, ArrayIterElem> |
229 | | { |
230 | | friend class ArrayIterElem; |
231 | | friend class BaseIterElem<ArrayIterElem, ArrayIter>; |
232 | | |
233 | | public: |
234 | | ArrayIter(JSContext* cx, JS::HandleObject object) |
235 | | : BaseIter(cx, object) |
236 | | , mLength(0) |
237 | 0 | { |
238 | 0 | bool isArray; |
239 | 0 | if (!JS_IsArrayObject(cx, object, &isArray) || !isArray) { |
240 | 0 | JS_ClearPendingException(cx); |
241 | 0 | return; |
242 | 0 | } |
243 | 0 | |
244 | 0 | if (!JS_GetArrayLength(cx, object, &mLength)) { |
245 | 0 | JS_ClearPendingException(cx); |
246 | 0 | } |
247 | 0 | } |
248 | | |
249 | | uint32_t Length() const |
250 | 0 | { |
251 | 0 | return mLength; |
252 | 0 | } |
253 | | |
254 | | private: |
255 | | uint32_t mLength; |
256 | | }; |
257 | | |
258 | | class MOZ_STACK_CLASS ArrayIterElem |
259 | | : public BaseIterElem<ArrayIterElem, ArrayIter> |
260 | | { |
261 | | friend class BaseIterElem<ArrayIterElem, ArrayIter>; |
262 | | |
263 | | public: |
264 | | using BaseIterElem::BaseIterElem; |
265 | | |
266 | | ArrayIterElem(const ArrayIterElem& other) |
267 | | : BaseIterElem(other.mIter, other.mIndex) |
268 | 0 | {} |
269 | | |
270 | | protected: |
271 | | bool |
272 | | GetValue(JS::MutableHandleValue value) |
273 | 0 | { |
274 | 0 | MOZ_ASSERT(mIndex < Length()); |
275 | 0 | return JS_GetElement(mIter.mCx, mIter.mObject, mIndex, value); |
276 | 0 | } |
277 | | }; |
278 | | |
279 | | } |
280 | | |
281 | | #endif // AddonManagerStartup_inlines_h |