webengine/osswebengine/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.c
changeset 0 dd21522fd290
child 36 0ed94ceaa377
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
       
     3  consideration of your agreement to the following terms, and your use, installation, 
       
     4  modification or redistribution of this Apple software constitutes acceptance of these 
       
     5  terms.  If you do not agree with these terms, please do not use, install, modify or 
       
     6  redistribute this Apple software.
       
     7  
       
     8  In consideration of your agreement to abide by the following terms, and subject to these 
       
     9  terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in 
       
    10  this original Apple software (the "Apple Software"), to use, reproduce, modify and 
       
    11  redistribute the Apple Software, with or without modifications, in source and/or binary 
       
    12  forms; provided that if you redistribute the Apple Software in its entirety and without 
       
    13  modifications, you must retain this notice and the following text and disclaimers in all 
       
    14  such redistributions of the Apple Software.  Neither the name, trademarks, service marks 
       
    15  or logos of Apple Computer, Inc. may be used to endorse or promote products derived from 
       
    16  the Apple Software without specific prior written permission from Apple. Except as expressly
       
    17  stated in this notice, no other rights or licenses, express or implied, are granted by Apple
       
    18  herein, including but not limited to any patent rights that may be infringed by your 
       
    19  derivative works or by other works in which the Apple Software may be incorporated.
       
    20  
       
    21  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO WARRANTIES, 
       
    22  EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, 
       
    23  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS 
       
    24  USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
       
    25  
       
    26  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL 
       
    27  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
       
    28  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, 
       
    29  REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND 
       
    30  WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR 
       
    31  OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    32  */
       
    33 
       
    34 #include "PluginObject.h"
       
    35 
       
    36 #include "TestObject.h"
       
    37 #include <assert.h>
       
    38 #include <stdio.h>
       
    39 
       
    40 static void pluginInvalidate(NPObject *obj);
       
    41 static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
       
    42 static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
       
    43 static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
       
    44 static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
       
    45 static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
       
    46 static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
       
    47 static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
       
    48 static void pluginDeallocate(NPObject *obj);
       
    49 
       
    50 NPNetscapeFuncs *browser;
       
    51 
       
    52 static NPClass pluginClass = { 
       
    53     NP_CLASS_STRUCT_VERSION,
       
    54     pluginAllocate, 
       
    55     pluginDeallocate, 
       
    56     pluginInvalidate,
       
    57     pluginHasMethod,
       
    58     pluginInvoke,
       
    59     pluginInvokeDefault,
       
    60     pluginHasProperty,
       
    61     pluginGetProperty,
       
    62     pluginSetProperty,
       
    63 };
       
    64  
       
    65 NPClass *getPluginClass(void)
       
    66 {
       
    67     return &pluginClass;
       
    68 }
       
    69 
       
    70 static bool identifiersInitialized = false;
       
    71 
       
    72 #define ID_PROPERTY_PROPERTY        0
       
    73 #define ID_PROPERTY_EVENT_LOGGING   1
       
    74 #define ID_PROPERTY_HAS_STREAM      2
       
    75 #define ID_PROPERTY_TEST_OBJECT     3
       
    76 #define ID_PROPERTY_LOG_DESTROY     4
       
    77 #define NUM_PROPERTY_IDENTIFIERS    5
       
    78 
       
    79 static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
       
    80 static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
       
    81     "property",
       
    82     "eventLoggingEnabled",
       
    83     "hasStream",
       
    84     "testObject",
       
    85     "logDestroy",
       
    86 };
       
    87 
       
    88 #define ID_TEST_CALLBACK_METHOD     0
       
    89 #define ID_TEST_GETURL              1
       
    90 #define ID_REMOVE_DEFAULT_METHOD    2
       
    91 #define ID_TEST_DOM_ACCESS          3
       
    92 #define ID_TEST_GET_URL_NOTIFY      4
       
    93 #define ID_TEST_INVOKE_DEFAULT      5
       
    94 #define ID_DESTROY_STREAM           6
       
    95 #define ID_TEST_ENUMERATE           7
       
    96 #define NUM_METHOD_IDENTIFIERS      8
       
    97 
       
    98 static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
       
    99 static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
       
   100     "testCallback",
       
   101     "getURL",
       
   102     "removeDefaultMethod",
       
   103     "testDOMAccess",
       
   104     "getURLNotify",
       
   105     "testInvokeDefault",
       
   106     "destroyStream",
       
   107     "testEnumerate"
       
   108 };
       
   109 
       
   110 static NPUTF8* createCStringFromNPVariant(const NPVariant *variant)
       
   111 {
       
   112     size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
       
   113     NPUTF8* result = (NPUTF8*)malloc(length + 1);
       
   114     memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
       
   115     result[length] = '\0';
       
   116     return result;
       
   117 }
       
   118 
       
   119 static void initializeIdentifiers(void)
       
   120 {
       
   121     browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
       
   122     browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
       
   123 }
       
   124 
       
   125 static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
       
   126 {
       
   127     for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
       
   128         if (name == pluginPropertyIdentifiers[i])
       
   129             return true;
       
   130     return false;
       
   131 }
       
   132 
       
   133 static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
       
   134 {
       
   135     for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
       
   136         if (name == pluginMethodIdentifiers[i])
       
   137             return true;
       
   138     return false;
       
   139 }
       
   140 
       
   141 static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
       
   142 {
       
   143     if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
       
   144         STRINGZ_TO_NPVARIANT("property", *variant);
       
   145         return true;
       
   146     } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
       
   147         BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->eventLogging, *variant);
       
   148         return true;
       
   149     } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
       
   150         BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->logDestroy, *variant);
       
   151         return true;            
       
   152     } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
       
   153         BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->stream != 0, *variant);
       
   154         return true;
       
   155     } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
       
   156         NPObject *testObject = ((PluginObject *)obj)->testObject;
       
   157         browser->retainobject(testObject);
       
   158         OBJECT_TO_NPVARIANT(testObject, *variant);
       
   159         return true;
       
   160     }
       
   161     return false;
       
   162 }
       
   163 
       
   164 static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
       
   165 {
       
   166     if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
       
   167         ((PluginObject *)obj)->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
       
   168         return true;
       
   169     } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
       
   170         ((PluginObject *)obj)->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
       
   171         return true;
       
   172     }
       
   173     
       
   174     return false;
       
   175 }
       
   176 
       
   177 static void testDOMAccess(PluginObject *obj)
       
   178 {
       
   179     // Get plug-in's DOM element
       
   180     NPObject *elementObject;
       
   181     if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) == NPERR_NO_ERROR) {
       
   182         // Get style
       
   183         NPVariant styleVariant;
       
   184         NPIdentifier styleIdentifier = browser->getstringidentifier("style");
       
   185         if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styleVariant) && NPVARIANT_IS_OBJECT(styleVariant)) {
       
   186             // Set style.border
       
   187             NPIdentifier borderIdentifier = browser->getstringidentifier("border");
       
   188             NPVariant borderVariant;
       
   189             STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
       
   190             browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), borderIdentifier, &borderVariant);
       
   191             browser->releasevariantvalue(&styleVariant);
       
   192         }
       
   193         
       
   194         browser->releaseobject(elementObject);
       
   195     }
       
   196 }
       
   197 
       
   198 static bool pluginInvoke(NPObject *header, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
       
   199 {
       
   200     PluginObject *obj = (PluginObject *)header;
       
   201     if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) {
       
   202         // call whatever method name we're given
       
   203         if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) {
       
   204             NPObject *windowScriptObject;
       
   205             browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
       
   206 
       
   207             NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
       
   208             NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
       
   209             free(callbackString);
       
   210 
       
   211             NPVariant browserResult;
       
   212             browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult);
       
   213             browser->releasevariantvalue(&browserResult);
       
   214 
       
   215             VOID_TO_NPVARIANT(*result);
       
   216             return true;
       
   217         }
       
   218     } else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) {
       
   219         if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) {
       
   220             NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
       
   221             NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
       
   222             browser->geturl(obj->npp, urlString, targetString);
       
   223             free(urlString);
       
   224             free(targetString);
       
   225 
       
   226             VOID_TO_NPVARIANT(*result);
       
   227             return true;
       
   228         } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
       
   229             NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
       
   230             browser->geturl(obj->npp, urlString, 0);
       
   231             free(urlString);
       
   232 
       
   233             VOID_TO_NPVARIANT(*result);
       
   234             return true;
       
   235         }
       
   236     } else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD]) {
       
   237         pluginClass.invokeDefault = 0;
       
   238         VOID_TO_NPVARIANT(*result);
       
   239         return true;
       
   240     } else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) {
       
   241         testDOMAccess(obj);
       
   242         VOID_TO_NPVARIANT(*result);
       
   243         return true;
       
   244     } else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) {
       
   245         if (argCount == 3
       
   246           && NPVARIANT_IS_STRING(args[0])
       
   247           && (NPVARIANT_IS_STRING(args[1]) || NPVARIANT_IS_NULL(args[1]))
       
   248           && NPVARIANT_IS_STRING(args[2])) {
       
   249             NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
       
   250             NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL);
       
   251             NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
       
   252             
       
   253             NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
       
   254             browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
       
   255 
       
   256             free(urlString);
       
   257             free(targetString);
       
   258             free(callbackString);
       
   259             
       
   260             VOID_TO_NPVARIANT(*result);
       
   261             return true;
       
   262         }
       
   263     } else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT] && NPVARIANT_IS_OBJECT(args[0])) {
       
   264         NPObject *callback = NPVARIANT_TO_OBJECT(args[0]);
       
   265         
       
   266         NPVariant args[1];
       
   267         NPVariant browserResult;
       
   268         
       
   269         STRINGZ_TO_NPVARIANT("test", args[0]);
       
   270         bool retval = browser->invokeDefault(obj->npp, callback, args, 1, &browserResult);
       
   271         
       
   272         if (retval)
       
   273             browser->releasevariantvalue(&browserResult);
       
   274         
       
   275         BOOLEAN_TO_NPVARIANT(retval, *result);
       
   276         return true;
       
   277     } else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) {
       
   278         if (argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_OBJECT(args[1])) {
       
   279             uint32_t count;            
       
   280             NPIdentifier* identifiers;
       
   281 
       
   282             if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
       
   283                 NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
       
   284                 NPIdentifier pushIdentifier = browser->getstringidentifier("push");
       
   285                 
       
   286                 for (uint32_t i = 0; i < count; i++) {
       
   287                     NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);
       
   288                     
       
   289                     if (!string)
       
   290                         continue;
       
   291                                         
       
   292                     NPVariant args[1];
       
   293                     STRINGZ_TO_NPVARIANT(string, args[0]);
       
   294                     NPVariant browserResult;
       
   295                     browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &browserResult);
       
   296                     browser->releasevariantvalue(&browserResult);
       
   297                     browser->memfree(string);
       
   298                 }
       
   299                 
       
   300                 browser->memfree(identifiers);
       
   301             }
       
   302             
       
   303             VOID_TO_NPVARIANT(*result);
       
   304             return true;            
       
   305         }
       
   306     } else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) {
       
   307         NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
       
   308         INT32_TO_NPVARIANT(npError, *result);
       
   309         return true;        
       
   310     } 
       
   311     return false;
       
   312 }
       
   313 
       
   314 static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
       
   315 {
       
   316     INT32_TO_NPVARIANT(1, *result);
       
   317     return true;
       
   318 }
       
   319 
       
   320 static void pluginInvalidate(NPObject *obj)
       
   321 {
       
   322 }
       
   323 
       
   324 static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
       
   325 {
       
   326     PluginObject *newInstance = (PluginObject*)malloc(sizeof(PluginObject));
       
   327     
       
   328     if (!identifiersInitialized) {
       
   329         identifiersInitialized = true;
       
   330         initializeIdentifiers();
       
   331     }
       
   332 
       
   333     newInstance->npp = npp;
       
   334     newInstance->testObject = browser->createobject(npp, getTestClass());
       
   335     newInstance->eventLogging = FALSE;
       
   336     newInstance->logDestroy = FALSE;
       
   337     newInstance->logSetWindow = FALSE;
       
   338     newInstance->returnErrorFromNewStream = FALSE;
       
   339     newInstance->stream = 0;
       
   340     
       
   341     newInstance->firstUrl = NULL;
       
   342     newInstance->firstHeaders = NULL;
       
   343     newInstance->lastUrl = NULL;
       
   344     newInstance->lastHeaders = NULL;
       
   345     
       
   346     return (NPObject *)newInstance;
       
   347 }
       
   348 
       
   349 static void pluginDeallocate(NPObject *header) 
       
   350 {
       
   351     PluginObject* obj = (PluginObject*)header;
       
   352     
       
   353     browser->releaseobject(obj->testObject);
       
   354 
       
   355     free(obj->firstUrl);
       
   356     free(obj->firstHeaders);
       
   357     free(obj->lastUrl);
       
   358     free(obj->lastHeaders);
       
   359 
       
   360     free(obj);
       
   361 }
       
   362 
       
   363 void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
       
   364 {
       
   365     assert(object);
       
   366     
       
   367     NPVariant args[2];
       
   368     
       
   369     NPObject *windowScriptObject;
       
   370     browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
       
   371     
       
   372     NPIdentifier callbackIdentifier = notifyData;
       
   373 
       
   374     INT32_TO_NPVARIANT(reason, args[0]);
       
   375 
       
   376     char *strHdr = NULL;
       
   377     if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
       
   378         // Format expected by JavaScript validator: four fields separated by \n\n:
       
   379         // First URL; first header block; last URL; last header block.
       
   380         // Note that header blocks already end with \n due to how NPStream::headers works.
       
   381         int len = strlen(object->firstUrl) + 2
       
   382             + strlen(object->firstHeaders) + 1
       
   383             + strlen(object->lastUrl) + 2
       
   384             + strlen(object->lastHeaders) + 1;
       
   385         strHdr = (char*)malloc(len + 1);
       
   386         snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n",
       
   387                  object->firstUrl, object->firstHeaders, object->lastUrl, object->lastHeaders);
       
   388         STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
       
   389     } else
       
   390         NULL_TO_NPVARIANT(args[1]);
       
   391 
       
   392     NPVariant browserResult;
       
   393     browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2, &browserResult);
       
   394     browser->releasevariantvalue(&browserResult);
       
   395 
       
   396     free(strHdr);
       
   397 }
       
   398 
       
   399 void notifyStream(PluginObject* object, const char *url, const char *headers)
       
   400 {
       
   401     if (object->firstUrl == NULL) {
       
   402         if (url)
       
   403             object->firstUrl = strdup(url);
       
   404         if (headers)
       
   405             object->firstHeaders = strdup(headers);
       
   406     } else {
       
   407         free(object->lastUrl);
       
   408         free(object->lastHeaders);
       
   409         object->lastUrl = (url ? strdup(url) : NULL);
       
   410         object->lastHeaders = (headers ? strdup(headers) : NULL);
       
   411     }
       
   412 }