1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
---|
2 | /* ***** BEGIN LICENSE BLOCK *****
|
---|
3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
---|
4 | *
|
---|
5 | * The contents of this file are subject to the Mozilla Public License Version
|
---|
6 | * 1.1 (the "License"); you may not use this file except in compliance with
|
---|
7 | * the License. You may obtain a copy of the License at
|
---|
8 | * http://www.mozilla.org/MPL/
|
---|
9 | *
|
---|
10 | * Software distributed under the License is distributed on an "AS IS" basis,
|
---|
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
12 | * for the specific language governing rights and limitations under the
|
---|
13 | * License.
|
---|
14 | *
|
---|
15 | * The Original Code is mozilla.org code.
|
---|
16 | *
|
---|
17 | * The Initial Developer of the Original Code is
|
---|
18 | * Netscape Communications Corporation.
|
---|
19 | * Portions created by the Initial Developer are Copyright (C) 1998
|
---|
20 | * the Initial Developer. All Rights Reserved.
|
---|
21 | *
|
---|
22 | * Contributor(s):
|
---|
23 | * Pierre Phaneuf <[email protected]>
|
---|
24 | * Scott Collins <[email protected]>
|
---|
25 | * Dan Mosedale <[email protected]>
|
---|
26 | *
|
---|
27 | * Alternatively, the contents of this file may be used under the terms of
|
---|
28 | * either of the GNU General Public License Version 2 or later (the "GPL"),
|
---|
29 | * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
---|
30 | * in which case the provisions of the GPL or the LGPL are applicable instead
|
---|
31 | * of those above. If you wish to allow use of your version of this file only
|
---|
32 | * under the terms of either the GPL or the LGPL, and not to allow others to
|
---|
33 | * use your version of this file under the terms of the MPL, indicate your
|
---|
34 | * decision by deleting the provisions above and replace them with the notice
|
---|
35 | * and other provisions required by the GPL or the LGPL. If you do not delete
|
---|
36 | * the provisions above, a recipient may use your version of this file under
|
---|
37 | * the terms of any one of the MPL, the GPL or the LGPL.
|
---|
38 | *
|
---|
39 | * ***** END LICENSE BLOCK ***** */
|
---|
40 |
|
---|
41 | #ifndef nsISupportsUtils_h__
|
---|
42 | #define nsISupportsUtils_h__
|
---|
43 |
|
---|
44 | #ifndef nscore_h___
|
---|
45 | #include "nscore.h"
|
---|
46 | #endif
|
---|
47 |
|
---|
48 | #ifndef nsISupportsBase_h__
|
---|
49 | #include "nsISupportsBase.h"
|
---|
50 | #endif
|
---|
51 |
|
---|
52 | #ifndef nsError_h__
|
---|
53 | #include "nsError.h"
|
---|
54 | #endif
|
---|
55 |
|
---|
56 | #ifndef nsDebug_h___
|
---|
57 | #include "nsDebug.h"
|
---|
58 | #endif
|
---|
59 |
|
---|
60 | #ifndef nsISupportsImpl_h__
|
---|
61 | #include "nsISupportsImpl.h"
|
---|
62 | #endif
|
---|
63 |
|
---|
64 | /**
|
---|
65 | * Macro for instantiating a new object that implements nsISupports.
|
---|
66 | * Note that you can only use this if you adhere to the no arguments
|
---|
67 | * constructor com policy (which you really should!).
|
---|
68 | * @param _result Where the new instance pointer is stored
|
---|
69 | * @param _type The type of object to call "new" with.
|
---|
70 | */
|
---|
71 | #define NS_NEWXPCOM(_result,_type) \
|
---|
72 | PR_BEGIN_MACRO \
|
---|
73 | _result = new _type(); \
|
---|
74 | PR_END_MACRO
|
---|
75 |
|
---|
76 | /**
|
---|
77 | * Macro for deleting an object that implements nsISupports.
|
---|
78 | * @param _ptr The object to delete.
|
---|
79 | */
|
---|
80 | #define NS_DELETEXPCOM(_ptr) \
|
---|
81 | PR_BEGIN_MACRO \
|
---|
82 | delete (_ptr); \
|
---|
83 | PR_END_MACRO
|
---|
84 |
|
---|
85 | /**
|
---|
86 | * Macro for adding a reference to an interface.
|
---|
87 | * @param _ptr The interface pointer.
|
---|
88 | */
|
---|
89 | #define NS_ADDREF(_ptr) \
|
---|
90 | (_ptr)->AddRef()
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * Macro for adding a reference to this. This macro should be used
|
---|
94 | * because NS_ADDREF (when tracing) may require an ambiguous cast
|
---|
95 | * from the pointers primary type to nsISupports. This macro sidesteps
|
---|
96 | * that entire problem.
|
---|
97 | */
|
---|
98 | #define NS_ADDREF_THIS() \
|
---|
99 | AddRef()
|
---|
100 |
|
---|
101 |
|
---|
102 | extern "C++" {
|
---|
103 | // ...because some one is accidentally including this file inside
|
---|
104 | // an |extern "C"|
|
---|
105 |
|
---|
106 |
|
---|
107 | // Making this a |inline| |template| allows |expr| to be evaluated only once,
|
---|
108 | // yet still denies you the ability to |AddRef()| an |nsCOMPtr|.
|
---|
109 | template <class T>
|
---|
110 | inline
|
---|
111 | nsrefcnt
|
---|
112 | ns_if_addref( T expr )
|
---|
113 | {
|
---|
114 | return expr ? expr->AddRef() : 0;
|
---|
115 | }
|
---|
116 |
|
---|
117 | } /* extern "C++" */
|
---|
118 |
|
---|
119 | /**
|
---|
120 | * Macro for adding a reference to an interface that checks for NULL.
|
---|
121 | * @param _expr The interface pointer.
|
---|
122 | */
|
---|
123 | #define NS_IF_ADDREF(_expr) ns_if_addref(_expr)
|
---|
124 |
|
---|
125 | /*
|
---|
126 | * Given these declarations, it explicitly OK and efficient to end a `getter' with:
|
---|
127 | *
|
---|
128 | * NS_IF_ADDREF(*result = mThing);
|
---|
129 | *
|
---|
130 | * even if |mThing| is an |nsCOMPtr|. If |mThing| is an |nsCOMPtr|, however, it is still
|
---|
131 | * _illegal_ to say |NS_IF_ADDREF(mThing)|.
|
---|
132 | */
|
---|
133 |
|
---|
134 | /**
|
---|
135 | * Macro for releasing a reference to an interface.
|
---|
136 | * @param _ptr The interface pointer.
|
---|
137 | */
|
---|
138 | #define NS_RELEASE(_ptr) \
|
---|
139 | PR_BEGIN_MACRO \
|
---|
140 | (_ptr)->Release(); \
|
---|
141 | (_ptr) = 0; \
|
---|
142 | PR_END_MACRO
|
---|
143 |
|
---|
144 | /**
|
---|
145 | * Macro for releasing a reference to an interface.
|
---|
146 | * @param _ptr The interface pointer.
|
---|
147 | */
|
---|
148 | #define NS_RELEASE_THIS() \
|
---|
149 | Release()
|
---|
150 |
|
---|
151 | /**
|
---|
152 | * Macro for releasing a reference to an interface, except that this
|
---|
153 | * macro preserves the return value from the underlying Release call.
|
---|
154 | * The interface pointer argument will only be NULLed if the reference count
|
---|
155 | * goes to zero.
|
---|
156 | *
|
---|
157 | * @param _ptr The interface pointer.
|
---|
158 | */
|
---|
159 | #define NS_RELEASE2(_ptr,_rv) \
|
---|
160 | PR_BEGIN_MACRO \
|
---|
161 | _rv = (_ptr)->Release(); \
|
---|
162 | if (0 == (_rv)) (_ptr) = 0; \
|
---|
163 | PR_END_MACRO
|
---|
164 |
|
---|
165 | /**
|
---|
166 | * Macro for releasing a reference to an interface that checks for NULL;
|
---|
167 | * @param _ptr The interface pointer.
|
---|
168 | */
|
---|
169 | #define NS_IF_RELEASE(_ptr) \
|
---|
170 | PR_BEGIN_MACRO \
|
---|
171 | if (_ptr) { \
|
---|
172 | (_ptr)->Release(); \
|
---|
173 | (_ptr) = 0; \
|
---|
174 | } \
|
---|
175 | PR_END_MACRO
|
---|
176 |
|
---|
177 | /*
|
---|
178 | * Often you have to cast an implementation pointer, e.g., |this|, to an
|
---|
179 | * |nsISupports*|, but because you have multiple inheritance, a simple cast
|
---|
180 | * is ambiguous. One could simply say, e.g., (given a base |nsIBase|),
|
---|
181 | * |NS_STATIC_CAST(nsIBase*, this)|; but that disguises the fact that what
|
---|
182 | * you are really doing is disambiguating the |nsISupports|. You could make
|
---|
183 | * that more obvious with a double cast, e.g., |NS_STATIC_CAST(nsISupports*,
|
---|
184 | * NS_STATIC_CAST(nsIBase*, this))|, but that is bulky and harder to read...
|
---|
185 | *
|
---|
186 | * The following macro is clean, short, and obvious. In the example above,
|
---|
187 | * you would use it like this: |NS_ISUPPORTS_CAST(nsIBase*, this)|.
|
---|
188 | */
|
---|
189 |
|
---|
190 | #define NS_ISUPPORTS_CAST(__unambiguousBase, __expr) \
|
---|
191 | NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(__unambiguousBase, __expr))
|
---|
192 |
|
---|
193 | extern "C++" {
|
---|
194 | // ...because some one is accidentally including this file inside
|
---|
195 | // an |extern "C"|
|
---|
196 |
|
---|
197 | class nsISupports;
|
---|
198 |
|
---|
199 | template <class T>
|
---|
200 | struct nsCOMTypeInfo
|
---|
201 | {
|
---|
202 | static const nsIID& GetIID() { return T::GetIID(); }
|
---|
203 | };
|
---|
204 |
|
---|
205 | NS_SPECIALIZE_TEMPLATE
|
---|
206 | struct nsCOMTypeInfo<nsISupports>
|
---|
207 | {
|
---|
208 | static const nsIID& GetIID() {
|
---|
209 | static const nsIID iid_NS_ISUPPORTS_IID = NS_ISUPPORTS_IID; return iid_NS_ISUPPORTS_IID;
|
---|
210 | }
|
---|
211 | };
|
---|
212 |
|
---|
213 | #define NS_GET_IID(T) nsCOMTypeInfo<T>::GetIID()
|
---|
214 |
|
---|
215 | // a type-safe shortcut for calling the |QueryInterface()| member function
|
---|
216 | template <class T, class DestinationType>
|
---|
217 | inline
|
---|
218 | nsresult
|
---|
219 | CallQueryInterface( T* aSource, DestinationType** aDestination )
|
---|
220 | {
|
---|
221 | NS_PRECONDITION(aSource, "null parameter");
|
---|
222 | NS_PRECONDITION(aDestination, "null parameter");
|
---|
223 |
|
---|
224 | return aSource->QueryInterface(NS_GET_IID(DestinationType),
|
---|
225 | NS_REINTERPRET_CAST(void**, aDestination));
|
---|
226 | }
|
---|
227 |
|
---|
228 | } // extern "C++"
|
---|
229 |
|
---|
230 | #endif /* __nsISupportsUtils_h */
|
---|