]> git.sesse.net Git - vlc/blob - projects/mozilla/control/nporuntime.h
2f6c91bb9214fa3ef053901958a23f771321f3e9
[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     NPP _instance;
131 };
132
133 template<class T> class RuntimeNPClass : public NPClass
134 {
135 public:
136     static NPClass *getClass()
137     {
138         static NPClass *singleton = new RuntimeNPClass<T>;
139         return singleton;
140     }
141
142 protected:
143     RuntimeNPClass();
144     virtual ~RuntimeNPClass();
145
146     template <class RuntimeNPObject> friend NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass);
147     template <class RuntimeNPObject> friend bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name);
148     template <class RuntimeNPObject> friend bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name);
149     template <class RuntimeNPObject> friend bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result);
150     template <class RuntimeNPObject> friend bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value);
151     template <class RuntimeNPObject> friend bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name);
152     template <class RuntimeNPObject> friend bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
153                                                                       const NPVariant *args, uint32_t argCount,
154                                                                       NPVariant *result);
155
156     RuntimeNPObject *create(NPP instance) const;
157
158     int indexOfMethod(NPIdentifier name) const;
159     int indexOfProperty(NPIdentifier name) const;
160
161 private:
162     NPIdentifier *propertyIdentifiers;
163     NPIdentifier *methodIdentifiers;
164 };
165
166 template<class T>
167 static NPObject *RuntimeNPClassAllocate(NPP instance, NPClass *aClass)
168 {
169     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(aClass);
170     return vClass->create(instance);
171 }
172
173 static void RuntimeNPClassDeallocate(NPObject *npobj)
174 {
175     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
176     vObj->_class = NULL;
177     delete vObj;
178 }
179
180 static void RuntimeNPClassInvalidate(NPObject *npobj)
181 {
182     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
183     vObj->_instance = NULL;
184 }
185
186 template<class T>
187 static bool RuntimeNPClassHasMethod(NPObject *npobj, NPIdentifier name)
188 {
189     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
190     return vClass->indexOfMethod(name) != -1;
191 }
192
193 template<class T>
194 static bool RuntimeNPClassHasProperty(NPObject *npobj, NPIdentifier name)
195 {
196     const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
197     return vClass->indexOfProperty(name) != -1;
198 }
199
200 template<class T>
201 static bool RuntimeNPClassGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
202 {
203     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
204     if( vObj->isValid() )
205     {
206         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
207         int index = vClass->indexOfProperty(name);
208         if( index != -1 )
209         {
210             return vObj->returnInvokeResult(vObj->getProperty(index, *result));
211         }
212     }
213     return false;
214 }
215
216 template<class T>
217 static bool RuntimeNPClassSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
218 {
219     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
220     if( vObj->isValid() )
221     {
222         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
223         int index = vClass->indexOfProperty(name);
224         if( index != -1 )
225         {
226             return vObj->returnInvokeResult(vObj->setProperty(index, *value));
227         }
228     }
229     return false;
230 }
231
232 template<class T>
233 static bool RuntimeNPClassRemoveProperty(NPObject *npobj, NPIdentifier name)
234 {
235     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
236     if( vObj->isValid() )
237     {
238         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
239         int index = vClass->indexOfProperty(name);
240         if( index != -1 )
241         {
242             return vObj->returnInvokeResult(vObj->removeProperty(index));
243         }
244     }
245     return false;
246 }
247
248 template<class T>
249 static bool RuntimeNPClassInvoke(NPObject *npobj, NPIdentifier name,
250                                     const NPVariant *args, uint32_t argCount,
251                                     NPVariant *result)
252 {
253     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
254     if( vObj->isValid() )
255     {
256         const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(npobj->_class);
257         int index = vClass->indexOfMethod(name);
258         if( index != -1 )
259         {
260             return vObj->returnInvokeResult(vObj->invoke(index, args, argCount, *result));
261
262         }
263     }
264     return false;
265 }
266
267 static bool RuntimeNPClassInvokeDefault(NPObject *npobj,
268                                            const NPVariant *args,
269                                            uint32_t argCount,
270                                            NPVariant *result)
271 {
272     RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
273     if( vObj->isValid() )
274     {
275         return vObj->returnInvokeResult(vObj->invokeDefault(args, argCount, *result));
276     }
277     return false;
278 }
279
280 template<class T>
281 RuntimeNPClass<T>::RuntimeNPClass()
282 {
283     // retreive property identifiers from names
284     if( T::propertyCount > 0 )
285     {
286         propertyIdentifiers = new NPIdentifier[T::propertyCount];
287         if( propertyIdentifiers )
288             NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::propertyNames),
289                 T::propertyCount, propertyIdentifiers);
290     }
291
292     // retreive method identifiers from names
293     if( T::methodCount > 0 )
294     {
295         methodIdentifiers = new NPIdentifier[T::methodCount];
296         if( methodIdentifiers )
297             NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::methodNames),
298                 T::methodCount, methodIdentifiers);
299     }
300
301     // fill in NPClass structure
302     structVersion  = NP_CLASS_STRUCT_VERSION;
303     allocate       = &RuntimeNPClassAllocate<T>;
304     deallocate     = &RuntimeNPClassDeallocate;
305     invalidate     = &RuntimeNPClassInvalidate;
306     hasMethod      = &RuntimeNPClassHasMethod<T>;
307     invoke         = &RuntimeNPClassInvoke<T>;
308     invokeDefault  = &RuntimeNPClassInvokeDefault;
309     hasProperty    = &RuntimeNPClassHasProperty<T>;
310     getProperty    = &RuntimeNPClassGetProperty<T>;
311     setProperty    = &RuntimeNPClassSetProperty<T>;
312     removeProperty = &RuntimeNPClassRemoveProperty<T>;
313 }
314
315 template<class T>
316 RuntimeNPClass<T>::~RuntimeNPClass()
317 {
318     delete propertyIdentifiers;
319     delete methodIdentifiers;
320 }
321
322 template<class T>
323 RuntimeNPObject *RuntimeNPClass<T>::create(NPP instance) const
324 {
325     return new T(instance, this);
326 }
327
328 template<class T>
329 int RuntimeNPClass<T>::indexOfMethod(NPIdentifier name) const
330 {
331     if( methodIdentifiers )
332     {
333         for(int c=0; c< T::methodCount; ++c )
334         {
335             if( name == methodIdentifiers[c] )
336                 return c;
337         }
338     }
339     return -1;
340 }
341
342 template<class T>
343 int RuntimeNPClass<T>::indexOfProperty(NPIdentifier name) const
344 {
345     if( propertyIdentifiers )
346     {
347         for(int c=0; c< T::propertyCount; ++c )
348         {
349             if( name == propertyIdentifiers[c] )
350                 return c;
351         }
352     }
353     return -1;
354 }
355
356 #endif