Line data Source code
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 : #ifndef nsHtml5StreamParserPtr_h
6 : #define nsHtml5StreamParserPtr_h
7 : #include "nsThreadUtils.h"
8 : #include "mozilla/dom/DocGroup.h"
9 :
10 21 : class nsHtml5StreamParserReleaser : public mozilla::Runnable
11 : {
12 : private:
13 : nsHtml5StreamParser* mPtr;
14 :
15 : public:
16 7 : explicit nsHtml5StreamParserReleaser(nsHtml5StreamParser* aPtr)
17 7 : : mozilla::Runnable("nsHtml5StreamParserReleaser")
18 7 : , mPtr(aPtr)
19 : {
20 7 : }
21 7 : NS_IMETHOD Run() override
22 : {
23 7 : mPtr->Release();
24 7 : return NS_OK;
25 : }
26 : };
27 : /**
28 : * Like nsRefPtr except release is proxied to the main
29 : * thread. Mostly copied from nsRefPtr.
30 : */
31 : class nsHtml5StreamParserPtr
32 : {
33 : private:
34 2 : void assign_with_AddRef(nsHtml5StreamParser* rawPtr)
35 : {
36 2 : if (rawPtr)
37 0 : rawPtr->AddRef();
38 2 : assign_assuming_AddRef(rawPtr);
39 2 : }
40 : void** begin_assignment()
41 : {
42 : assign_assuming_AddRef(0);
43 : return reinterpret_cast<void**>(&mRawPtr);
44 : }
45 2 : void assign_assuming_AddRef(nsHtml5StreamParser* newPtr)
46 : {
47 2 : nsHtml5StreamParser* oldPtr = mRawPtr;
48 2 : mRawPtr = newPtr;
49 2 : if (oldPtr)
50 2 : release(oldPtr);
51 2 : }
52 7 : void release(nsHtml5StreamParser* aPtr)
53 : {
54 14 : nsCOMPtr<nsIRunnable> releaser = new nsHtml5StreamParserReleaser(aPtr);
55 7 : if (NS_FAILED(aPtr->DispatchToMain("nsHtml5StreamParserReleaser",
56 : releaser.forget()))) {
57 0 : NS_WARNING("Failed to dispatch releaser event.");
58 : }
59 7 : }
60 :
61 : private:
62 : nsHtml5StreamParser* mRawPtr;
63 :
64 : public:
65 7 : ~nsHtml5StreamParserPtr()
66 7 : {
67 7 : if (mRawPtr)
68 5 : release(mRawPtr);
69 7 : }
70 : // Constructors
71 : nsHtml5StreamParserPtr()
72 : : mRawPtr(0)
73 : // default constructor
74 : {
75 : }
76 : nsHtml5StreamParserPtr(const nsHtml5StreamParserPtr& aSmartPtr)
77 : : mRawPtr(aSmartPtr.mRawPtr)
78 : // copy-constructor
79 : {
80 : if (mRawPtr)
81 : mRawPtr->AddRef();
82 : }
83 7 : explicit nsHtml5StreamParserPtr(nsHtml5StreamParser* aRawPtr)
84 7 : : mRawPtr(aRawPtr)
85 : // construct from a raw pointer (of the right type)
86 : {
87 7 : if (mRawPtr)
88 7 : mRawPtr->AddRef();
89 7 : }
90 : // Assignment operators
91 : nsHtml5StreamParserPtr& operator=(const nsHtml5StreamParserPtr& rhs)
92 : // copy assignment operator
93 : {
94 : assign_with_AddRef(rhs.mRawPtr);
95 : return *this;
96 : }
97 2 : nsHtml5StreamParserPtr& operator=(nsHtml5StreamParser* rhs)
98 : // assign from a raw pointer (of the right type)
99 : {
100 2 : assign_with_AddRef(rhs);
101 2 : return *this;
102 : }
103 : // Other pointer operators
104 : void swap(nsHtml5StreamParserPtr& rhs)
105 : // ...exchange ownership with |rhs|; can save a pair of refcount operations
106 : {
107 : nsHtml5StreamParser* temp = rhs.mRawPtr;
108 : rhs.mRawPtr = mRawPtr;
109 : mRawPtr = temp;
110 : }
111 : void swap(nsHtml5StreamParser*& rhs)
112 : // ...exchange ownership with |rhs|; can save a pair of refcount operations
113 : {
114 : nsHtml5StreamParser* temp = rhs;
115 : rhs = mRawPtr;
116 : mRawPtr = temp;
117 : }
118 : template<typename I>
119 : void forget(I** rhs)
120 : // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
121 : // Useful to avoid unnecessary AddRef/Release pairs with "out"
122 : // parameters where rhs bay be a T** or an I** where I is a base class
123 : // of T.
124 : {
125 : NS_ASSERTION(rhs, "Null pointer passed to forget!");
126 : *rhs = mRawPtr;
127 : mRawPtr = 0;
128 : }
129 66 : nsHtml5StreamParser* get() const
130 : /*
131 : Prefer the implicit conversion provided automatically by |operator nsHtml5StreamParser*() const|.
132 : Use |get()| to resolve ambiguity or to get a castable pointer.
133 : */
134 : {
135 66 : return const_cast<nsHtml5StreamParser*>(mRawPtr);
136 : }
137 43 : operator nsHtml5StreamParser*() const
138 : /*
139 : ...makes an |nsHtml5StreamParserPtr| act like its underlying raw pointer type whenever it
140 : is used in a context where a raw pointer is expected. It is this operator
141 : that makes an |nsHtml5StreamParserPtr| substitutable for a raw pointer.
142 : Prefer the implicit use of this operator to calling |get()|, except where
143 : necessary to resolve ambiguity.
144 : */
145 : {
146 43 : return get();
147 : }
148 23 : nsHtml5StreamParser* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
149 : {
150 23 : NS_PRECONDITION(
151 : mRawPtr != 0,
152 : "You can't dereference a NULL nsHtml5StreamParserPtr with operator->().");
153 23 : return get();
154 : }
155 : nsHtml5StreamParserPtr* get_address()
156 : // This is not intended to be used by clients. See |address_of|
157 : // below.
158 : {
159 : return this;
160 : }
161 : const nsHtml5StreamParserPtr* get_address() const
162 : // This is not intended to be used by clients. See |address_of|
163 : // below.
164 : {
165 : return this;
166 : }
167 :
168 : public:
169 : nsHtml5StreamParser& operator*() const
170 : {
171 : NS_PRECONDITION(
172 : mRawPtr != 0,
173 : "You can't dereference a NULL nsHtml5StreamParserPtr with operator*().");
174 : return *get();
175 : }
176 : nsHtml5StreamParser** StartAssignment()
177 : {
178 : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
179 : return reinterpret_cast<nsHtml5StreamParser**>(begin_assignment());
180 : #else
181 : assign_assuming_AddRef(0);
182 : return reinterpret_cast<nsHtml5StreamParser**>(&mRawPtr);
183 : #endif
184 : }
185 : };
186 :
187 : inline nsHtml5StreamParserPtr*
188 : address_of(nsHtml5StreamParserPtr& aPtr)
189 : {
190 : return aPtr.get_address();
191 : }
192 :
193 : inline const nsHtml5StreamParserPtr*
194 : address_of(const nsHtml5StreamParserPtr& aPtr)
195 : {
196 : return aPtr.get_address();
197 : }
198 :
199 : class nsHtml5StreamParserPtrGetterAddRefs
200 : /*
201 : ...
202 : This class is designed to be used for anonymous temporary objects in the
203 : argument list of calls that return COM interface pointers, e.g.,
204 : nsHtml5StreamParserPtr<IFoo> fooP;
205 : ...->GetAddRefedPointer(getter_AddRefs(fooP))
206 : DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
207 : When initialized with a |nsHtml5StreamParserPtr|, as in the example above, it returns
208 : a |void**|, a |T**|, or an |nsISupports**| as needed, that the
209 : outer call (|GetAddRefedPointer| in this case) can fill in.
210 : This type should be a nested class inside |nsHtml5StreamParserPtr<T>|.
211 : */
212 : {
213 : public:
214 : explicit nsHtml5StreamParserPtrGetterAddRefs(
215 : nsHtml5StreamParserPtr& aSmartPtr)
216 : : mTargetSmartPtr(aSmartPtr)
217 : {
218 : // nothing else to do
219 : }
220 : operator void**()
221 : {
222 : return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
223 : }
224 : operator nsHtml5StreamParser**() { return mTargetSmartPtr.StartAssignment(); }
225 : nsHtml5StreamParser*& operator*()
226 : {
227 : return *(mTargetSmartPtr.StartAssignment());
228 : }
229 :
230 : private:
231 : nsHtml5StreamParserPtr& mTargetSmartPtr;
232 : };
233 :
234 : inline nsHtml5StreamParserPtrGetterAddRefs
235 : getter_AddRefs(nsHtml5StreamParserPtr& aSmartPtr)
236 : /*
237 : Used around a |nsHtml5StreamParserPtr| when
238 : ...makes the class |nsHtml5StreamParserPtrGetterAddRefs| invisible.
239 : */
240 : {
241 : return nsHtml5StreamParserPtrGetterAddRefs(aSmartPtr);
242 : }
243 :
244 : // Comparing an |nsHtml5StreamParserPtr| to |0|
245 :
246 : inline bool
247 : operator==(const nsHtml5StreamParserPtr& lhs, decltype(nullptr))
248 : {
249 : return lhs.get() == nullptr;
250 : }
251 :
252 : inline bool
253 : operator==(decltype(nullptr), const nsHtml5StreamParserPtr& rhs)
254 : {
255 : return nullptr == rhs.get();
256 : }
257 :
258 : inline bool
259 : operator!=(const nsHtml5StreamParserPtr& lhs, decltype(nullptr))
260 : {
261 : return lhs.get() != nullptr;
262 : }
263 :
264 : inline bool
265 : operator!=(decltype(nullptr), const nsHtml5StreamParserPtr& rhs)
266 : {
267 : return nullptr != rhs.get();
268 : }
269 : #endif // !defined(nsHtml5StreamParserPtr_h)
|