nporuntime.h 9.61 KB
Newer Older
1
/*****************************************************************************
2 3
 * runtime.cpp: support for NPRuntime API for Netscape Script-able plugins
 *              FYI: http://www.mozilla.org/projects/plugins/npruntime.html
4
 *****************************************************************************
5
 * Copyright (C) 2002-2012  VLC authors and VideoLAN
Konstantin Pavlov's avatar
Konstantin Pavlov committed
6
 * $Id$
7 8
 *
 * Authors: Damien Fouilleul <damien.fouilleul@laposte.net>
9
 *          JP Dinger <jpd@videolan.org>
10
 *          Hugo Beauzée-Luyssen <hugo@beauzee.fr>
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifndef __NPORUNTIME_H__
#define __NPORUNTIME_H__

/*
** support framework for runtime script objects
*/

34
//on windows, to avoid including <npapi.h>
35 36 37
//from Microsoft SDK (rather then from Mozilla SDK),
//#include it indirectly via <npfunctions.h>
#include <npfunctions.h>
38
#include <npruntime.h>
39
#include <stdlib.h>
40 41 42 43

class RuntimeNPObject : public NPObject
{
public:
44 45 46
    // Lazy child object cration helper. Doing this avoids
    // ownership problems with firefox.
    template<class T> void InstantObj( NPObject *&obj );
47

48 49 50
    bool isValid()
    {
        return _instance != NULL;
51
    }
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

    enum InvokeResult
    {
        INVOKERESULT_NO_ERROR       = 0,    /* returns no error */
        INVOKERESULT_GENERIC_ERROR  = 1,    /* returns error */
        INVOKERESULT_NO_SUCH_METHOD = 2,    /* throws method does not exist */
        INVOKERESULT_INVALID_ARGS   = 3,    /* throws invalid arguments */
        INVOKERESULT_INVALID_VALUE  = 4,    /* throws invalid value in assignment */
        INVOKERESULT_OUT_OF_MEMORY  = 5,    /* throws out of memory */
    };

    virtual InvokeResult getProperty(int index, NPVariant &result);
    virtual InvokeResult setProperty(int index, const NPVariant &value);
    virtual InvokeResult removeProperty(int index);
    virtual InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result);
    virtual InvokeResult invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant &result);

    bool returnInvokeResult(InvokeResult result);

    static InvokeResult invokeResultString(const char *,NPVariant &);

73
protected:
74 75
    void *operator new(size_t n)
    {
76 77 78 79
        /*
        ** Assume that browser has a smarter memory allocator
        ** than plain old malloc() and use it instead.
        */
80 81 82 83 84
        return NPN_MemAlloc(n);
    };

    void operator delete(void *p)
    {
85 86 87
        NPN_MemFree(p);
    };

88 89 90 91
    RuntimeNPObject(NPP instance, const NPClass *aClass) :
        _instance(instance)
    {
        _class = const_cast<NPClass *>(aClass);
92
        referenceCount = 1;
93
    };
94
    virtual ~RuntimeNPObject() = default;
95

96 97
    bool isPluginRunning()
    {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
98
        return (_instance->pdata != NULL);
99 100 101 102 103 104
    }
    template<class T> T *getPrivate()
    {
        return reinterpret_cast<T *>(_instance->pdata);
    }

105
    NPP _instance;
106 107 108

    template <typename>
    friend class RuntimeNPClass;
109 110
};

