1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=2 et :
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Plugin App.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * The Mozilla Foundation
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Ben Turner <bent.mozilla@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef dom_plugins_PluginScriptableObjectUtils_h
41 : #define dom_plugins_PluginScriptableObjectUtils_h
42 :
43 : #include "PluginModuleParent.h"
44 : #include "PluginModuleChild.h"
45 : #include "PluginInstanceParent.h"
46 : #include "PluginInstanceChild.h"
47 : #include "PluginScriptableObjectParent.h"
48 : #include "PluginScriptableObjectChild.h"
49 :
50 : #include "npapi.h"
51 : #include "npfunctions.h"
52 : #include "npruntime.h"
53 :
54 : #include "nsDebug.h"
55 :
56 : namespace mozilla {
57 : namespace plugins {
58 :
59 : inline PluginInstanceParent*
60 0 : GetInstance(NPObject* aObject)
61 : {
62 0 : NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
63 : "Bad class!");
64 :
65 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
66 0 : if (object->invalidated) {
67 0 : NS_WARNING("Calling method on an invalidated object!");
68 0 : return nsnull;
69 : }
70 0 : if (!object->parent) {
71 0 : return nsnull;
72 : }
73 0 : return object->parent->GetInstance();
74 : }
75 :
76 : inline NPObject*
77 0 : NPObjectFromVariant(const Variant& aRemoteVariant)
78 : {
79 0 : switch (aRemoteVariant.type()) {
80 : case Variant::TPPluginScriptableObjectParent: {
81 : PluginScriptableObjectParent* actor =
82 : const_cast<PluginScriptableObjectParent*>(
83 : reinterpret_cast<const PluginScriptableObjectParent*>(
84 0 : aRemoteVariant.get_PPluginScriptableObjectParent()));
85 0 : return actor->GetObject(true);
86 : }
87 :
88 : case Variant::TPPluginScriptableObjectChild: {
89 : PluginScriptableObjectChild* actor =
90 : const_cast<PluginScriptableObjectChild*>(
91 : reinterpret_cast<const PluginScriptableObjectChild*>(
92 0 : aRemoteVariant.get_PPluginScriptableObjectChild()));
93 0 : return actor->GetObject(true);
94 : }
95 :
96 : default:
97 0 : NS_NOTREACHED("Shouldn't get here!");
98 0 : return nsnull;
99 : }
100 : }
101 :
102 : inline NPObject*
103 : NPObjectFromVariant(const NPVariant& aVariant)
104 : {
105 : NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
106 : return NPVARIANT_TO_OBJECT(aVariant);
107 : }
108 :
109 : inline const NPNetscapeFuncs*
110 0 : GetNetscapeFuncs(PluginInstanceParent* aInstance)
111 : {
112 0 : PluginModuleParent* module = aInstance->Module();
113 0 : if (!module) {
114 0 : NS_WARNING("Null module?!");
115 0 : return nsnull;
116 : }
117 0 : return module->GetNetscapeFuncs();
118 : }
119 :
120 : inline const NPNetscapeFuncs*
121 0 : GetNetscapeFuncs(NPObject* aObject)
122 : {
123 0 : NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
124 : "Bad class!");
125 :
126 0 : PluginInstanceParent* instance = GetInstance(aObject);
127 0 : if (!instance) {
128 0 : return nsnull;
129 : }
130 :
131 0 : return GetNetscapeFuncs(instance);
132 : }
133 :
134 : inline void
135 0 : ReleaseRemoteVariant(Variant& aVariant)
136 : {
137 0 : switch (aVariant.type()) {
138 : case Variant::TPPluginScriptableObjectParent: {
139 : PluginScriptableObjectParent* actor =
140 : const_cast<PluginScriptableObjectParent*>(
141 : reinterpret_cast<const PluginScriptableObjectParent*>(
142 0 : aVariant.get_PPluginScriptableObjectParent()));
143 0 : actor->Unprotect();
144 0 : break;
145 : }
146 :
147 : case Variant::TPPluginScriptableObjectChild: {
148 0 : NS_ASSERTION(PluginModuleChild::current(),
149 : "Should only be running in the child!");
150 : PluginScriptableObjectChild* actor =
151 : const_cast<PluginScriptableObjectChild*>(
152 : reinterpret_cast<const PluginScriptableObjectChild*>(
153 0 : aVariant.get_PPluginScriptableObjectChild()));
154 0 : actor->Unprotect();
155 0 : break;
156 : }
157 :
158 : default:
159 0 : break; // Intentional fall-through for other variant types.
160 : }
161 :
162 0 : aVariant = mozilla::void_t();
163 0 : }
164 :
165 : bool
166 : ConvertToVariant(const Variant& aRemoteVariant,
167 : NPVariant& aVariant,
168 : PluginInstanceParent* aInstance = nsnull);
169 :
170 : template <class InstanceType>
171 : bool
172 0 : ConvertToRemoteVariant(const NPVariant& aVariant,
173 : Variant& aRemoteVariant,
174 : InstanceType* aInstance,
175 : bool aProtectActors = false);
176 :
177 : class ProtectedVariant
178 : {
179 : public:
180 0 : ProtectedVariant(const NPVariant& aVariant,
181 : PluginInstanceParent* aInstance)
182 0 : {
183 0 : mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
184 0 : }
185 :
186 0 : ProtectedVariant(const NPVariant& aVariant,
187 : PluginInstanceChild* aInstance)
188 0 : {
189 0 : mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
190 0 : }
191 :
192 0 : ~ProtectedVariant() {
193 0 : ReleaseRemoteVariant(mVariant);
194 0 : }
195 :
196 0 : bool IsOk() {
197 0 : return mOk;
198 : }
199 :
200 0 : operator const Variant&() {
201 0 : return mVariant;
202 : }
203 :
204 : private:
205 : Variant mVariant;
206 : bool mOk;
207 : };
208 :
209 : class ProtectedVariantArray
210 : {
211 : public:
212 0 : ProtectedVariantArray(const NPVariant* aArgs,
213 : PRUint32 aCount,
214 : PluginInstanceParent* aInstance)
215 0 : : mUsingShadowArray(false)
216 : {
217 0 : for (PRUint32 index = 0; index < aCount; index++) {
218 0 : Variant* remoteVariant = mArray.AppendElement();
219 0 : if (!(remoteVariant &&
220 0 : ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
221 0 : true))) {
222 0 : mOk = false;
223 0 : return;
224 : }
225 : }
226 0 : mOk = true;
227 : }
228 :
229 0 : ProtectedVariantArray(const NPVariant* aArgs,
230 : PRUint32 aCount,
231 : PluginInstanceChild* aInstance)
232 0 : : mUsingShadowArray(false)
233 : {
234 0 : for (PRUint32 index = 0; index < aCount; index++) {
235 0 : Variant* remoteVariant = mArray.AppendElement();
236 0 : if (!(remoteVariant &&
237 0 : ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
238 0 : true))) {
239 0 : mOk = false;
240 0 : return;
241 : }
242 : }
243 0 : mOk = true;
244 : }
245 :
246 0 : ~ProtectedVariantArray()
247 0 : {
248 0 : InfallibleTArray<Variant>& vars = EnsureAndGetShadowArray();
249 0 : PRUint32 count = vars.Length();
250 0 : for (PRUint32 index = 0; index < count; index++) {
251 0 : ReleaseRemoteVariant(vars[index]);
252 : }
253 0 : }
254 :
255 0 : operator const InfallibleTArray<Variant>&()
256 : {
257 0 : return EnsureAndGetShadowArray();
258 : }
259 :
260 0 : bool IsOk()
261 : {
262 0 : return mOk;
263 : }
264 :
265 : private:
266 : InfallibleTArray<Variant>&
267 0 : EnsureAndGetShadowArray()
268 : {
269 0 : if (!mUsingShadowArray) {
270 0 : mShadowArray.SwapElements(mArray);
271 0 : mUsingShadowArray = true;
272 : }
273 0 : return mShadowArray;
274 : }
275 :
276 : // We convert the variants fallibly, but pass them to Call*()
277 : // methods as an infallible array
278 : nsTArray<Variant> mArray;
279 : InfallibleTArray<Variant> mShadowArray;
280 : bool mOk;
281 : bool mUsingShadowArray;
282 : };
283 :
284 : template<class ActorType>
285 : struct ProtectedActorTraits
286 : {
287 : static bool Nullable();
288 : };
289 :
290 : template<class ActorType, class Traits=ProtectedActorTraits<ActorType> >
291 : class ProtectedActor
292 : {
293 : public:
294 0 : ProtectedActor(ActorType* aActor) : mActor(aActor)
295 : {
296 0 : if (!Traits::Nullable()) {
297 0 : NS_ASSERTION(mActor, "This should never be null!");
298 : }
299 0 : }
300 :
301 0 : ~ProtectedActor()
302 : {
303 0 : if (Traits::Nullable() && !mActor)
304 0 : return;
305 0 : mActor->Unprotect();
306 0 : }
307 :
308 0 : ActorType* operator->()
309 : {
310 0 : return mActor;
311 : }
312 :
313 0 : operator bool()
314 : {
315 0 : return !!mActor;
316 : }
317 :
318 : private:
319 : ActorType* mActor;
320 : };
321 :
322 : template<>
323 : struct ProtectedActorTraits<PluginScriptableObjectParent>
324 : {
325 0 : static bool Nullable() { return true; }
326 : };
327 :
328 : template<>
329 : struct ProtectedActorTraits<PluginScriptableObjectChild>
330 : {
331 0 : static bool Nullable() { return false; }
332 : };
333 :
334 : } /* namespace plugins */
335 : } /* namespace mozilla */
336 :
337 : #include "PluginScriptableObjectUtils-inl.h"
338 :
339 : #endif /* dom_plugins_PluginScriptableObjectUtils_h */
|