2 // Copyright (C) 2010, 2011 Free Software Foundation, Inc
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #include "gnashconfig.h"
30 #if NPAPI_VERSION == 190
34 #include "npruntime.h"
35 #include "npfunctions.h"
37 #include "pluginbase.h"
39 #include "../../testsuite/check.h"
43 #include "GnashNPVariant.h"
45 TestState
& runtest
= _runtest
;
47 std::map
<NPIdentifier
, NPVariant
*> _properties
;
48 std::map
<NPIdentifier
, NPInvokeFunctionPtr
> _methods
;
53 using namespace gnash
;
55 NPVariant
*value
= (NPVariant
*)NPN_MemAlloc(sizeof(NPVariant
));
57 BOOLEAN_TO_NPVARIANT(true, *value
);
58 std::string str
= plugin::ExternalInterface::convertNPVariant(value
);
59 if (str
== "<true/>") {
60 runtest
.pass("convertNPVariant(true)");
62 runtest
.fail("convertNPVariant(true)");
65 BOOLEAN_TO_NPVARIANT(false, *value
);
66 str
= plugin::ExternalInterface::convertNPVariant(value
);
67 if (str
== "<false/>") {
68 runtest
.pass("convertNPVariant(false)");
70 runtest
.fail("convertNPVariant(false)");
73 NULL_TO_NPVARIANT(*value
);
74 str
= plugin::ExternalInterface::convertNPVariant(value
);
75 if (str
== "<null/>") {
76 runtest
.pass("convertNPVariant(null)");
78 runtest
.fail("convertNPVariant(null)");
81 VOID_TO_NPVARIANT(*value
);
82 str
= plugin::ExternalInterface::convertNPVariant(value
);
83 if (str
== "<void/>") {
84 runtest
.pass("convertNPVariant(void)");
86 runtest
.fail("convertNPVariant(void)");
89 DOUBLE_TO_NPVARIANT(123.456, *value
);
90 str
= plugin::ExternalInterface::convertNPVariant(value
);
91 if (str
== "<number>123.456</number>") {
92 runtest
.pass("convertNPVariant(double)");
94 runtest
.fail("convertNPVariant(double)");
97 INT32_TO_NPVARIANT(78, *value
);
98 str
= plugin::ExternalInterface::convertNPVariant(value
);
99 if (str
== "<number>78</number>") {
100 runtest
.pass("convertNPVariant(int32)");
102 runtest
.fail("convertNPVariant(int32)");
105 STRINGZ_TO_NPVARIANT("Hello World!", *value
);
106 str
= plugin::ExternalInterface::convertNPVariant(value
);
107 if (str
== "<string>Hello World!</string>") {
108 runtest
.pass("convertNPVariant(string)");
110 runtest
.fail("convertNPVariant(string)");
113 str
= plugin::ExternalInterface::makeProperty("hi", "Hello World!");
114 if (str
== "<property id=\"hi\">Hello World!</property>") {
115 runtest
.pass("plugin::ExternalInterface::makeProperty()");
117 runtest
.fail("plugin::ExternalInterface::makeProperty()");
121 ARRAY_TO_NPVARIANT(*value
);
122 str
= plugin::ExternalInterface::convertNPVariant(value
);
123 if (str
== "<array></array>") {
124 runtest
.pass("convertNPVariant(array)");
126 runtest
.fail("convertNPVariant(array)");
130 std::string prop1
= plugin::ExternalInterface::makeString("foobar");
131 std::string prop2
= plugin::ExternalInterface::makeNumber(12.34);
132 std::string prop3
= plugin::ExternalInterface::makeNumber(56);
133 std::vector
<std::string
> aargs
;
134 aargs
.push_back(prop1
);
135 aargs
.push_back(prop2
);
136 aargs
.push_back(prop3
);
139 regcomp (®ex_pat
, "<array><property id=\"0\"><string>foobar</string></property><property id=\"1\"><number>12.34</number></property><property id=\"2\"><number>56</number></property></array>", REG_NOSUB
|REG_NEWLINE
);
140 str
= plugin::ExternalInterface::makeArray(aargs
);
141 if (regexec (®ex_pat
, reinterpret_cast<const char*>(str
.c_str()), 0, (regmatch_t
*)0, 0)) {
142 runtest
.fail("plugin::ExternalInterface::makeArray()");
144 runtest
.pass("plugin::ExternalInterface::makeArray()");
147 std::map
<std::string
, std::string
> margs
;
148 margs
["test1"] = prop1
;
149 margs
["test2"] = prop2
;
150 margs
["test3"] = prop3
;
152 str
= plugin::ExternalInterface::makeObject(margs
);
153 std::string xml
= "<object><property id=\"test1\"><string>foobar</string></property><property id=\"test2\"><number>12.34</number></property><property id=\"test3\"><number>56</number></property></object>";
155 regfree (®ex_pat
);
156 regcomp (®ex_pat
, xml
.c_str(), REG_NOSUB
|REG_NEWLINE
);
158 // std::cout << str << std::endl;
159 if (regexec (®ex_pat
, reinterpret_cast<const char*>(str
.c_str()), 0, (regmatch_t
*)0, 0)) {
160 runtest
.fail("plugin::ExternalInterface::makeObject()");
162 runtest
.pass("plugin::ExternalInterface::makeObject()");
168 xml
= "<string>Hello World!</string>";
169 GnashNPVariant np
= plugin::ExternalInterface::parseXML(xml
);
170 std::string data
= NPStringToString(NPVARIANT_TO_STRING(np
.get()));
171 if (NPVARIANT_IS_STRING(np
.get()) &&
172 (data
== "Hello World!")) {
173 runtest
.pass("plugin::ExternalInterface::parseXML(string)");
175 runtest
.fail("plugin::ExternalInterface::parseXML(string)");
178 xml
= "<number>123.456</number>";
179 np
= plugin::ExternalInterface::parseXML(xml
);
180 double num
= NPVARIANT_TO_DOUBLE(np
.get());
181 if (NPVARIANT_IS_DOUBLE(np
.get()) &&
183 runtest
.pass("plugin::ExternalInterface::parseXML(double)");
185 runtest
.fail("plugin::ExternalInterface::parseXML(double)");
188 xml
= "<number>78</number>";
189 np
= plugin::ExternalInterface::parseXML(xml
);
190 int inum
= NPVARIANT_TO_INT32(np
.get());
191 if (NPVARIANT_IS_INT32(np
.get()) &&
193 runtest
.pass("plugin::ExternalInterface::parseXML(int32)");
195 runtest
.fail("plugin::ExternalInterface::parseXML(int32)");
199 np
= plugin::ExternalInterface::parseXML(xml
);
200 bool flag
= NPVARIANT_TO_BOOLEAN(np
.get());
201 if (NPVARIANT_IS_BOOLEAN(np
.get()) &&
203 runtest
.pass("plugin::ExternalInterface::parseXML(true)");
205 runtest
.fail("plugin::ExternalInterface::parseXML(true)");
209 np
= plugin::ExternalInterface::parseXML(xml
);
210 flag
= NPVARIANT_TO_BOOLEAN(np
.get());
211 if (NPVARIANT_IS_BOOLEAN(np
.get()) &&
213 runtest
.pass("plugin::ExternalInterface::parseXML(false)");
215 runtest
.fail("plugin::ExternalInterface::parseXML(false)");
219 np
= plugin::ExternalInterface::parseXML(xml
);
220 if (NPVARIANT_IS_NULL(np
.get())) {
221 runtest
.pass("plugin::ExternalInterface::parseXML(null)");
223 runtest
.fail("plugin::ExternalInterface::parseXML(null)");
227 np
= plugin::ExternalInterface::parseXML(xml
);
228 if (NPVARIANT_IS_VOID(np
.get())) {
229 runtest
.pass("plugin::ExternalInterface::parseXML(void)");
231 runtest
.fail("plugin::ExternalInterface::parseXML(void)");
234 xml
= "<property id=\"0\"><string>foobar</string></property><property id=\"1\"><number>12.34</number></property><property id=\"2\"><number>56</number></property>";
235 std::map
<std::string
, GnashNPVariant
> props
= plugin::ExternalInterface::parseProperties(xml
);
237 data
= NPStringToString(NPVARIANT_TO_STRING(np
.get()));
238 if ((props
.size() == 3) && (data
== "foobar")) {
239 runtest
.pass("plugin::ExternalInterface::parseProperties()");
241 runtest
.fail("plugin::ExternalInterface::parseProperties()");
244 xml
= "<object><property id=\"test1\"><string>foobar</string></property><property id=\"test2\"><number>12.34</number></property><property id=\"test3\"><number>56</number></property></object>";
245 np
= plugin::ExternalInterface::parseXML(xml
);
246 if (NPVARIANT_IS_OBJECT(np
.get())) {
247 runtest
.pass("plugin::ExternalInterface::parseXML(object)");
249 runtest
.fail("plugin::ExternalInterface::parseXML(object)");
252 std::vector
<std::string
> iargs
;
253 str
= plugin::ExternalInterface::makeString("barfoo");
254 iargs
.push_back(str
);
255 str
= plugin::ExternalInterface::makeNumber(135.78);
256 iargs
.push_back(str
);
258 str
= plugin::ExternalInterface::makeInvoke("barbyfoo", iargs
);
259 xml
= "<invoke name=\"barbyfoo\" returntype=\"xml\"><arguments><string>barfoo</string><number>135.78</number></arguments></invoke>";
260 // std::cout << str << std::endl;
261 regfree (®ex_pat
);
262 regcomp (®ex_pat
, xml
.c_str(), REG_NOSUB
|REG_NEWLINE
);
263 if (regexec (®ex_pat
, reinterpret_cast<const char*>(str
.c_str()), 0, (regmatch_t
*)0, 0) == 0) {
264 runtest
.pass("plugin::ExternalInterface::makeInvoke()");
266 runtest
.fail("plugin::ExternalInterface::makeInvoke()");
269 xml
= "<arguments><string>barfoo</string><number>135.78</number><number>89</number></arguments>";
270 std::vector
<GnashNPVariant
> arguments
= plugin::ExternalInterface::parseArguments(xml
);
272 str
= NPStringToString(NPVARIANT_TO_STRING(np
.get()));
273 double dub
= NPVARIANT_TO_DOUBLE(arguments
[1].get());
274 int val
= NPVARIANT_TO_INT32(arguments
[2].get());
275 if ((arguments
.size() == 3) && (str
== "barfoo")
276 && (dub
== 135.78) && (val
== 89)) {
277 runtest
.pass("plugin::ExternalInterface::parseArguments()");
279 runtest
.fail("plugin::ExternalInterface::parseArguments()");
282 // Parse an invoke message
283 xml
= "<invoke name=\"barbyfoo\" returntype=\"xml\"><arguments><string>barfoo</string><number>135.78</number></arguments></invoke>";
284 boost::shared_ptr
<plugin::ExternalInterface::invoke_t
> invoke ( plugin::ExternalInterface::parseInvoke(xml
) );
285 str
= NPStringToString(NPVARIANT_TO_STRING(invoke
->args
[0].get()));
286 if ((invoke
->name
== "barbyfoo") && (invoke
->type
== "xml")
287 && (NPVARIANT_IS_STRING(invoke
->args
[0].get()))
289 && (NPVARIANT_IS_DOUBLE(invoke
->args
[1].get()))
290 && (NPVARIANT_TO_DOUBLE(invoke
->args
[1].get()) == 135.78)
292 runtest
.pass("plugin::ExternalInterface::parseInvoke()");
294 runtest
.fail("plugin::ExternalInterface::parseInvoke()");
297 // Test for bug #31766
298 xml
= "<invoke name=\"reportFlashTiming\" returntype=\"xml\"><arguments><string>reportFlashTiming</string><object><property id=\"5\"><number>1297286708921</number></property><property id=\"4\"><string>vr</string></p";
299 invoke
= plugin::ExternalInterface::parseInvoke(xml
);
300 if ((invoke
->name
== "reportFlashTiming") && (invoke
->type
== "xml")
301 && invoke
->args
.empty())
303 runtest
.pass("plugin::ExternalInterface::parseInvoke() with missing closing invoke tag");
305 runtest
.fail("plugin::ExternalInterface::parseInvoke() with missing closing invoke tag");
309 xml
= "<invoke name=\"reportFlashTiming\" returntype=\"xml\"><arguments><string>reportFlashTiming</string><object><property id=\"5\"><number>1297326407594</number></property><property id=\"4\"><string>vr</string></property><property id=\"3\"><number>1297326407147</number></property><property id=\"2\"><string>gv</string></property><property id=\"1\"><number>1297326406281</number></property><property id=\"0\"><string>fs</string></property></object><string>34</string><number>2</number><string>AASb6VeOkQtvnu_8</string><string>0</string><string>LNX%2010%2C1%2C999%2C0</string><string>Gnash%20GNU%2FLinux</string></arguments></invoke>";
310 invoke
= plugin::ExternalInterface::parseInvoke(xml
);
311 check_equals (invoke
->name
, "reportFlashTiming");
312 check_equals (invoke
->type
, "xml");
313 xcheck_equals (invoke
->args
.size(), 8);
315 check(NPVARIANT_IS_STRING(invoke
->args
[0].get()));
316 str
= NPStringToString(NPVARIANT_TO_STRING(invoke
->args
[0].get()));
317 check_equals(str
, "reportFlashTiming");
319 xcheck(NPVARIANT_IS_OBJECT(invoke
->args
[1].get()));
320 // TODO: check object contents
322 xcheck(NPVARIANT_IS_STRING(invoke
->args
[2].get()));
323 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[2].get()));
324 // check_equals(str, "34");
326 xcheck(NPVARIANT_IS_DOUBLE(invoke
->args
[3].get()));
327 // check_equals(NPVARIANT_TO_DOUBLE(invoke->args[3].get()), 2);
329 check(NPVARIANT_IS_STRING(invoke
->args
[4].get()));
330 str
= NPStringToString(NPVARIANT_TO_STRING(invoke
->args
[4].get()));
331 xcheck_equals(str
, "AASb6VeOkQtvnu_8");
333 xcheck(NPVARIANT_IS_STRING(invoke
->args
[5].get()));
334 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[5].get()));
335 // check_equals(str, "0");
337 xcheck(NPVARIANT_IS_STRING(invoke
->args
[6].get()));
338 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[6].get()));
339 // check_equals(str, "LNX%2010%2C1%2C999%2C0");
341 xcheck(NPVARIANT_IS_STRING(invoke
->args
[7].get()));
342 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[7].get()));
343 // check_equals(str, "Gnash%20GNU%2FLinux");
347 xml
= "<object><property id=\"5\">";
348 GnashNPVariant v
= plugin::ExternalInterface::parseXML(xml
);
349 check(NPVARIANT_IS_NULL(v
.get()));
354 NULL_TO_NPVARIANT(val
);
355 check(NPVARIANT_IS_NULL(val
));
356 GnashNPVariant v
= val
;
357 check(NPVARIANT_IS_NULL(v
.get()));
360 regfree (®ex_pat
);
364 // We have to implement these two memory allocation functions as
365 // they're used in the code we're testing.
367 NPN_MemAlloc(uint32_t size
)
375 NPN_MemFree(void* ptr
)
381 // These are just stubs to get the test case to link standalone.
383 NPN_GetStringIdentifier(const NPUTF8
*)
388 nsPluginInstanceBase
*
389 NS_NewPluginInstance(nsPluginCreateData
*)
395 NS_PluginGetValue(NPPVariable
, void *)
397 return NPERR_INVALID_INSTANCE_ERROR
;
401 NS_PluginInitialize()
403 return NPERR_INVALID_INSTANCE_ERROR
;
412 NPP_GetMIMEDescription(void)
419 NS_DestroyPluginInstance(nsPluginInstanceBase
*)
423 // Implement minimal properties handling
425 NPN_SetProperty(NPP
, NPObject
*, NPIdentifier name
,
426 const NPVariant
*value
)
428 _properties
[name
] = const_cast<NPVariant
*>(value
);
433 NPN_GetProperty(NPP
, NPObject
* , NPIdentifier name
,
434 const NPVariant
*value
)
436 std::map
<NPIdentifier
, NPVariant
*>::iterator it
;
437 it
= _properties
.find(name
);
438 if (it
== _properties
.end()) return false;
444 NPN_HasProperty(NPP
, NPObject
* , NPIdentifier name
)
446 std::map
<NPIdentifier
, NPVariant
*>::iterator it
;
447 it
= _properties
.find(name
);
448 if (it
!= _properties
.end()) {
455 NPN_ReleaseVariantValue(NPVariant
*variant
)
457 switch(variant
->type
) {
458 case NPVariantType_String
:
460 NPN_MemFree(const_cast<NPUTF8
*>(gnash::GetNPStringChars(NPVARIANT_TO_STRING(*variant
))));
463 case NPVariantType_Object
:
465 NPObject
* obj
= NPVARIANT_TO_OBJECT(*variant
);
467 NPN_ReleaseObject(obj
);
475 NULL_TO_NPVARIANT(*variant
);
479 NPN_RetainObject(NPObject
*obj
)
480 { assert(obj
); ++obj
->referenceCount
; return obj
; }
484 NPN_ReleaseObject(NPObject
*npobj
)
487 --npobj
->referenceCount
;
488 if (npobj
->referenceCount
== 0) {
494 // indent-tabs-mode: nil