]> git.sesse.net Git - vlc/blob - mozilla/control/nporuntime.h
70d89170774b8f70b1350aea5c3a7b9d4a6dd8f0
[vlc] / 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: RuntimeNPObject.h 14466 2006-02-22 23:34:54Z dionoea $
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         return NPN_MemAlloc(n);
75     };
76
77     void operator delete(void *p)
78     {
79         /*
80         ** Some memory scribble happens occasionally on freed object
81         ** when used on Firefox (MacOS X) and may cause crash, a leak
82         ** sounds like the better option.
83         */
84         //NPN_MemFree(p);
85     };
86
87     RuntimeNPObject(NPP instance, const NPClass *aClass) :
88         _instance(instance)
89     {
90         _class = const_cast<NPClass *>(aClass);
91         //referenceCount = 1;
92     };
93     virtual ~RuntimeNPObject() {};
94
95     enum InvokeResult
96     {
97         INVOKERESULT_NO_ERROR       = 0,    /* returns no error */
98         INVOKERESULT_GENERIC_ERROR  = 1,    /* returns error */
99         INVOKERESULT_NO_SUCH_METHOD = 2,    /* throws method does not exist */
100         INVOKERESULT_INVALID_ARGS   = 3,    /* throws invalid arguments */
101         INVOKERESULT_INVALID_VALUE  = 4,    /* throws invalid value in assignment */
102         INVOKERESULT_OUT_OF_MEMORY  = 5,    /* throws out of memory */
103     };
104
105     friend void RuntimeNPClassDeallocate(NPObject *npobj);
106     friend void RuntimeNPClassInvalidate(NPObject *npobj);
107     template <class RuntimeNPObject> friend bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result);
108     template <class RuntimeNPObject> friend bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value);
109     template <class RuntimeNPObject> friend bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name);
110     template <class RuntimeNPObject> friend bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
111                                                     const NPVariant *args, uint32_t argCount,
112                                                     NPVariant *result);
113     friend bool RuntimeNPClassInvokeDefault(NPObject *npobj,
114                                             const NPVariant *args,
115                                             uint32_t argCount,
116                                             NPVariant *result);
117
118     virtual InvokeResult getProperty(int index, NPVariant &result);
119     virtual InvokeResult setProperty(int index, const NPVariant &value);
120     virtual InvokeResult removeProperty(int index);
121     virtual InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result);
122     virtual InvokeResult invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant &result);
123
124     bool returnInvokeResult(InvokeResult result);
125
126     NPP _instance;
127 };
128
129 template<class T> class RuntimeNPClass : public NPClass
130 {
131 public:
132     static NPClass *getClass()
133     {
134         static NPClass *singleton = new RuntimeNPClass<T>;
135         return singleton;
136     }
137
138 protected:
139     RuntimeNPClass();
140     virtual ~RuntimeNPClass();
141
142     template <class RuntimeNPObject> friend NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass);
143     template <class RuntimeNPObject> friend bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name);
144     template <class RuntimeNPObject> friend bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name);
145     template <class RuntimeNPObject> friend bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result);
146     template <class RuntimeNPObject> friend bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value);
147     template <class RuntimeNPObject> friend bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name);
148     template <class RuntimeNPObject> friend bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
149                                                                       const NPVariant *args, uint32_t argCount,
150                                                                       NPVariant *result);
151
152     RuntimeNPObject *create(NPP instance) const;
153
154     int indexOfMethod(NPIdentifier name) const;
155     int indexOfProperty(NPIdentifier name) const;
156
157 private:
158     NPIdentifier *propertyIdentifiers;
159     NPIdentifier *methodIdentifiers;
160 };
161
162 template<class T>
163 static NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass)
164 {
165     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(aClass);
166     return vClass->create(instance);
167 }
168
169 static void RuntimeNPClassDeallocate(NPObject *npobj)
170 {
171     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
172     vObj->_class = NULL;
173     delete vObj;
174 }
175
176 static void RuntimeNPClassInvalidate(NPObject *npobj)
177 {
178     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
179     vObj->_instance = NULL;
180 }
181
182 template<class T>
183 static bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name)
184 {
185     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
186     return vClass->indexOfMethod(name) != -1;
187 }
188
189 template<class T>
190 static bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name)
191 {
192     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
193     return vClass->indexOfProperty(name) != -1;
194 }
195
196 template<class T>
197 static bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
198 {
199     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
200     if( vObj->_instance )
201     {
202         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
203         int index = vClass->indexOfProperty(name);
204         if( index != -1 )
205         {
206             return vObj->returnInvokeResult(vObj->getProperty(index, *result));
207         }
208     }
209     return false;
210 }
211
212 template<class T>
213 static bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
214 {
215     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
216     if( vObj->_instance )
217     {
218         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
219         int index = vClass->indexOfProperty(name);
220         if( index != -1 )
221         {
222             return vObj->returnInvokeResult(vObj->setProperty(index, *value));
223         }
224     }
225     return false;
226 }
227
228 template<class T>
229 static bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name)
230 {
231     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
232     if( vObj->_instance )
233     {
234         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
235         int index = vClass->indexOfProperty(name);
236         if( index != -1 )
237         {
238             return vObj->returnInvokeResult(vObj->removeProperty(index));
239         }
240     }
241     return false;
242 }
243
244 template<class T>
245 static bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
246                                     const NPVariant *args, uint32_t argCount,
247                                     NPVariant *result)
248 {
249     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
250     if( vObj->_instance )
251     {
252         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
253         int index = vClass->indexOfMethod(name);
254         if( index != -1 )
255         {
256             return vObj->returnInvokeResult(vObj->invoke(index, args, argCount, *result));
257
258         }
259     }
260     return false;
261 }
262
263 static bool RuntimeNPClassInvokeDefault(NPObject *npobj,
264                                            const NPVariant *args,
265                                            uint32_t argCount,
266                                            NPVariant *result)
267 {
268     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
269     if( vObj->_instance )
270     {
271         return vObj->returnInvokeResult(vObj->invokeDefault(args, argCount, *result));
272     }
273     return false;
274 }
275
276 template<class T>
277 RuntimeNPClass<T>::RuntimeNPClass()
278 {
279     // retreive property identifiers from names
280     if( T::propertyCount > 0 )
281     {
282         propertyIdentifiers = new NPIdentifier[T::propertyCount];
283         if( propertyIdentifiers )
284             NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::propertyNames),
285                 T::propertyCount, propertyIdentifiers);
286     }
287
288     // retreive method identifiers from names
289     if( T::methodCount > 0 )
290     {
291         methodIdentifiers = new NPIdentifier[T::methodCount];
292         if( methodIdentifiers )
293             NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::methodNames),
294                 T::methodCount, methodIdentifiers);
295     }
296
297     // fill in NPClass structure
298     structVersion  = NP_CLASS_STRUCT_VERSION;
299     allocate       = &RuntimeNPClassAllocate<T>;
300     deallocate     = &RuntimeNPClassDeallocate;
301     invalidate     = &RuntimeNPClassInvalidate;
302     hasMethod      = &RuntimeNPClassHasMethod<T>;
303     invoke         = &RuntimeNPClassInvoke<T>;
304     invokeDefault  = &RuntimeNPClassInvokeDefault;
305     hasProperty    = &RuntimeNPClassHasProperty<T>;
306     getProperty    = &RuntimeNPClassGetProperty<T>;
307     setProperty    = &RuntimeNPClassSetProperty<T>;
308     removeProperty = &RuntimeNPClassRemoveProperty<T>;
309 }
310
311 template<class T>
312 RuntimeNPClass<T>::~RuntimeNPClass()
313 {
314     delete propertyIdentifiers;
315     delete methodIdentifiers;
316 }
317
318 template<class T>
319 RuntimeNPObject *RuntimeNPClass<T>::create(NPP instance) const
320 {
321     return new T(instance, this);
322 }
323
324 template<class T>
325 int RuntimeNPClass<T>::indexOfMethod(NPIdentifier name) const
326 {
327     if( methodIdentifiers )
328     {
329         for(int c=0; c< T::methodCount; ++c )
330         {
331             if( name == methodIdentifiers[c] )
332                 return c;
333         }
334     }
335     return -1;
336 }
337
338 template<class T>
339 int RuntimeNPClass<T>::indexOfProperty(NPIdentifier name) const
340 {
341     if( propertyIdentifiers )
342     {
343         for(int c=0; c< T::propertyCount; ++c )
344         {
345             if( name == propertyIdentifiers[c] )
346                 return c;
347         }
348     }
349     return -1;
350 }
351
352 #endif