Rubber-stamped by Brady Eidson.
[webbrowser.git] / WebCore / bridge / testbindings.cpp
blobe4bbc7e6e8d5692afb99ab7187c9186617a0d9ad
1 /*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "config.h"
22 #include <assert.h>
23 #include <stdio.h>
24 #include <string.h>
26 #include "JSValue.h"
27 #include "JSObject.h"
28 #include "types.h"
29 #include "interpreter.h"
31 #include "npruntime_internal.h"
33 #include "runtime.h"
34 #include "runtime_object.h"
37 #define LOG(formatAndArgs...) { \
38 fprintf (stderr, "%s: ", __PRETTY_FUNCTION__); \
39 fprintf(stderr, formatAndArgs); \
43 // ------------------ NP Interface definition --------------------
44 typedef struct
46 NPObject object;
47 double doubleValue;
48 int intValue;
49 NPVariant stringValue;
50 bool boolValue;
51 } MyObject;
54 static bool identifiersInitialized = false;
56 #define ID_DOUBLE_VALUE 0
57 #define ID_INT_VALUE 1
58 #define ID_STRING_VALUE 2
59 #define ID_BOOLEAN_VALUE 3
60 #define ID_NULL_VALUE 4
61 #define ID_UNDEFINED_VALUE 5
62 #define NUM_PROPERTY_IDENTIFIERS 6
64 static NPIdentifier myPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
65 static const NPUTF8 *myPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
66 "doubleValue",
67 "intValue",
68 "stringValue",
69 "booleanValue",
70 "nullValue",
71 "undefinedValue"
74 #define ID_LOG_MESSAGE 0
75 #define ID_SET_DOUBLE_VALUE 1
76 #define ID_SET_INT_VALUE 2
77 #define ID_SET_STRING_VALUE 3
78 #define ID_SET_BOOLEAN_VALUE 4
79 #define ID_GET_DOUBLE_VALUE 5
80 #define ID_GET_INT_VALUE 6
81 #define ID_GET_STRING_VALUE 7
82 #define ID_GET_BOOLEAN_VALUE 8
83 #define NUM_METHOD_IDENTIFIERS 9
85 static NPIdentifier myMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
86 static const NPUTF8 *myMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
87 "logMessage",
88 "setDoubleValue",
89 "setIntValue",
90 "setStringValue",
91 "setBooleanValue",
92 "getDoubleValue",
93 "getIntValue",
94 "getStringValue",
95 "getBooleanValue"
98 static void initializeIdentifiers()
100 NPN_GetStringIdentifiers (myPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, myPropertyIdentifiers);
101 NPN_GetStringIdentifiers (myMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, myMethodIdentifiers);
104 bool myHasProperty (NPClass *theClass, NPIdentifier name)
106 int i;
107 for (i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++) {
108 if (name == myPropertyIdentifiers[i]){
109 return true;
112 return false;
115 bool myHasMethod (NPClass *theClass, NPIdentifier name)
117 int i;
118 for (i = 0; i < NUM_METHOD_IDENTIFIERS; i++) {
119 if (name == myMethodIdentifiers[i]){
120 return true;
123 return false;
127 void logMessage (const NPVariant *message)
129 if (message->type == NPVariantStringType) {
130 char msgBuf[1024];
131 strncpy (msgBuf, message->value.stringValue.UTF8Characters, message->value.stringValue.UTF8Length);
132 msgBuf[message->value.stringValue.UTF8Length] = 0;
133 printf ("%s\n", msgBuf);
135 else if (message->type == NPVariantDoubleType)
136 printf ("%f\n", (float)message->value.doubleValue);
137 else if (message->type == NPVariantInt32Type)
138 printf ("%d\n", message->value.intValue);
139 else if (message->type == NPVariantObjectType)
140 printf ("%p\n", message->value.objectValue);
143 void setDoubleValue (MyObject *obj, const NPVariant *variant)
145 if (!NPN_VariantToDouble (variant, &obj->doubleValue)) {
146 NPUTF8 *msg = "Attempt to set double value with invalid type.";
147 NPString aString;
148 aString.UTF8Characters = msg;
149 aString.UTF8Length = strlen (msg);
150 NPN_SetException ((NPObject *)obj, &aString);
154 void setIntValue (MyObject *obj, const NPVariant *variant)
156 if (!NPN_VariantToInt32 (variant, &obj->intValue)) {
157 NPUTF8 *msg = "Attempt to set int value with invalid type.";
158 NPString aString;
159 aString.UTF8Characters = msg;
160 aString.UTF8Length = strlen (msg);
161 NPN_SetException ((NPObject *)obj, &aString);
165 void setStringValue (MyObject *obj, const NPVariant *variant)
167 NPN_ReleaseVariantValue (&obj->stringValue);
168 NPN_InitializeVariantWithVariant (&obj->stringValue, variant);
171 void setBooleanValue (MyObject *obj, const NPVariant *variant)
173 if (!NPN_VariantToBool (variant, (NPBool *)&obj->boolValue)) {
174 NPUTF8 *msg = "Attempt to set bool value with invalid type.";
175 NPString aString;
176 aString.UTF8Characters = msg;
177 aString.UTF8Length = strlen (msg);
178 NPN_SetException ((NPObject *)obj, &aString);
182 void getDoubleValue (MyObject *obj, NPVariant *variant)
184 NPN_InitializeVariantWithDouble (variant, obj->doubleValue);
187 void getIntValue (MyObject *obj, NPVariant *variant)
189 NPN_InitializeVariantWithInt32 (variant, obj->intValue);
192 void getStringValue (MyObject *obj, NPVariant *variant)
194 NPN_InitializeVariantWithVariant (variant, &obj->stringValue);
197 void getBooleanValue (MyObject *obj, NPVariant *variant)
199 NPN_InitializeVariantWithBool (variant, obj->boolValue);
202 void myGetProperty (MyObject *obj, NPIdentifier name, NPVariant *variant)
204 if (name == myPropertyIdentifiers[ID_DOUBLE_VALUE]){
205 getDoubleValue (obj, variant);
207 else if (name == myPropertyIdentifiers[ID_INT_VALUE]){
208 getIntValue (obj, variant);
210 else if (name == myPropertyIdentifiers[ID_STRING_VALUE]){
211 getStringValue (obj, variant);
213 else if (name == myPropertyIdentifiers[ID_BOOLEAN_VALUE]){
214 getBooleanValue (obj, variant);
216 else if (name == myPropertyIdentifiers[ID_NULL_VALUE]){
217 return NPN_InitializeVariantAsNull (variant);
219 else if (name == myPropertyIdentifiers[ID_UNDEFINED_VALUE]){
220 return NPN_InitializeVariantAsUndefined (variant);
222 else
223 NPN_InitializeVariantAsUndefined(variant);
226 void mySetProperty (MyObject *obj, NPIdentifier name, const NPVariant *variant)
228 if (name == myPropertyIdentifiers[ID_DOUBLE_VALUE]) {
229 setDoubleValue (obj, variant);
231 else if (name == myPropertyIdentifiers[ID_INT_VALUE]) {
232 setIntValue (obj, variant);
234 else if (name == myPropertyIdentifiers[ID_STRING_VALUE]) {
235 setStringValue (obj, variant);
237 else if (name == myPropertyIdentifiers[ID_BOOLEAN_VALUE]) {
238 setBooleanValue (obj, variant);
240 else if (name == myPropertyIdentifiers[ID_NULL_VALUE]) {
241 // Do nothing!
243 else if (name == myPropertyIdentifiers[ID_UNDEFINED_VALUE]) {
244 // Do nothing!
248 void myInvoke (MyObject *obj, NPIdentifier name, NPVariant *args, unsigned argCount, NPVariant *result)
250 if (name == myMethodIdentifiers[ID_LOG_MESSAGE]) {
251 if (argCount == 1 && NPN_VariantIsString(&args[0]))
252 logMessage (&args[0]);
253 NPN_InitializeVariantAsVoid (result);
255 else if (name == myMethodIdentifiers[ID_SET_DOUBLE_VALUE]) {
256 if (argCount == 1 && NPN_VariantIsDouble (&args[0]))
257 setDoubleValue (obj, &args[0]);
258 NPN_InitializeVariantAsVoid (result);
260 else if (name == myMethodIdentifiers[ID_SET_INT_VALUE]) {
261 if (argCount == 1 && (NPN_VariantIsDouble (&args[0]) || NPN_VariantIsInt32 (&args[0])))
262 setIntValue (obj, &args[0]);
263 NPN_InitializeVariantAsVoid (result);
265 else if (name == myMethodIdentifiers[ID_SET_STRING_VALUE]) {
266 if (argCount == 1 && NPN_VariantIsString (&args[0]))
267 setStringValue (obj, &args[0]);
268 NPN_InitializeVariantAsVoid (result);
270 else if (name == myMethodIdentifiers[ID_SET_BOOLEAN_VALUE]) {
271 if (argCount == 1 && NPN_VariantIsBool (&args[0]))
272 setBooleanValue (obj, &args[0]);
273 NPN_InitializeVariantAsVoid (result);
275 else if (name == myMethodIdentifiers[ID_GET_DOUBLE_VALUE]) {
276 getDoubleValue (obj, result);
278 else if (name == myMethodIdentifiers[ID_GET_INT_VALUE]) {
279 getIntValue (obj, result);
281 else if (name == myMethodIdentifiers[ID_GET_STRING_VALUE]) {
282 getStringValue (obj, result);
284 else if (name == myMethodIdentifiers[ID_GET_BOOLEAN_VALUE]) {
285 getBooleanValue (obj, result);
287 else
288 NPN_InitializeVariantAsUndefined (result);
291 NPObject *myAllocate ()
293 MyObject *newInstance = (MyObject *)malloc (sizeof(MyObject));
295 if (!identifiersInitialized) {
296 identifiersInitialized = true;
297 initializeIdentifiers();
301 newInstance->doubleValue = 666.666;
302 newInstance->intValue = 1234;
303 newInstance->boolValue = true;
304 newInstance->stringValue.type = NPVariantType_String;
305 newInstance->stringValue.value.stringValue.UTF8Length = strlen ("Hello world");
306 newInstance->stringValue.value.stringValue.UTF8Characters = strdup ("Hello world");
308 return (NPObject *)newInstance;
311 void myInvalidate ()
313 // Make sure we've released any remaining references to JavaScript objects.
316 void myDeallocate (MyObject *obj)
318 free ((void *)obj);
321 static NPClass _myFunctionPtrs = {
322 kNPClassStructVersionCurrent,
323 (NPAllocateFunctionPtr) myAllocate,
324 (NPDeallocateFunctionPtr) myDeallocate,
325 (NPInvalidateFunctionPtr) myInvalidate,
326 (NPHasMethodFunctionPtr) myHasMethod,
327 (NPInvokeFunctionPtr) myInvoke,
328 (NPHasPropertyFunctionPtr) myHasProperty,
329 (NPGetPropertyFunctionPtr) myGetProperty,
330 (NPSetPropertyFunctionPtr) mySetProperty,
332 static NPClass *myFunctionPtrs = &_myFunctionPtrs;
334 // --------------------------------------------------------
336 using namespace JSC;
337 using namespace JSC::Bindings;
339 class GlobalImp : public ObjectImp {
340 public:
341 virtual UString className() const { return "global"; }
344 #define BufferSize 200000
345 static char code[BufferSize];
347 const char *readJavaScriptFromFile (const char *file)
349 FILE *f = fopen(file, "r");
350 if (!f) {
351 fprintf(stderr, "Error opening %s.\n", file);
352 return 0;
355 int num = fread(code, 1, BufferSize, f);
356 code[num] = '\0';
357 if(num >= BufferSize)
358 fprintf(stderr, "Warning: File may have been too long.\n");
360 fclose(f);
362 return code;
365 int main(int argc, char **argv)
367 // expecting a filename
368 if (argc < 2) {
369 fprintf(stderr, "You have to specify at least one filename\n");
370 return -1;
373 bool ret = true;
375 JSLock lock;
377 // create interpreter w/ global object
378 Object global(new GlobalImp());
379 Interpreter interp;
380 interp.setGlobalObject(global);
381 ExecState *exec = interp.globalExec();
383 MyObject *myObject = (MyObject *)NPN_CreateObject (myFunctionPtrs);
385 global.put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::CLanguage, (void *)myObject));
387 for (int i = 1; i < argc; i++) {
388 const char *code = readJavaScriptFromFile(argv[i]);
390 if (code) {
391 // run
392 Completion comp(interp.evaluate(code));
394 if (comp.complType() == Throw) {
395 Value exVal = comp.value();
396 char *msg = exVal.toString(exec).ascii();
397 int lineno = -1;
398 if (exVal.type() == ObjectType) {
399 Value lineVal = Object::dynamicCast(exVal).get(exec,Identifier("line"));
400 if (lineVal.type() == NumberType)
401 lineno = int(lineVal.toNumber(exec));
403 if (lineno != -1)
404 fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
405 else
406 fprintf(stderr,"Exception: %s\n",msg);
407 ret = false;
409 else if (comp.complType() == ReturnValue) {
410 char *msg = comp.value().toString(interp.globalExec()).ascii();
411 fprintf(stderr,"Return value: %s\n",msg);
416 NPN_ReleaseObject ((NPObject *)myObject);
418 } // end block, so that Interpreter and global get deleted
420 return ret ? 0 : 3;