2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Holger Hans Peter Freyther
4 * Copyright (C) 2010 Collabora Ltd.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "PluginObject.h"
30 #include "PluginTest.h"
31 #include "TestObject.h"
37 // Helper function which takes in the plugin window object for logging to the console object.
38 static void pluginLogWithWindowObject(NPObject* windowObject, NPP instance, const char* message)
40 NPVariant consoleVariant;
41 if (!browser->getproperty(instance, windowObject, browser->getstringidentifier("console"), &consoleVariant)) {
42 fprintf(stderr, "Failed to retrieve console object while logging: %s\n", message);
46 NPObject* consoleObject = NPVARIANT_TO_OBJECT(consoleVariant);
48 NPVariant messageVariant;
49 STRINGZ_TO_NPVARIANT(message, messageVariant);
52 if (!browser->invoke(instance, consoleObject, browser->getstringidentifier("log"), &messageVariant, 1, &result)) {
53 fprintf(stderr, "Failed to invoke console.log while logging: %s\n", message);
54 browser->releaseobject(consoleObject);
58 browser->releasevariantvalue(&result);
59 browser->releaseobject(consoleObject);
62 void pluginLogWithArguments(NPP instance, const char* format, va_list args)
64 const size_t messageBufferSize = 2048;
65 char message[messageBufferSize] = "PLUGIN: ";
66 int messageLength = sizeof("PLUGIN: ") - 1;
67 messageLength += vsnprintf(message + messageLength, messageBufferSize - 1 - messageLength, format, args);
68 message[messageLength] = '\0';
70 NPObject* windowObject = 0;
71 NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
72 if (error != NPERR_NO_ERROR) {
73 fprintf(stderr, "Failed to retrieve window object while logging: %s\n", message);
77 pluginLogWithWindowObject(windowObject, instance, message);
78 browser->releaseobject(windowObject);
81 // Helper function to log to the console object.
82 void pluginLog(NPP instance, const char* format, ...)
85 va_start(args, format);
86 pluginLogWithArguments(instance, format, args);
90 static void pluginInvalidate(NPObject*);
91 static bool pluginHasProperty(NPObject*, NPIdentifier name);
92 static bool pluginHasMethod(NPObject*, NPIdentifier name);
93 static bool pluginGetProperty(NPObject*, NPIdentifier name, NPVariant*);
94 static bool pluginSetProperty(NPObject*, NPIdentifier name, const NPVariant*);
95 static bool pluginInvoke(NPObject*, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result);
96 static NPObject* pluginAllocate(NPP npp, NPClass*);
97 static void pluginDeallocate(NPObject*);
99 NPNetscapeFuncs* browser;
100 NPPluginFuncs* pluginFunctions;
102 static NPClass pluginClass_ = {
103 NP_CLASS_STRUCT_VERSION,
109 0, // NPClass::invokeDefault,
113 0, // NPClass::removeProperty
114 0, // NPClass::enumerate
115 0, // NPClass::construct
118 NPClass* createPluginClass(void)
120 NPClass* pluginClass = new NPClass;
121 *pluginClass = pluginClass_;
125 static bool identifiersInitialized = false;
128 ID_PROPERTY_PROPERTY = 0,
129 ID_PROPERTY_EVENT_LOGGING,
130 ID_PROPERTY_HAS_STREAM,
131 ID_PROPERTY_TEST_OBJECT,
132 ID_PROPERTY_LOG_DESTROY,
133 ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM,
134 ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE,
135 ID_PROPERTY_THROW_EXCEPTION_PROPERTY,
136 ID_LAST_SET_WINDOW_ARGUMENTS,
137 ID_PROPERTY_WINDOWED_PLUGIN,
138 ID_PROPERTY_TEST_OBJECT_COUNT,
139 ID_PROPERTY_DELETE_IN_GET_PROPERTY,
140 ID_PROPERTY_DELETE_IN_HAS_PROPERTY_RETURN_TRUE,
141 ID_PROPERTY_DELETE_IN_SET_PROPERTY,
142 NUM_PROPERTY_IDENTIFIERS
145 static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
146 static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
148 "eventLoggingEnabled",
152 "returnErrorFromNewStream",
153 "returnNegativeOneFromWrite",
154 "testThrowExceptionProperty",
155 "lastSetWindowArguments",
158 "deletePluginInGetProperty",
159 "deletePluginInHasPropertyReturnTrue",
160 "deletePluginInSetProperty"
164 ID_TEST_CALLBACK_METHOD = 0,
165 ID_TEST_CALLBACK_METHOD_RETURN,
168 ID_TEST_GET_URL_NOTIFY,
169 ID_TEST_INVOKE_DEFAULT,
172 ID_TEST_GETINTIDENTIFIER,
173 ID_TEST_GET_PROPERTY,
174 ID_TEST_HAS_PROPERTY,
177 ID_TEST_GET_PROPERTY_RETURN_VALUE,
178 ID_TEST_IDENTIFIER_TO_STRING,
179 ID_TEST_IDENTIFIER_TO_INT,
180 ID_TEST_PASS_TEST_OBJECT,
181 ID_TEST_POSTURL_FILE,
183 ID_TEST_THROW_EXCEPTION_METHOD,
185 ID_TEST_CLONE_OBJECT,
186 ID_TEST_SCRIPT_OBJECT_INVOKE,
187 ID_TEST_CREATE_TEST_OBJECT,
188 ID_DESTROY_NULL_STREAM,
189 ID_TEST_RELOAD_PLUGINS_NO_PAGES,
190 ID_TEST_RELOAD_PLUGINS_AND_PAGES,
191 ID_TEST_GET_BROWSER_PROPERTY,
192 ID_TEST_SET_BROWSER_PROPERTY,
194 ID_GET_REMEMBERED_OBJECT,
195 ID_GET_AND_FORGET_REMEMBERED_OBJECT,
202 ID_TEST_DELETE_WITHIN_INVOKE,
203 NUM_METHOD_IDENTIFIERS
206 static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
207 static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
209 "testCallbackReturn",
216 "testGetIntIdentifier",
221 "testGetPropertyReturnValue",
222 "testIdentifierToString",
223 "testIdentifierToInt",
224 "testPassTestObject",
227 "testThrowException",
230 "testScriptObjectInvoke",
231 "testCreateTestObject",
233 "reloadPluginsNoPages",
234 "reloadPluginsAndPages",
235 "testGetBrowserProperty",
236 "testSetBrowserProperty",
238 "getRememberedObject",
239 "getAndForgetRememberedObject",
246 "testDeleteWithinInvoke"
249 static NPUTF8* createCStringFromNPVariant(const NPVariant* variant)
251 size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
252 NPUTF8* result = (NPUTF8*)malloc(length + 1);
253 memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
254 result[length] = '\0';
258 static void initializeIdentifiers(void)
260 browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
261 browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
264 static bool callDeletePlugin(NPObject* obj, NPIdentifier name, NPIdentifier identifierToMatch)
266 if (name != identifierToMatch)
269 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
270 NPObject* windowScriptObject;
271 browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);
273 NPIdentifier callbackIdentifier = browser->getstringidentifier("deletePlugin");
274 NPVariant browserResult;
275 if (browser->invoke(plugin->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult))
276 browser->releasevariantvalue(&browserResult);
280 static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
282 if (callDeletePlugin(obj, name, browser->getstringidentifier("deletePluginInHasPropertyReturnFalse")))
285 callDeletePlugin(obj, name, pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_HAS_PROPERTY_RETURN_TRUE]);
287 for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
288 if (name == pluginPropertyIdentifiers[i])
293 static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
295 if (callDeletePlugin(obj, name, browser->getstringidentifier("deletePluginInHasMethod")))
298 for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
299 if (name == pluginMethodIdentifiers[i])
304 static bool pluginGetProperty(NPObject* obj, NPIdentifier name, NPVariant* result)
306 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
307 if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
308 static const char* originalString = "property";
309 char* buf = static_cast<char*>(browser->memalloc(strlen(originalString) + 1));
310 strcpy(buf, originalString);
311 STRINGZ_TO_NPVARIANT(buf, *result);
314 if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
315 BOOLEAN_TO_NPVARIANT(plugin->eventLogging, *result);
318 if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
319 BOOLEAN_TO_NPVARIANT(plugin->logDestroy, *result);
322 if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
323 BOOLEAN_TO_NPVARIANT(plugin->stream, *result);
326 if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
327 NPObject* testObject = plugin->testObject;
328 browser->retainobject(testObject);
329 OBJECT_TO_NPVARIANT(testObject, *result);
332 if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
333 BOOLEAN_TO_NPVARIANT(plugin->returnErrorFromNewStream, *result);
336 if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
337 BOOLEAN_TO_NPVARIANT(plugin->returnNegativeOneFromWrite, *result);
340 if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
341 browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS");
344 if (name == pluginPropertyIdentifiers[ID_LAST_SET_WINDOW_ARGUMENTS]) {
345 char* buf = static_cast<char*>(browser->memalloc(256));
346 snprintf(buf, 256, "x: %d, y: %d, width: %u, height: %u, clipRect: (%u, %u, %u, %u)", (int)plugin->lastWindow.x, (int)plugin->lastWindow.y, (unsigned)plugin->lastWindow.width, (unsigned)plugin->lastWindow.height,
347 plugin->lastWindow.clipRect.left, plugin->lastWindow.clipRect.top, plugin->lastWindow.clipRect.right - plugin->lastWindow.clipRect.left, plugin->lastWindow.clipRect.bottom - plugin->lastWindow.clipRect.top);
349 STRINGZ_TO_NPVARIANT(buf, *result);
352 if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT_COUNT]) {
353 INT32_TO_NPVARIANT(getTestObjectCount(), *result);
357 if (name == pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_GET_PROPERTY]) {
358 browser->retainobject(obj);
359 callDeletePlugin(obj, name, pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_GET_PROPERTY]);
360 NPObject* testObject = plugin->testObject;
361 browser->retainobject(testObject);
362 OBJECT_TO_NPVARIANT(testObject, *result);
363 browser->releaseobject(obj);
370 static bool pluginSetProperty(NPObject* obj, NPIdentifier name, const NPVariant* variant)
372 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
373 if (callDeletePlugin(obj, name, pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_SET_PROPERTY]))
376 if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
377 plugin->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
380 if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
381 plugin->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
384 if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
385 plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant);
388 if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
389 plugin->returnNegativeOneFromWrite = NPVARIANT_TO_BOOLEAN(*variant);
392 if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
393 browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS");
396 if (name == pluginPropertyIdentifiers[ID_PROPERTY_WINDOWED_PLUGIN]) {
397 browser->setvalue(plugin->npp, NPPVpluginWindowBool, (void *)NPVARIANT_TO_BOOLEAN(*variant));
404 static bool testDOMAccess(PluginObject* obj, const NPVariant*, uint32_t, NPVariant* result)
406 // Get plug-in's DOM element
407 NPObject* elementObject;
408 if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) == NPERR_NO_ERROR) {
410 NPVariant styleVariant;
411 NPIdentifier styleIdentifier = browser->getstringidentifier("style");
412 if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styleVariant) && NPVARIANT_IS_OBJECT(styleVariant)) {
414 NPIdentifier borderIdentifier = browser->getstringidentifier("border");
415 NPVariant borderVariant;
416 STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
417 browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), borderIdentifier, &borderVariant);
418 browser->releasevariantvalue(&styleVariant);
421 browser->releaseobject(elementObject);
423 VOID_TO_NPVARIANT(*result);
427 static NPIdentifier stringVariantToIdentifier(NPVariant variant)
429 assert(NPVARIANT_IS_STRING(variant));
430 NPUTF8* utf8String = createCStringFromNPVariant(&variant);
431 NPIdentifier identifier = browser->getstringidentifier(utf8String);
436 static NPIdentifier int32VariantToIdentifier(NPVariant variant)
438 assert(NPVARIANT_IS_INT32(variant));
439 int32_t integer = NPVARIANT_TO_INT32(variant);
440 return browser->getintidentifier(integer);
443 static NPIdentifier doubleVariantToIdentifier(NPVariant variant)
445 assert(NPVARIANT_IS_DOUBLE(variant));
446 double value = NPVARIANT_TO_DOUBLE(variant);
447 // Sadly there is no "getdoubleidentifier"
448 int32_t integer = static_cast<int32_t>(value);
449 return browser->getintidentifier(integer);
452 static NPIdentifier variantToIdentifier(NPVariant variant)
454 if (NPVARIANT_IS_STRING(variant))
455 return stringVariantToIdentifier(variant);
456 if (NPVARIANT_IS_INT32(variant))
457 return int32VariantToIdentifier(variant);
458 if (NPVARIANT_IS_DOUBLE(variant))
459 return doubleVariantToIdentifier(variant);
463 static bool testIdentifierToString(PluginObject*, const NPVariant* args, uint32_t argCount, NPVariant* result)
467 NPIdentifier identifier = variantToIdentifier(args[0]);
470 NPUTF8* utf8String = browser->utf8fromidentifier(identifier);
473 STRINGZ_TO_NPVARIANT(utf8String, *result);
477 static bool testIdentifierToInt(PluginObject*, const NPVariant* args, uint32_t argCount, NPVariant* result)
481 NPIdentifier identifier = variantToIdentifier(args[0]);
484 int32_t integer = browser->intfromidentifier(identifier);
485 INT32_TO_NPVARIANT(integer, *result);
489 static bool testPassTestObject(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
491 if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]))
494 NPObject* windowScriptObject;
495 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
497 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
498 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
499 free(callbackString);
501 NPVariant browserResult;
502 browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, &args[1], 1, &browserResult);
503 browser->releasevariantvalue(&browserResult);
505 VOID_TO_NPVARIANT(*result);
509 static bool testCallback(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
511 if (!argCount || !NPVARIANT_IS_STRING(args[0]))
514 NPObject* windowScriptObject;
515 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
517 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
518 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
519 free(callbackString);
521 NPVariant browserResult;
522 if (browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult))
523 browser->releasevariantvalue(&browserResult);
525 browser->releaseobject(windowScriptObject);
527 VOID_TO_NPVARIANT(*result);
531 static bool testCallbackReturn(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
533 if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
536 NPObject* windowScriptObject;
537 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
539 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
540 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
541 free(callbackString);
543 NPVariant callbackArgs[1];
544 OBJECT_TO_NPVARIANT(windowScriptObject, callbackArgs[0]);
546 NPVariant browserResult;
547 browser->invoke(obj->npp, windowScriptObject, callbackIdentifier,
548 callbackArgs, 1, &browserResult);
550 if (NPVARIANT_IS_OBJECT(browserResult))
551 OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(browserResult), *result);
553 browser->releasevariantvalue(&browserResult);
554 VOID_TO_NPVARIANT(*result);
560 static bool getURL(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
562 if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) {
563 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
564 NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
565 NPError npErr = browser->geturl(obj->npp, urlString, targetString);
569 INT32_TO_NPVARIANT(npErr, *result);
572 if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
573 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
574 NPError npErr = browser->geturl(obj->npp, urlString, 0);
577 INT32_TO_NPVARIANT(npErr, *result);
583 static bool getURLNotify(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
585 if (argCount != 3 || !NPVARIANT_IS_STRING(args[0])
586 || (!NPVARIANT_IS_STRING(args[1]) && !NPVARIANT_IS_NULL(args[1]))
587 || !NPVARIANT_IS_STRING(args[2]))
590 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
591 NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : 0);
592 NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
594 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
595 browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
599 free(callbackString);
601 VOID_TO_NPVARIANT(*result);
605 static bool testInvokeDefault(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
607 if (!NPVARIANT_IS_OBJECT(args[0]))
610 NPObject* callback = NPVARIANT_TO_OBJECT(args[0]);
612 NPVariant invokeArgs[1];
613 NPVariant browserResult;
615 STRINGZ_TO_NPVARIANT("test", invokeArgs[0]);
616 bool retval = browser->invokeDefault(obj->npp, callback, invokeArgs, 1, &browserResult);
619 browser->releasevariantvalue(&browserResult);
621 BOOLEAN_TO_NPVARIANT(retval, *result);
625 static bool destroyStream(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
627 NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
628 INT32_TO_NPVARIANT(npError, *result);
632 static bool destroyNullStream(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
634 NPError npError = browser->destroystream(obj->npp, 0, NPRES_USER_BREAK);
635 INT32_TO_NPVARIANT(npError, *result);
639 static bool testEnumerate(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
641 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_OBJECT(args[1]))
645 NPIdentifier* identifiers;
646 if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
647 NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
648 NPIdentifier pushIdentifier = browser->getstringidentifier("push");
650 for (uint32_t i = 0; i < count; i++) {
651 NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);
657 STRINGZ_TO_NPVARIANT(string, args[0]);
658 NPVariant browserResult;
659 if (browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &browserResult))
660 browser->releasevariantvalue(&browserResult);
661 browser->memfree(string);
664 browser->memfree(identifiers);
667 VOID_TO_NPVARIANT(*result);
671 static bool testGetIntIdentifier(PluginObject*, const NPVariant* args, uint32_t argCount, NPVariant* result)
673 if (argCount != 1 || !NPVARIANT_IS_DOUBLE(args[0]))
676 NPIdentifier identifier = browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0]));
677 INT32_TO_NPVARIANT((int32_t)(long long)identifier, *result);
681 static bool testGetProperty(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
687 browser->getvalue(obj->npp, NPNVWindowNPObject, &object);
689 for (uint32_t i = 0; i < argCount; i++) {
690 assert(NPVARIANT_IS_STRING(args[i]));
691 NPUTF8* propertyString = createCStringFromNPVariant(&args[i]);
692 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
693 free(propertyString);
696 bool retval = browser->getproperty(obj->npp, object, propertyIdentifier, &variant);
697 browser->releaseobject(object);
702 if (i + 1 < argCount) {
703 assert(NPVARIANT_IS_OBJECT(variant));
704 object = NPVARIANT_TO_OBJECT(variant);
711 VOID_TO_NPVARIANT(*result);
715 static bool testHasProperty(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
717 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(args[1]))
720 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
721 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
722 free(propertyString);
724 bool retval = browser->hasproperty(obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier);
726 BOOLEAN_TO_NPVARIANT(retval, *result);
730 static bool testHasMethod(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
732 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(args[1]))
735 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
736 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
737 free(propertyString);
739 bool retval = browser->hasmethod(obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier);
741 BOOLEAN_TO_NPVARIANT(retval, *result);
745 static bool testEvaluate(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
747 if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
749 NPObject* windowScriptObject;
750 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
752 NPString s = NPVARIANT_TO_STRING(args[0]);
754 bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result);
755 browser->releaseobject(windowScriptObject);
759 static bool testGetPropertyReturnValue(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
761 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(args[1]))
764 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
765 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
766 free(propertyString);
769 bool retval = browser->getproperty(obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier, &variant);
771 browser->releasevariantvalue(&variant);
773 BOOLEAN_TO_NPVARIANT(retval, *result);
777 static char* toCString(const NPString& string)
779 char* result = static_cast<char*>(malloc(string.UTF8Length + 1));
780 memcpy(result, string.UTF8Characters, string.UTF8Length);
781 result[string.UTF8Length] = '\0';
786 static bool testPostURLFile(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
788 if (argCount != 4 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]) || !NPVARIANT_IS_STRING(args[2]) || !NPVARIANT_IS_STRING(args[3]))
791 NPString urlString = NPVARIANT_TO_STRING(args[0]);
792 char* url = toCString(urlString);
794 NPString targetString = NPVARIANT_TO_STRING(args[1]);
795 char* target = toCString(targetString);
797 NPString pathString = NPVARIANT_TO_STRING(args[2]);
798 char* path = toCString(pathString);
800 NPString contentsString = NPVARIANT_TO_STRING(args[3]);
802 FILE* tempFile = fopen(path, "w");
806 size_t written = fwrite(contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile);
811 NPError error = browser->posturl(obj->npp, url, target, pathString.UTF8Length, path, true);
817 BOOLEAN_TO_NPVARIANT(error == NPERR_NO_ERROR, *result);
821 static bool testConstruct(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
823 if (!argCount || !NPVARIANT_IS_OBJECT(args[0]))
826 return browser->construct(obj->npp, NPVARIANT_TO_OBJECT(args[0]), args + 1, argCount - 1, result);
829 // Invoke a script callback to get a script NPObject. Then call a method on the
830 // script NPObject passing it a freshly created NPObject.
831 static bool testScriptObjectInvoke(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
833 if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]))
835 NPObject* windowScriptObject;
836 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
838 // Arg1 is the name of the callback
839 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
840 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
841 free(callbackString);
843 // Invoke a callback that returns a script object
844 NPVariant object_result;
845 browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, &args[1], 1, &object_result);
847 // Script object returned
848 NPObject* script_object = object_result.value.objectValue;
850 // Arg2 is the name of the method to be called on the script object
851 NPUTF8* object_mehod_string = createCStringFromNPVariant(&args[1]);
852 NPIdentifier object_method = browser->getstringidentifier(object_mehod_string);
853 free(object_mehod_string);
855 // Create a fresh NPObject to be passed as an argument
856 NPObject* object_arg = browser->createobject(obj->npp, obj->header._class);
858 NPVariant invoke_args[1];
859 OBJECT_TO_NPVARIANT(object_arg, invoke_args[0]);
861 // Invoke the script method
862 NPVariant object_method_result;
863 browser->invoke(obj->npp, script_object, object_method, invoke_args, 1, &object_method_result);
865 browser->releasevariantvalue(&object_result);
866 VOID_TO_NPVARIANT(*result);
867 if (NPVARIANT_IS_OBJECT(object_method_result)) {
868 // Now return the callbacks return value back to our caller.
869 // BUG 897451: This should be the same as the
870 // windowScriptObject, but its not (in Chrome) - or at least, it
871 // has a different refcount. This means Chrome will delete the
872 // object before returning it and the calling JS gets a garbage
873 // value. Firefox handles it fine.
874 OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(object_method_result), *result);
876 browser->releasevariantvalue(&object_method_result);
877 VOID_TO_NPVARIANT(*result);
880 browser->releaseobject(object_arg);
885 // Helper function to notify the layout test controller that the test completed.
886 void notifyTestCompletion(NPP npp, NPObject* object)
890 script.UTF8Characters = "javascript:window.testRunner.notifyDone();";
891 script.UTF8Length = strlen("javascript:window.testRunner.notifyDone();");
892 browser->evaluate(npp, object, &script, &result);
893 browser->releasevariantvalue(&result);
896 bool testDocumentOpen(NPP npp)
898 NPIdentifier documentId = browser->getstringidentifier("document");
899 NPIdentifier openId = browser->getstringidentifier("open");
901 NPObject* windowObject = 0;
902 browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
906 NPVariant docVariant;
907 browser->getproperty(npp, windowObject, documentId, &docVariant);
908 if (docVariant.type != NPVariantType_Object) {
909 browser->releaseobject(windowObject);
913 NPObject* documentObject = NPVARIANT_TO_OBJECT(docVariant);
915 NPVariant openArgs[2];
916 STRINGZ_TO_NPVARIANT("text/html", openArgs[0]);
917 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);
920 if (!browser->invoke(npp, documentObject, openId, openArgs, 2, &result)) {
921 browser->releaseobject(windowObject);
922 browser->releaseobject(documentObject);
926 browser->releaseobject(documentObject);
928 if (result.type != NPVariantType_Object) {
929 browser->releaseobject(windowObject);
930 browser->releasevariantvalue(&result);
934 pluginLogWithWindowObject(windowObject, npp, "PLUGIN: DOCUMENT OPEN SUCCESS");
935 notifyTestCompletion(npp, result.value.objectValue);
936 browser->releaseobject(result.value.objectValue);
937 browser->releaseobject(windowObject);
941 bool testWindowOpen(NPP npp)
943 NPIdentifier openId = browser->getstringidentifier("open");
945 NPObject* windowObject = 0;
946 browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
950 NPVariant openArgs[2];
951 STRINGZ_TO_NPVARIANT("about:blank", openArgs[0]);
952 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);
955 if (!browser->invoke(npp, windowObject, openId, openArgs, 2, &result)) {
956 browser->releaseobject(windowObject);
960 if (result.type != NPVariantType_Object) {
961 browser->releaseobject(windowObject);
962 browser->releasevariantvalue(&result);
966 pluginLogWithWindowObject(windowObject, npp, "PLUGIN: WINDOW OPEN SUCCESS");
967 notifyTestCompletion(npp, result.value.objectValue);
968 browser->releaseobject(result.value.objectValue);
969 browser->releaseobject(windowObject);
973 static bool testSetStatus(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
976 if (argCount && NPVARIANT_IS_STRING(args[0])) {
977 NPString statusString = NPVARIANT_TO_STRING(args[0]);
978 message = toCString(statusString);
981 browser->status(obj->npp, message);
987 static bool testResizeTo(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
989 VOID_TO_NPVARIANT(*result);
991 NPObject* windowObject;
992 if (NPERR_NO_ERROR != browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
995 NPVariant callResult;
996 if (browser->invoke(obj->npp, windowObject, browser->getstringidentifier("resizePlugin"), args, argCount, &callResult))
997 browser->releasevariantvalue(&callResult);
1000 if (browser->getproperty(obj->npp, windowObject, browser->getstringidentifier("pageYOffset"), &callResult))
1001 browser->releasevariantvalue(&callResult);
1006 static bool normalizeOverride(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
1008 VOID_TO_NPVARIANT(*result);
1010 NPObject* windowObject;
1011 if (NPERR_NO_ERROR != browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
1014 NPVariant callResult;
1015 if (browser->invoke(obj->npp, windowObject, browser->getstringidentifier("pluginCallback"), args, argCount, &callResult))
1016 browser->releasevariantvalue(&callResult);
1021 static bool invalidateRect(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
1027 rect.left = static_cast<int>(NPVARIANT_TO_DOUBLE(args[0]));
1028 rect.top = static_cast<int>(NPVARIANT_TO_DOUBLE(args[1]));
1029 rect.right = static_cast<int>(NPVARIANT_TO_DOUBLE(args[2]));
1030 rect.bottom = static_cast<int>(NPVARIANT_TO_DOUBLE(args[3]));
1032 browser->invalidaterect(obj->npp, &rect);
1036 static bool objectsAreSame(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result)
1038 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_OBJECT(args[1]))
1041 BOOLEAN_TO_NPVARIANT(NPVARIANT_TO_OBJECT(args[0]) == NPVARIANT_TO_OBJECT(args[1]), *result);
1045 static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
1047 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1048 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD])
1049 return testCallback(plugin, args, argCount, result);
1050 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD_RETURN])
1051 return testCallbackReturn(plugin, args, argCount, result);
1052 if (name == pluginMethodIdentifiers[ID_TEST_GETURL])
1053 return getURL(plugin, args, argCount, result);
1054 if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS])
1055 return testDOMAccess(plugin, args, argCount, result);
1056 if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY])
1057 return getURLNotify(plugin, args, argCount, result);
1058 if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT])
1059 return testInvokeDefault(plugin, args, argCount, result);
1060 if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE])
1061 return testEnumerate(plugin, args, argCount, result);
1062 if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM])
1063 return destroyStream(plugin, args, argCount, result);
1064 if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER])
1065 return testGetIntIdentifier(plugin, args, argCount, result);
1066 if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE])
1067 return testEvaluate(plugin, args, argCount, result);
1068 if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY])
1069 return testGetProperty(plugin, args, argCount, result);
1070 if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE])
1071 return testGetPropertyReturnValue(plugin, args, argCount, result);
1072 if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY])
1073 return testHasProperty(plugin, args, argCount, result);
1074 if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD])
1075 return testHasMethod(plugin, args, argCount, result);
1076 if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING])
1077 return testIdentifierToString(plugin, args, argCount, result);
1078 if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT])
1079 return testIdentifierToInt(plugin, args, argCount, result);
1080 if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT])
1081 return testPassTestObject(plugin, args, argCount, result);
1082 if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE])
1083 return testPostURLFile(plugin, args, argCount, result);
1084 if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT])
1085 return testConstruct(plugin, args, argCount, result);
1086 if (name == pluginMethodIdentifiers[ID_TEST_SCRIPT_OBJECT_INVOKE])
1087 return testScriptObjectInvoke(plugin, args, argCount, result);
1088 if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) {
1089 browser->setexception(header, "plugin object testThrowException SUCCESS");
1092 if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) {
1093 NPObject* windowScriptObject;
1094 browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);
1095 browser->invoke(plugin->npp, windowScriptObject, name, args, argCount, result);
1098 if (name == pluginMethodIdentifiers[ID_TEST_CLONE_OBJECT]) {
1099 NPObject* new_object = browser->createobject(plugin->npp, plugin->header._class);
1100 assert(new_object->referenceCount == 1);
1101 OBJECT_TO_NPVARIANT(new_object, *result);
1104 if (name == pluginMethodIdentifiers[ID_TEST_CREATE_TEST_OBJECT]) {
1105 NPObject* testObject = browser->createobject(plugin->npp, getTestClass());
1106 assert(testObject->referenceCount == 1);
1107 OBJECT_TO_NPVARIANT(testObject, *result);
1110 if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM])
1111 return destroyNullStream(plugin, args, argCount, result);
1112 if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) {
1113 browser->reloadplugins(false);
1116 if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) {
1117 browser->reloadplugins(true);
1120 if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) {
1121 browser->getproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), result);
1124 if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) {
1125 browser->setproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), &args[2]);
1128 if (name == pluginMethodIdentifiers[ID_REMEMBER]) {
1129 if (plugin->rememberedObject)
1130 browser->releaseobject(plugin->rememberedObject);
1131 plugin->rememberedObject = NPVARIANT_TO_OBJECT(args[0]);
1132 browser->retainobject(plugin->rememberedObject);
1133 VOID_TO_NPVARIANT(*result);
1136 if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) {
1137 assert(plugin->rememberedObject);
1138 browser->retainobject(plugin->rememberedObject);
1139 OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
1142 if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) {
1143 assert(plugin->rememberedObject);
1144 OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
1145 plugin->rememberedObject = 0;
1148 if (name == pluginMethodIdentifiers[ID_REF_COUNT]) {
1149 uint32_t refCount = NPVARIANT_TO_OBJECT(args[0])->referenceCount;
1150 INT32_TO_NPVARIANT(refCount, *result);
1153 if (name == pluginMethodIdentifiers[ID_SET_STATUS])
1154 return testSetStatus(plugin, args, argCount, result);
1155 if (name == pluginMethodIdentifiers[ID_RESIZE_TO])
1156 return testResizeTo(plugin, args, argCount, result);
1157 if (name == pluginMethodIdentifiers[ID_NORMALIZE])
1158 return normalizeOverride(plugin, args, argCount, result);
1159 if (name == pluginMethodIdentifiers[ID_INVALIDATE_RECT])
1160 return invalidateRect(plugin, args, argCount, result);
1161 if (name == pluginMethodIdentifiers[ID_OBJECTS_ARE_SAME])
1162 return objectsAreSame(plugin, args, argCount, result);
1163 if (name == pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]) {
1164 NPObject* newObject = browser->createobject(plugin->npp, plugin->header._class);
1165 OBJECT_TO_NPVARIANT(newObject, *result);
1166 callDeletePlugin(header, name, pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]);
1172 static void pluginInvalidate(NPObject* header)
1174 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1175 plugin->testObject = 0;
1176 plugin->rememberedObject = 0;
1179 static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
1181 PluginObject* newInstance = (PluginObject*)malloc(sizeof(PluginObject));
1183 if (!identifiersInitialized) {
1184 identifiersInitialized = true;
1185 initializeIdentifiers();
1188 newInstance->pluginTest = 0;
1189 newInstance->npp = npp;
1190 newInstance->testObject = browser->createobject(npp, getTestClass());
1191 newInstance->rememberedObject = 0;
1192 newInstance->eventLogging = false;
1193 newInstance->onStreamLoad = 0;
1194 newInstance->onStreamDestroy = 0;
1195 newInstance->onDestroy = 0;
1196 newInstance->onURLNotify = 0;
1197 newInstance->onSetWindow = 0;
1198 newInstance->onPaintEvent = 0;
1199 newInstance->logDestroy = false;
1200 newInstance->logSetWindow = false;
1201 newInstance->returnErrorFromNewStream = false;
1202 newInstance->returnNegativeOneFromWrite = false;
1203 newInstance->stream = 0;
1205 newInstance->firstUrl = 0;
1206 newInstance->firstHeaders = 0;
1207 newInstance->lastUrl = 0;
1208 newInstance->lastHeaders = 0;
1210 newInstance->testGetURLOnDestroy = false;
1211 newInstance->testWindowOpen = false;
1212 newInstance->testKeyboardFocusForPlugins = false;
1214 newInstance->mouseDownForEvaluateScript = false;
1215 newInstance->evaluateScriptOnMouseDownOrKeyDown = 0;
1217 return (NPObject*)newInstance;
1220 static void pluginDeallocate(NPObject* header)
1222 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1223 delete plugin->pluginTest;
1224 if (plugin->testObject)
1225 browser->releaseobject(plugin->testObject);
1226 if (plugin->rememberedObject)
1227 browser->releaseobject(plugin->rememberedObject);
1229 free(plugin->firstUrl);
1230 free(plugin->firstHeaders);
1231 free(plugin->lastUrl);
1232 free(plugin->lastHeaders);
1236 void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
1242 NPObject* windowScriptObject;
1243 browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
1245 NPIdentifier callbackIdentifier = notifyData;
1247 INT32_TO_NPVARIANT(reason, args[0]);
1250 if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
1251 // Format expected by JavaScript validator: four fields separated by \n\n:
1252 // First URL; first header block; last URL; last header block.
1253 // Note that header blocks already end with \n due to how NPStream::headers works.
1254 int len = strlen(object->firstUrl) + 2
1255 + strlen(object->firstHeaders) + 1
1256 + strlen(object->lastUrl) + 2
1257 + strlen(object->lastHeaders) + 1;
1258 strHdr = (char*)malloc(len + 1);
1259 snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n",
1260 object->firstUrl, object->firstHeaders, object->lastUrl, object->lastHeaders);
1261 STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
1263 NULL_TO_NPVARIANT(args[1]);
1265 NPVariant browserResult;
1266 if (browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2, &browserResult))
1267 browser->releasevariantvalue(&browserResult);
1272 void notifyStream(PluginObject* object, const char *url, const char *headers)
1274 if (!object->firstUrl) {
1276 object->firstUrl = strdup(url);
1278 object->firstHeaders = strdup(headers);
1280 free(object->lastUrl);
1281 free(object->lastHeaders);
1282 object->lastUrl = (url ? strdup(url) : 0);
1283 object->lastHeaders = (headers ? strdup(headers) : 0);
1287 void testNPRuntime(NPP npp)
1289 NPObject* windowScriptObject;
1290 browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject);
1293 NPIdentifier testNPInvoke = browser->getstringidentifier("testNPInvoke");
1296 VOID_TO_NPVARIANT(args[0]);
1297 NULL_TO_NPVARIANT(args[1]);
1298 BOOLEAN_TO_NPVARIANT(true, args[2]);
1299 INT32_TO_NPVARIANT(242, args[3]);
1300 DOUBLE_TO_NPVARIANT(242.242, args[4]);
1301 STRINGZ_TO_NPVARIANT("Hello, World", args[5]);
1302 OBJECT_TO_NPVARIANT(windowScriptObject, args[6]);
1305 if (browser->invoke(npp, windowScriptObject, testNPInvoke, args, 7, &result))
1306 browser->releasevariantvalue(&result);
1308 browser->releaseobject(windowScriptObject);