111 112
template<class T>
class RuntimeNPClass : public NPClass
113 114
{
public:
115 116 117 118 119 120 121
    static NPClass *getClass()
    {
        static NPClass *singleton = new RuntimeNPClass<T>;
        return singleton;
    }

protected:
122 123 124
    RuntimeNPClass();
    virtual ~RuntimeNPClass();

125 126 127 128 129
    static NPObject *Allocate(NPP instance, NPClass *aClass)
    {
        const RuntimeNPClass<T> *vClass = static_cast<RuntimeNPClass<T> *>(aClass);
        return new T(instance, vClass);
    }
130

131 132 133 134 135
    static void Deallocate(NPObject *npobj)
    {
        RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
        delete vObj;
    }
136

137 138 139 140 141
    static void Invalidate(NPObject *npobj)
    {
        RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
        vObj->_instance = NULL;
    }
142

143 144 145 146 147
    static bool HasMethod(NPObject *npobj, NPIdentifier name)
    {
        const RuntimeNPClass* vClass = static_cast<RuntimeNPClass*>(npobj->_class);
        return vClass->indexOfMethod(name) != -1;
    }
148

149 150 151 152 153
    static bool HasProperty(NPObject *npobj, NPIdentifier name)
    {
        const RuntimeNPClass* vClass = static_cast<RuntimeNPClass*>(npobj->_class);
        return vClass->indexOfProperty(name) != -1;
    }
154

155
    static bool GetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
156
    {
157 158
        RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
        if( vObj->isValid() )
159
        {
160 161 162 163 164 165
            const RuntimeNPClass* vClass = static_cast<RuntimeNPClass*>(npobj->_class);
            int index = vClass->indexOfProperty(name);
            if( index != -1 )
            {
                return vObj->returnInvokeResult(vObj->getProperty(index, *result));
            }
166
        }
167
        return false;
168 169
    }

170
    static bool SetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
171
    {
172 173
        RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
        if( vObj->isValid() )
174
        {
175 176 177 178 179 180
            const RuntimeNPClass* vClass = static_cast<RuntimeNPClass*>(npobj->_class);
            int index = vClass->indexOfProperty(name);
            if( index != -1 )
            {
                return vObj->returnInvokeResult(vObj->setProperty(index, *value));
            }
181
        }
182
        return false;
183 184
    }

185
    static bool RemoveProperty(NPObject *npobj, NPIdentifier name)
186
    {
187 188
        RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
        if( vObj->isValid() )
189
        {
190 191 192 193 194 195
            const RuntimeNPClass* vClass = static_cast<RuntimeNPClass*>(npobj->_class);
            int index = vClass->indexOfProperty(name);
            if( index != -1 )
            {
                return vObj->returnInvokeResult(vObj->removeProperty(index));
            }
196
        }
197
        return false;
198 199
    }

200 201 202
    static bool ClassInvoke(NPObject *npobj, NPIdentifier name,
                                        const NPVariant *args, uint32_t argCount,
                                        NPVariant *result)
203
    {
204 205
        RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
        if( vObj->isValid() )
206
        {
207 208 209 210 211
            const RuntimeNPClass* vClass = static_cast<RuntimeNPClass*>(npobj->_class);
            int index = vClass->indexOfMethod(name);
            if( index != -1 )
            {
                return vObj->returnInvokeResult(vObj->invoke(index, args, argCount, *result));
212

213
            }
214
        }
215
        return false;
216 217
    }

218 219 220 221
    static bool InvokeDefault(NPObject *npobj,
                                               const NPVariant *args,
                                               uint32_t argCount,
                                               NPVariant *result)
222
    {
223 224 225 226 227 228
        RuntimeNPObject *vObj = static_cast<RuntimeNPObject *>(npobj);
        if( vObj->isValid() )
        {
            return vObj->returnInvokeResult(vObj->invokeDefault(args, argCount, *result));
        }
        return false;
229
    }
230 231 232 233 234 235 236 237 238 239 240 241 242 243

    int indexOfMethod(NPIdentifier name) const;
    int indexOfProperty(NPIdentifier name) const;

private:
    NPIdentifier *propertyIdentifiers;
    NPIdentifier *methodIdentifiers;
};

template<class T>
inline void RuntimeNPObject::InstantObj( NPObject *&obj )
{
    if( !obj )
        obj = NPN_CreateObject(_instance, RuntimeNPClass<T>::getClass());
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
}

template<class T>
RuntimeNPClass<T>::RuntimeNPClass()
{
    // retreive property identifiers from names
    if( T::propertyCount > 0 )
    {
        propertyIdentifiers = new NPIdentifier[T::propertyCount];
        if( propertyIdentifiers )
            NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::propertyNames),
                T::propertyCount, propertyIdentifiers);
    }

    // retreive method identifiers from names
    if( T::methodCount > 0 )
    {
        methodIdentifiers = new NPIdentifier[T::methodCount];
        if( methodIdentifiers )
            NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(T::methodNames),
                T::methodCount, methodIdentifiers);
    }

    // fill in NPClass structure
    structVersion  = NP_CLASS_STRUCT_VERSION;
269 270 271 272 273 274 275 276 277 278
    allocate       = &Allocate;
    deallocate     = &Deallocate;
    invalidate     = &Invalidate;
    hasMethod      = &HasMethod;
    invoke         = &ClassInvoke;
    invokeDefault  = &InvokeDefault;
    hasProperty    = &HasProperty;
    getProperty    = &GetProperty;
    setProperty    = &SetProperty;
    removeProperty = &RemoveProperty;
279 280
    enumerate      = 0;
    construct      = 0;
281 282 283 284 285
}

template<class T>
RuntimeNPClass<T>::~RuntimeNPClass()
{
286 287
    delete[] propertyIdentifiers;
    delete[] methodIdentifiers;
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
}

template<class T>
int RuntimeNPClass<T>::indexOfMethod(NPIdentifier name) const
{
    if( methodIdentifiers )
    {
        for(int c=0; c< T::methodCount; ++c )
        {
            if( name == methodIdentifiers[c] )
                return c;
        }
    }
    return -1;
}

template<class T>
int RuntimeNPClass<T>::indexOfProperty(NPIdentifier name) const
{
    if( propertyIdentifiers )
    {
        for(int c=0; c< T::propertyCount; ++c )
        {
            if( name == propertyIdentifiers[c] )
                return c;
        }
    }
    return -1;
}

#endif