]> git.sesse.net Git - vlc/blob - projects/mozilla/control/nporuntime.h
Merge branch 1.0-bugfix
[vlc] / projects / mozilla / control / nporuntime.h
1 /*****************************************************************************
2  * runtime.cpp: support for NPRuntime API for Netscape Script-able plugins
3  *              FYI: http://www.mozilla.org/projects/plugins/npruntime.html
4  *****************************************************************************
5  * Copyright (C) 2002-2005 the VideoLAN team
6  * $Id$
7  *
8  * Authors: Damien Fouilleul <damien.fouilleul@laposte.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifndef __NPORUNTIME_H__
26 #define __NPORUNTIME_H__
27
28 /*
29 ** support framework for runtime script objects
30 */
31
32 #include <npapi.h>
33 #include <npruntime.h>
34
35 static void RuntimeNPClassDeallocate(NPObject *npobj);
36 static void RuntimeNPClassInvalidate(NPObject *npobj);
37 static bool RuntimeNPClassInvokeDefault(NPObject *npobj,
38                                         const NPVariant *args,
39                                         uint32_t argCount,
40                                         NPVariant *result);
41
42 class RuntimeNPObject : public NPObject
43 {
44 public:
45
46     /*
47     ** utility functions
48     */
49
50     static bool isNumberValue(const NPVariant &v)
51     {
52         return NPVARIANT_IS_INT32(v)
53             || NPVARIANT_IS_DOUBLE(v);
54     };
55
56     static int numberValue(const NPVariant &v)
57     {
58         switch( v.type ) {
59             case NPVariantType_Int32:
60                 return NPVARIANT_TO_INT32(v);
61             case NPVariantType_Double:
62                 return(int)NPVARIANT_TO_DOUBLE(v);
63             default:
64                 return 0;
65         }
66     };
67
68     static char* stringValue(const NPString &v);
69     static char* stringValue(const NPVariant &v);
70
71 protected:
72     void *operator new(size_t n)
73     {
74         /*
75         ** Assume that browser has a smarter memory allocator
76         ** than plain old malloc() and use it instead.
77         */
78         return NPN_MemAlloc(n);
79     };
80
81     void operator delete(void *p)
82     {
83         NPN_MemFree(p);
84     };
85
86     bool isValid()
87     {
88         return _instance != NULL;
89     };
90
91     RuntimeNPObject(NPP instance, const NPClass *aClass) :
92         _instance(instance)
93     {
94         _class = const_cast<NPClass *>(aClass);
95         referenceCount = 1;
96     };
97     virtual ~RuntimeNPObject() {};
98
99     enum InvokeResult
100     {
101         INVOKERESULT_NO_ERROR       = 0,    /* returns no error */
102         INVOKERESULT_GENERIC_ERROR  = 1,    /* returns error */
103         INVOKERESULT_NO_SUCH_METHOD = 2,    /* throws method does not exist */
104         INVOKERESULT_INVALID_ARGS   = 3,    /* throws invalid arguments */
105         INVOKERESULT_INVALID_VALUE  = 4,    /* throws invalid value in assignment */
106         INVOKERESULT_OUT_OF_MEMORY  = 5,    /* throws out of memory */
107     };
108
109     friend void RuntimeNPClassDeallocate(NPObject *npobj);
110     friend void RuntimeNPClassInvalidate(NPObject *npobj);
111     template <class RuntimeNPObject> friend bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result);
112     template <class RuntimeNPObject> friend bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value);
113     template <class RuntimeNPObject> friend bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name);
114     template <class RuntimeNPObject> friend bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
115                                                     const NPVariant *args, uint32_t argCount,
116                                                     NPVariant *result);
117     friend bool RuntimeNPClassInvokeDefault(NPObject *npobj,
118                                             const NPVariant *args,
119                                             uint32_t argCount,
120                                             NPVariant *result);
121
122     virtual InvokeResult getProperty(int index, NPVariant &result);
123     virtual InvokeResult setProperty(int index, const NPVariant &value);
124     virtual InvokeResult removeProperty(int index);
125     virtual InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result);
126     virtual InvokeResult invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant &result);
127
128     bool returnInvokeResult(InvokeResult result);
129
130     static InvokeResult invokeResultString(const char *,NPVariant &);
131
132     bool isPluginRunning()
133     {
134         return _instance->pdata;
135     }
136     template<class T> T *getPrivate()
137     {
138         return reinterpret_cast<T *>(_instance->pdata);
139     }
140
141     NPP _instance;
142 };
143
144 template<class T> class RuntimeNPClass : public NPClass
145 {
146 public:
147     static NPClass *getClass()
148     {
149         static NPClass *singleton = new RuntimeNPClass<T>;
150         return singleton;
151     }
152
153 protected:
154     RuntimeNPClass();
155     virtual ~RuntimeNPClass();
156
157     template <class RuntimeNPObject> friend NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass);
158     template <class RuntimeNPObject> friend bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name);
159     template <class RuntimeNPObject> friend bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name);
160     template <class RuntimeNPObject> friend bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result);
161     template <class RuntimeNPObject> friend bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value);
162     template <class RuntimeNPObject> friend bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name);
163     template <class RuntimeNPObject> friend bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
164                                                                       const NPVariant *args, uint32_t argCount,
165                                                                       NPVariant *result);
166
167     RuntimeNPObject *create(NPP instance) const;
168
169     int indexOfMethod(NPIdentifier name) const;
170     int indexOfProperty(NPIdentifier name) const;
171
172 private:
173     NPIdentifier *propertyIdentifiers;
174     NPIdentifier *methodIdentifiers;
175 };
176
177 template<class T>
178 static NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass)
179 {
180     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(aClass);
181     return vClass->create(instance);
182 }
183
184 static void RuntimeNPClassDeallocate(NPObject *npobj)
185 {
186     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
187     vObj->_class = NULL;
188     delete vObj;
189 }
190
191 static void RuntimeNPClassInvalidate(NPObject *npobj)
192 {
193     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
194     vObj->_instance = NULL;
195 }
196
197 template<class T>
198 static bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name)
199 {
200     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
201     return vClass->indexOfMethod(name) != -1;
202 }
203
204 template<class T>
205 static bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name)
206 {
207     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
208     return vClass->indexOfProperty(name) != -1;
209 }
210
211 template<class T>
212 static bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
213 {
214     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
215     if( vObj->isValid() )
216     {
217         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
218         int index = vClass->indexOfProperty(name);
219         if( index != -1 )
220         {
221             return vObj->returnInvokeResult(vObj->getProperty(index, *result));
222         }
223     }
224     return false;
225 }
226
227 template<class T>
228 static bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
229 {
230     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
231     if( vObj->isValid() )
232     {
233         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
234         int index = vClass->indexOfProperty(name);
235         if( index != -1 )
236         {
237             return vObj->returnInvokeResult(vObj->setProperty(index, *value));
238         }
239     }
240     return false;
241 }
242
243 template<class T>
244 static bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name)
245 {
246     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
247     if( vObj->isValid() )
248     {
249         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
250         int index = vClass->indexOfProperty(name);
251         if( index != -1 )
252         {
253             return vObj->returnInvokeResult(vObj->removeProperty(index));
254         }
255     }
256     return false;
257 }
258
259 template<class T>
260 static bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
261                                     const NPVariant *args, uint32_t argCount,
262                                     NPVariant *result)
263 {
264     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
265     if( vObj->isValid() )
266     {
267         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
268         int index = vClass->indexOfMethod(name);
269         if( index != -1 )
270         {
271             return vObj->returnInvokeResult(vObj->invoke(index, args, argCount, *result));
272
273         }
274     }
275     return false;
276 }
277
278 static bool RuntimeNPClassInvokeDefault(NPObject *npobj,
279                                            const NPVariant *args,
280                                            uint32_t argCount,
281                                            NPVariant *result)
282 {
283     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
284     if( vObj->isValid() )
285     {
286         return vObj->returnInvokeResult(vObj->invokeDefault(args, argCount, *result));
287     }
288     return false;
289 }
290
291 template<class T>
292 RuntimeNPClass<T>::RuntimeNPClass()
293 {
294     // retreive property identifiers from names
295     if( T::propertyCount > 0 )
296     {
297         propertyIdentifiers = new NPIdentifier[T::propertyCount];
298         if( propertyIdentifiers )
299             NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::propertyNames),
300                 T::propertyCount, propertyIdentifiers);
301     }
302
303     // retreive method identifiers from names
304     if( T::methodCount > 0 )
305     {
306         methodIdentifiers = new NPIdentifier[T::methodCount];
307         if( methodIdentifiers )
308             NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::methodNames),
309                 T::methodCount, methodIdentifiers);
310     }
311
312     // fill in NPClass structure
313     structVersion  = NP_CLASS_STRUCT_VERSION;
314     allocate       = &RuntimeNPClassAllocate<T>;
315     deallocate     = &RuntimeNPClassDeallocate;
316     invalidate     = &RuntimeNPClassInvalidate;
317     hasMethod      = &RuntimeNPClassHasMethod<T>;
318     invoke         = &RuntimeNPClassInvoke<T>;
319     invokeDefault  = &RuntimeNPClassInvokeDefault;
320     hasProperty    = &RuntimeNPClassHasProperty<T>;
321     getProperty    = &RuntimeNPClassGetProperty<T>;
322     setProperty    = &RuntimeNPClassSetProperty<T>;
323     removeProperty = &RuntimeNPClassRemoveProperty<T>;
324 }
325
326 template<class T>
327 RuntimeNPClass<T>::~RuntimeNPClass()
328 {
329     delete[] propertyIdentifiers;
330     delete[] methodIdentifiers;
331 }
332
333 template<class T>
334 RuntimeNPObject *RuntimeNPClass<T>::create(NPP instance) const
335 {
336     return new T(instance, this);
337 }
338
339 template<class T>
340 int RuntimeNPClass<T>::indexOfMethod(NPIdentifier name) const
341 {
342     if( methodIdentifiers )
343     {
344         for(int c=0; c< T::methodCount; ++c )
345         {
346             if( name == methodIdentifiers[c] )
347                 return c;
348         }
349     }
350     return -1;
351 }
352
353 template<class T>
354 int RuntimeNPClass<T>::indexOfProperty(NPIdentifier name) const
355 {
356     if( propertyIdentifiers )
357     {
358         for(int c=0; c< T::propertyCount; ++c )
359         {
360             if( name == propertyIdentifiers[c] )
361                 return c;
362         }
363     }
364     return -1;
365 }
366
367 #endif