| /* |
| * Copyright (C) 2010 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef PluginTest_h |
| #define PluginTest_h |
| |
| #include <WebKit/npfunctions.h> |
| #include <assert.h> |
| #include <map> |
| #include <string> |
| #include <wtf/Assertions.h> |
| |
| // Helper classes for implementing has_member |
| typedef char (&no_tag)[1]; |
| typedef char (&yes_tag)[2]; |
| |
| #define DEFINE_HAS_MEMBER_CHECK(member, returnType, argumentTypes) \ |
| template<typename T, returnType (T::*member) argumentTypes> struct pmf_##member##_helper {}; \ |
| template<typename T> no_tag has_member_##member##_helper(...); \ |
| template<typename T> yes_tag has_member_##member##_helper(pmf_##member##_helper<T, &T::member >*); \ |
| template<typename T> struct has_member_##member { \ |
| static const bool value = sizeof(has_member_##member##_helper<T>(0)) == sizeof(yes_tag); \ |
| }; |
| |
| DEFINE_HAS_MEMBER_CHECK(hasMethod, bool, (NPIdentifier methodName)); |
| DEFINE_HAS_MEMBER_CHECK(invoke, bool, (NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result)); |
| DEFINE_HAS_MEMBER_CHECK(invokeDefault, bool, (const NPVariant*, uint32_t, NPVariant* result)); |
| DEFINE_HAS_MEMBER_CHECK(hasProperty, bool, (NPIdentifier propertyName)); |
| DEFINE_HAS_MEMBER_CHECK(getProperty, bool, (NPIdentifier propertyName, NPVariant* result)); |
| DEFINE_HAS_MEMBER_CHECK(removeProperty, bool, (NPIdentifier propertyName)); |
| |
| class PluginTest { |
| public: |
| static PluginTest* create(NPP, const std::string& identifier); |
| virtual ~PluginTest(); |
| |
| static void NP_Shutdown(); |
| |
| // NPP functions. |
| virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved); |
| virtual NPError NPP_Destroy(NPSavedData**); |
| virtual NPError NPP_SetWindow(NPWindow*); |
| virtual NPError NPP_NewStream(NPMIMEType, NPStream*, NPBool seekable, uint16_t* stype); |
| virtual NPError NPP_DestroyStream(NPStream*, NPReason); |
| virtual int32_t NPP_WriteReady(NPStream*); |
| virtual int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer); |
| |
| virtual int16_t NPP_HandleEvent(void* event); |
| virtual bool NPP_URLNotify(const char* url, NPReason, void* notifyData); |
| virtual void NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData); |
| virtual NPError NPP_GetValue(NPPVariable, void* value); |
| virtual NPError NPP_SetValue(NPNVariable, void *value); |
| |
| // NPN functions. |
| NPError NPN_GetURL(const char* url, const char* target); |
| NPError NPN_GetURLNotify(const char* url, const char* target, void* notifyData); |
| NPError NPN_PostURLNotify(const char *url, const char *target, uint32_t len, const char* buf, NPBool file, void *notifyData); |
| NPError NPN_GetValue(NPNVariable, void* value); |
| void NPN_InvalidateRect(NPRect* invalidRect); |
| bool NPN_Invoke(NPObject *, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result); |
| void* NPN_MemAlloc(uint32_t size); |
| |
| // NPRuntime NPN functions. |
| NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name); |
| NPIdentifier NPN_GetIntIdentifier(int32_t intid); |
| bool NPN_IdentifierIsString(NPIdentifier); |
| NPUTF8* NPN_UTF8FromIdentifier(NPIdentifier); |
| int32_t NPN_IntFromIdentifier(NPIdentifier); |
| |
| NPObject* NPN_CreateObject(NPClass*); |
| NPObject* NPN_RetainObject(NPObject*); |
| void NPN_ReleaseObject(NPObject*); |
| bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName); |
| void NPN_ReleaseVariantValue(NPVariant*); |
| void NPN_URLRedirectResponse(void* notifyData, NPBool allow); |
| |
| #ifdef XP_MACOSX |
| bool NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); |
| #endif |
| |
| bool executeScript(const NPString*, NPVariant* result); |
| void executeScript(const char*); |
| void log(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3); |
| |
| void registerNPShutdownFunction(void (*)()); |
| |
| static void indicateTestFailure(); |
| |
| template<typename TestClassTy> class Register { |
| public: |
| Register(const std::string& identifier) |
| { |
| registerCreateTestFunction(identifier, Register::create); |
| } |
| |
| private: |
| static PluginTest* create(NPP npp, const std::string& identifier) |
| { |
| return new TestClassTy(npp, identifier); |
| } |
| }; |
| |
| protected: |
| PluginTest(NPP npp, const std::string& identifier); |
| |
| // FIXME: A plug-in test shouldn't need to know about it's NPP. Make this private. |
| NPP m_npp; |
| |
| const std::string& identifier() const { return m_identifier; } |
| |
| static NPNetscapeFuncs* netscapeFuncs(); |
| |
| void waitUntilDone(); |
| void notifyDone(); |
| |
| // NPObject helper template. |
| template<typename T> struct Object : NPObject { |
| public: |
| static NPObject* create(PluginTest* pluginTest) |
| { |
| Object* object = static_cast<Object*>(pluginTest->NPN_CreateObject(npClass())); |
| |
| object->m_pluginTest = pluginTest; |
| return object; |
| } |
| |
| // These should never be called. |
| bool hasMethod(NPIdentifier methodName) |
| { |
| assert(false); |
| return false; |
| } |
| |
| bool invoke(NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result) |
| { |
| assert(false); |
| return false; |
| } |
| |
| bool invokeDefault(const NPVariant*, uint32_t, NPVariant* result) |
| { |
| assert(false); |
| return false; |
| } |
| |
| bool hasProperty(NPIdentifier propertyName) |
| { |
| assert(false); |
| return false; |
| } |
| |
| bool getProperty(NPIdentifier propertyName, NPVariant* result) |
| { |
| assert(false); |
| return false; |
| } |
| |
| bool removeProperty(NPIdentifier propertyName) |
| { |
| assert(false); |
| return false; |
| } |
| |
| // Helper functions. |
| bool identifierIs(NPIdentifier identifier, const char* value) |
| { |
| return pluginTest()->NPN_GetStringIdentifier(value) == identifier; |
| } |
| |
| protected: |
| Object() |
| : m_pluginTest(0) |
| { |
| } |
| |
| virtual ~Object() |
| { |
| } |
| |
| PluginTest* pluginTest() const { return m_pluginTest; } |
| |
| private: |
| static NPObject* NP_Allocate(NPP npp, NPClass* aClass) |
| { |
| return new T; |
| } |
| |
| static void NP_Deallocate(NPObject* npObject) |
| { |
| delete static_cast<T*>(npObject); |
| } |
| |
| static bool NP_HasMethod(NPObject* npObject, NPIdentifier methodName) |
| { |
| return static_cast<T*>(npObject)->hasMethod(methodName); |
| } |
| |
| static bool NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) |
| { |
| return static_cast<T*>(npObject)->invoke(methodName, arguments, argumentCount, result); |
| } |
| |
| static bool NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) |
| { |
| return static_cast<T*>(npObject)->invokeDefault(arguments, argumentCount, result); |
| } |
| |
| static bool NP_HasProperty(NPObject* npObject, NPIdentifier propertyName) |
| { |
| return static_cast<T*>(npObject)->hasProperty(propertyName); |
| } |
| |
| static bool NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result) |
| { |
| return static_cast<T*>(npObject)->getProperty(propertyName, result); |
| } |
| |
| static bool NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName) |
| { |
| return static_cast<T*>(npObject)->removeProperty(propertyName); |
| } |
| |
| static NPClass* npClass() |
| { |
| static NPClass npClass = { |
| NP_CLASS_STRUCT_VERSION, |
| NP_Allocate, |
| NP_Deallocate, |
| 0, // NPClass::invalidate |
| has_member_hasMethod<T>::value ? NP_HasMethod : 0, |
| has_member_invoke<T>::value ? NP_Invoke : 0, |
| has_member_invokeDefault<T>::value ? NP_InvokeDefault : 0, |
| has_member_hasProperty<T>::value ? NP_HasProperty : 0, |
| has_member_getProperty<T>::value ? NP_GetProperty : 0, |
| 0, // NPClass::setProperty |
| has_member_removeProperty<T>::value ? NP_RemoveProperty : 0, |
| 0, // NPClass::enumerate |
| 0 // NPClass::construct |
| }; |
| |
| return &npClass; |
| }; |
| |
| PluginTest* m_pluginTest; |
| }; |
| |
| private: |
| typedef PluginTest* (*CreateTestFunction)(NPP, const std::string&); |
| |
| static void registerCreateTestFunction(const std::string&, CreateTestFunction); |
| static std::map<std::string, CreateTestFunction>& createTestFunctions(); |
| |
| std::string m_identifier; |
| }; |
| |
| #endif // PluginTest_h |