/* * 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 #include #include #include #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf #endif // 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 struct pmf_##member##_helper {}; \ template no_tag has_member_##member##_helper(...); \ template yes_tag has_member_##member##_helper(pmf_##member##_helper*); \ template struct has_member_##member { \ static const bool value = sizeof(has_member_##member##_helper(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, ...); void registerNPShutdownFunction(void (*)()); static void indicateTestFailure(); template 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 struct Object : NPObject { public: static NPObject* create(PluginTest* pluginTest) { Object* object = static_cast(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(npObject); } static bool NP_HasMethod(NPObject* npObject, NPIdentifier methodName) { return static_cast(npObject)->hasMethod(methodName); } static bool NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { return static_cast(npObject)->invoke(methodName, arguments, argumentCount, result); } static bool NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { return static_cast(npObject)->invokeDefault(arguments, argumentCount, result); } static bool NP_HasProperty(NPObject* npObject, NPIdentifier propertyName) { return static_cast(npObject)->hasProperty(propertyName); } static bool NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result) { return static_cast(npObject)->getProperty(propertyName, result); } static bool NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName) { return static_cast(npObject)->removeProperty(propertyName); } static NPClass* npClass() { static NPClass npClass = { NP_CLASS_STRUCT_VERSION, NP_Allocate, NP_Deallocate, 0, // NPClass::invalidate has_member_hasMethod::value ? NP_HasMethod : 0, has_member_invoke::value ? NP_Invoke : 0, has_member_invokeDefault::value ? NP_InvokeDefault : 0, has_member_hasProperty::value ? NP_HasProperty : 0, has_member_getProperty::value ? NP_GetProperty : 0, 0, // NPClass::setProperty has_member_removeProperty::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& createTestFunctions(); std::string m_identifier; }; #endif // PluginTest_h