FreeWRL/FreeX3D  3.0.0
jsVRMLClasses.c
1 /*
2 
3 
4 ???
5 
6 */
7 
8 /****************************************************************************
9  This file is part of the FreeWRL/FreeX3D Distribution.
10 
11  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12 
13  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14  it under the terms of the GNU Lesser Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25 ****************************************************************************/
26 
27 
28 #include <config.h>
29 #include <system.h>
30 #if !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK))
31 #include <system_threads.h>
32 #include <display.h>
33 #include <internal.h>
34 
35 #include <libFreeWRL.h>
36 
37 
38 #include "../vrml_parser/Structs.h"
39 #include "../main/headers.h"
40 #include "../vrml_parser/CParseGeneral.h"
41 #include "../main/Snapshot.h"
42 #include "../scenegraph/Collision.h"
43 #include "../scenegraph/quaternion.h"
44 #include "../scenegraph/Viewer.h"
45 #include "../input/SensInterps.h"
46 #include "../x3d_parser/Bindable.h"
47 
48 #include "JScript.h"
49 #include "CScripts.h"
50 #include "jsUtils.h"
51 #include "jsNative.h"
52 #include "jsVRMLClasses.h"
53 
54 
55 
56 /********************************************************/
57 /* */
58 /* first part - standard helper functions */
59 /* */
60 /********************************************************/
61 
62 void _get4f(double *ret, double *mat, int row);
63 void _set4f(double len, double *mat, int row);
64 
65 /* for keeping track of the ECMA values */
66 #define ECMAValueTableSize 100
67 /* for keeping track of the ECMA values */
69  jsval JS_address;
70  JSContext *context;
71  int valueChanged;
72  char *name;
73 };
74 
75 //struct ECMAValueStruct ECMAValues[ECMAValueTableSize];
76 //int maxECMAVal = 0;
77 
78 typedef struct pjsVRMLClasses{
79  struct ECMAValueStruct ECMAValues[ECMAValueTableSize];
80  int maxECMAVal;// = 0;
82 void *jsVRMLClasses_constructor(){
83  void *v = MALLOCV(sizeof(struct pjsVRMLClasses));
84  memset(v,0,sizeof(struct pjsVRMLClasses));
85  return v;
86 }
87 void jsVRMLClasses_init(struct tjsVRMLClasses *t){
88  //public
89  //private
90  t->prv = jsVRMLClasses_constructor();
91  {
92  ppjsVRMLClasses p = (ppjsVRMLClasses)t->prv;
93  //p->ECMAValues[ECMAValueTableSize];
94  p->maxECMAVal = 0;
95  }
96 }
97 // ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
98 /*
99  * VRML Node types as JS classes:
100  */
101 
102 
103 
104 JSClass SFColorClass = {
105  "SFColor",
106  JSCLASS_HAS_PRIVATE,
107  JS_PropertyStub,
108  JS_PropertyStub,
109  SFColorGetProperty,
110  SFColorSetProperty,
111  JS_EnumerateStub,
112  JS_ResolveStub,
113  JS_ConvertStub,
114  JS_MY_Finalize
115 };
116 
117 JSPropertySpec (SFColorProperties)[] = {
118  {"r", 0, JSPROP_ENUMERATE},
119  {"g", 1, JSPROP_ENUMERATE},
120  {"b", 2, JSPROP_ENUMERATE},
121  {0}
122 };
123 
124 JSFunctionSpec (SFColorFunctions)[] = {
125  {"getHSV", SFColorGetHSV, 0},
126  {"setHSV", SFColorSetHSV, 0},
127  {"toString", SFColorToString, 0},
128  {"assign", SFColorAssign, 0},
129  {0}
130 };
131 
132 
133 
134 JSClass SFColorRGBAClass = {
135  "SFColorRGBA",
136  JSCLASS_HAS_PRIVATE,
137  JS_PropertyStub,
138  JS_PropertyStub,
139  SFColorRGBAGetProperty,
140  SFColorRGBASetProperty,
141  JS_EnumerateStub,
142  JS_ResolveStub,
143  JS_ConvertStub,
144  JS_MY_Finalize
145 };
146 
147 JSPropertySpec (SFColorRGBAProperties)[] = {
148  {"r", 0, JSPROP_ENUMERATE},
149  {"g", 1, JSPROP_ENUMERATE},
150  {"b", 2, JSPROP_ENUMERATE},
151  {"a", 3, JSPROP_ENUMERATE},
152  {0}
153 };
154 
155 JSFunctionSpec (SFColorRGBAFunctions)[] = {
156  {"getHSV", SFColorRGBAGetHSV, 0},
157  {"setHSV", SFColorRGBASetHSV, 0},
158  {"toString", SFColorRGBAToString, 0},
159  {"assign", SFColorRGBAAssign, 0},
160  {0}
161 };
162 
163 
164 
165 JSClass SFImageClass = {
166  "SFImage",
167  JSCLASS_HAS_PRIVATE,
168  JS_PropertyStub,
169  JS_PropertyStub,
170  SFImageGetProperty,
171  SFImageSetProperty,
172  JS_EnumerateStub,
173  JS_ResolveStub,
174  JS_ConvertStub,
175  JS_MY_Finalize
176 };
177 
178 JSPropertySpec (SFImageProperties)[] = {
179  {"x", 0, JSPROP_ENUMERATE},
180  {"y", 1, JSPROP_ENUMERATE},
181  {"comp", 2, JSPROP_ENUMERATE},
182  {"array", 3, JSPROP_ENUMERATE},
183  {0}
184 };
185 
186 JSFunctionSpec (SFImageFunctions)[] = {
187  {"toString", SFImageToString, 0},
188  {"assign", SFImageAssign, 0},
189  {0}
190 };
191 
192 
193 
194 JSClass SFNodeClass = {
195  "SFNode",
196  JSCLASS_HAS_PRIVATE,
197  JS_PropertyStub,
198  JS_PropertyStub,
199  SFNodeGetProperty,
200  SFNodeSetProperty,
201  JS_EnumerateStub,
202  JS_ResolveStub,
203  JS_ConvertStub,
204  SFNodeFinalize /* note, this is different, as it contains a string to get rid of */
205 };
206 
207 JSPropertySpec (SFNodeProperties)[] = {
208  {0}
209 };
210 
211 JSFunctionSpec (SFNodeFunctions)[] = {
212 #ifdef NEWCLASSES
213  {"getNodeName", SFNodeGetNodeName, 0},
214  {"getNodeType", SFNodeGetNodeType, 0},
215  {"getFieldDefinitions",SFNodeGetFieldDefs, 0},
216  {"toVRMLString",SFNodeToVRMLString, 0},
217  {"toXMLString", SFNodeToXMLString, 0},
218 #endif
219  {"toString", SFNodeToString, 0}, /* depreciated JAS */
220  {"assign", SFNodeAssign, 0},
221  {0}
222 };
223 
224 
225 
226 JSClass SFRotationClass = {
227  "SFRotation",
228  JSCLASS_HAS_PRIVATE,
229  JS_PropertyStub,
230  JS_PropertyStub,
231  SFRotationGetProperty,
232  SFRotationSetProperty,
233  JS_EnumerateStub,
234  JS_ResolveStub,
235  JS_ConvertStub,
236  JS_MY_Finalize
237 };
238 
239 JSPropertySpec (SFRotationProperties)[] = {
240  {"x", 0, JSPROP_ENUMERATE},
241  {"y", 1, JSPROP_ENUMERATE},
242  {"z", 2, JSPROP_ENUMERATE},
243  {"angle",3, JSPROP_ENUMERATE},
244  {0}
245 };
246 
247 JSFunctionSpec (SFRotationFunctions)[] = {
248  {"getAxis", SFRotationGetAxis, 0},
249  {"inverse", SFRotationInverse, 0},
250  {"multiply", SFRotationMultiply, 0},
251  {"multVec", SFRotationMultVec, 0},
252  {"multiVec", SFRotationMultVec, 0},
253  {"setAxis", SFRotationSetAxis, 0},
254  {"slerp", SFRotationSlerp, 0},
255  {"toString", SFRotationToString, 0},
256  {"assign", SFRotationAssign, 0},
257  {0}
258 };
259 
260 
261 
262 JSClass SFVec2fClass = {
263  "SFVec2f",
264  JSCLASS_HAS_PRIVATE,
265  JS_PropertyStub,
266  JS_PropertyStub,
267  SFVec2fGetProperty,
268  SFVec2fSetProperty,
269  JS_EnumerateStub,
270  JS_ResolveStub,
271  JS_ConvertStub,
272  JS_MY_Finalize
273 };
274 
275 JSPropertySpec (SFVec2fProperties)[] = {
276  {"x", 0, JSPROP_ENUMERATE},
277  {"y", 1, JSPROP_ENUMERATE},
278  {0}
279 };
280 
281 JSFunctionSpec (SFVec2fFunctions)[] = {
282  {"add", SFVec2fAdd, 0},
283  {"divide", SFVec2fDivide, 0},
284  {"dot", SFVec2fDot, 0},
285  {"length", SFVec2fLength, 0},
286  {"multiply", SFVec2fMultiply, 0},
287  {"normalize", SFVec2fNormalize, 0},
288  {"subtract", SFVec2fSubtract, 0},
289  {"toString", SFVec2fToString, 0},
290  {"assign", SFVec2fAssign, 0},
291  {0}
292 };
293 
294 #ifdef NEWCLASSES
295 JSClass SFVec2dClass = {
296  "SFVec2d",
297  JSCLASS_HAS_PRIVATE,
298  JS_PropertyStub,
299  JS_PropertyStub,
300  SFVec2dGetProperty,
301  SFVec2dSetProperty,
302  JS_EnumerateStub,
303  JS_ResolveStub,
304  JS_ConvertStub,
305  JS_MY_Finalize
306 };
307 
308 JSPropertySpec (SFVec2dProperties)[] = {
309  {"x", 0, JSPROP_ENUMERATE},
310  {"y", 1, JSPROP_ENUMERATE},
311  {0}
312 };
313 
314 JSFunctionSpec (SFVec2dFunctions)[] = {
315  {"add", SFVec2dAdd, 0},
316  {"divide", SFVec2dDivide, 0},
317  {"dot", SFVec2dDot, 0},
318  {"length", SFVec2dLength, 0},
319  {"multiply", SFVec2dMultiply, 0},
320  {"normalize", SFVec2dNormalize, 0},
321  {"subtract", SFVec2dSubtract, 0},
322  {"toString", SFVec2dToString, 0},
323  {"assign", SFVec2dAssign, 0},
324  {0}
325 };
326 
327 #endif /* NEWCLASSES */
328 
329 JSClass SFVec4fClass = {
330  "SFVec4f",
331  JSCLASS_HAS_PRIVATE,
332  JS_PropertyStub,
333  JS_PropertyStub,
334  SFVec4fGetProperty,
335  SFVec4fSetProperty,
336  JS_EnumerateStub,
337  JS_ResolveStub,
338  JS_ConvertStub,
339  JS_MY_Finalize
340 };
341 
342 JSPropertySpec (SFVec4fProperties)[] = {
343  {"x", 0, JSPROP_ENUMERATE},
344  {"y", 1, JSPROP_ENUMERATE},
345  {"z", 2, JSPROP_ENUMERATE},
346  {"w", 3, JSPROP_ENUMERATE},
347  {0}
348 };
349 
350 JSFunctionSpec (SFVec4fFunctions)[] = {
351  /* do not know what functions to use here */
352  {"toString", SFVec4fToString, 0},
353  {"assign", SFVec4fAssign, 0},
354  {0}
355 };
356 
357 
358 JSClass SFVec4dClass = {
359  "SFVec4d",
360  JSCLASS_HAS_PRIVATE,
361  JS_PropertyStub,
362  JS_PropertyStub,
363  SFVec4dGetProperty,
364  SFVec4dSetProperty,
365  JS_EnumerateStub,
366  JS_ResolveStub,
367  JS_ConvertStub,
368  JS_MY_Finalize
369 };
370 
371 JSPropertySpec (SFVec4dProperties)[] = {
372  {"x", 0, JSPROP_ENUMERATE},
373  {"y", 1, JSPROP_ENUMERATE},
374  {"z", 2, JSPROP_ENUMERATE},
375  {"w", 3, JSPROP_ENUMERATE},
376  {0}
377 };
378 
379 JSFunctionSpec (SFVec4dFunctions)[] = {
380  /* do not know what functions to use here */
381  {"toString", SFVec4dToString, 0},
382  {"assign", SFVec4dAssign, 0},
383  {0}
384 };
385 
386 
387 
388 
389 JSClass SFVec3fClass = {
390  "SFVec3f",
391  JSCLASS_HAS_PRIVATE,
392  JS_PropertyStub,
393  JS_PropertyStub,
394  SFVec3fGetProperty,
395  SFVec3fSetProperty,
396  JS_EnumerateStub,
397  JS_ResolveStub,
398  JS_ConvertStub,
399  JS_MY_Finalize
400 };
401 
402 JSPropertySpec (SFVec3fProperties)[] = {
403  {"x", 0, JSPROP_ENUMERATE},
404  {"y", 1, JSPROP_ENUMERATE},
405  {"z", 2, JSPROP_ENUMERATE},
406  {0}
407 };
408 
409 JSFunctionSpec (SFVec3fFunctions)[] = {
410  {"add", SFVec3fAdd, 0},
411  {"cross", SFVec3fCross, 0},
412  {"divide", SFVec3fDivide, 0},
413  {"dot", SFVec3fDot, 0},
414  {"length", SFVec3fLength, 0},
415  {"multiply", SFVec3fMultiply, 0},
416  {"negate", SFVec3fNegate, 0},
417  {"normalize", SFVec3fNormalize, 0},
418  {"subtract", SFVec3fSubtract, 0},
419  {"toString", SFVec3fToString, 0},
420  {"assign", SFVec3fAssign, 0},
421  {0}
422 };
423 
424 
425 JSClass SFVec3dClass = {
426  "SFVec3d",
427  JSCLASS_HAS_PRIVATE,
428  JS_PropertyStub,
429  JS_PropertyStub,
430  SFVec3dGetProperty,
431  SFVec3dSetProperty,
432  JS_EnumerateStub,
433  JS_ResolveStub,
434  JS_ConvertStub,
435  JS_MY_Finalize
436 };
437 
438 JSPropertySpec (SFVec3dProperties)[] = {
439  {"x", 0, JSPROP_ENUMERATE},
440  {"y", 1, JSPROP_ENUMERATE},
441  {"z", 2, JSPROP_ENUMERATE},
442  {0}
443 };
444 
445 JSFunctionSpec (SFVec3dFunctions)[] = {
446  {"add", SFVec3dAdd, 0},
447  {"cross", SFVec3dCross, 0},
448  {"divide", SFVec3dDivide, 0},
449  {"dot", SFVec3dDot, 0},
450  {"length", SFVec3dLength, 0},
451  {"multiply", SFVec3dMultiply, 0},
452  {"negate", SFVec3dNegate, 0},
453  {"normalize", SFVec3dNormalize, 0},
454  {"subtract", SFVec3dSubtract, 0},
455  {"toString", SFVec3dToString, 0},
456  {"assign", SFVec3dAssign, 0},
457  {0}
458 };
459 
460 JSClass MFColorClass = {
461  "MFColor",
462  JSCLASS_HAS_PRIVATE,
463  MFColorAddProperty,
464  JS_PropertyStub,
465  MFColorGetProperty,
466  MFColorSetProperty,
467  JS_EnumerateStub,
468  JS_ResolveStub,
469  JS_ConvertStub,
470  JS_MY_Finalize
471 };
472 
473 JSFunctionSpec (MFColorFunctions)[] = {
474  {"toString", MFColorToString, 0},
475  {"assign", MFColorAssign, 0},
476  {0}
477 };
478 
479 
480 
481 JSClass MFFloatClass = {
482  "MFFloat",
483  JSCLASS_HAS_PRIVATE,
484  MFFloatAddProperty,
485  JS_PropertyStub,
486  MFFloatGetProperty,
487  MFFloatSetProperty,
488  JS_EnumerateStub,
489  JS_ResolveStub,
490  JS_ConvertStub,
491  JS_MY_Finalize
492 };
493 
494 JSFunctionSpec (MFFloatFunctions)[] = {
495  {"toString", MFFloatToString, 0},
496  {"assign", MFFloatAssign, 0},
497  {0}
498 };
499 
500 
501 
502 JSClass MFInt32Class = {
503  "MFInt32",
504  JSCLASS_HAS_PRIVATE,
505  MFInt32AddProperty,
506  JS_PropertyStub,
507  MFInt32GetProperty,
508  MFInt32SetProperty,
509  JS_EnumerateStub,
510  JS_ResolveStub,
511  JS_ConvertStub,
512  JS_MY_Finalize
513 };
514 
515 JSFunctionSpec (MFInt32Functions)[] = {
516  {"toString", MFInt32ToString, 0},
517  {"assign", MFInt32Assign, 0},
518  {0}
519 };
520 
521 #ifdef NEWCLASSES
522 JSClass MFBoolClass = {
523  "MFBool",
524  JSCLASS_HAS_PRIVATE,
525  MFBoolAddProperty,
526  JS_PropertyStub,
527  MFBoolGetProperty,
528  MFBoolSetProperty,
529  JS_EnumerateStub,
530  JS_ResolveStub,
531  JS_ConvertStub,
532  JS_MY_Finalize
533 };
534 
535 JSFunctionSpec (MFBoolFunctions)[] = {
536  {"toString", MFBoolToString, 0},
537  {"assign", MFBoolAssign, 0},
538  {0}
539 };
540 
541 
542 JSClass MFDoubleClass = {
543  "MFDouble",
544  JSCLASS_HAS_PRIVATE,
545  MFDoubleAddProperty,
546  JS_PropertyStub,
547  MFDoubleGetProperty,
548  MFDoubleSetProperty,
549  JS_EnumerateStub,
550  JS_ResolveStub,
551  JS_ConvertStub,
552  JS_MY_Finalize
553 };
554 
555 JSFunctionSpec (MFDoubleFunctions)[] = {
556  {"toString", MFDoubleToString, 0},
557  {"assign", MFDoubleAssign, 0},
558  {0}
559 };
560 
561 
562 
563 JSClass MFImageClass = {
564  "MFImage",
565  JSCLASS_HAS_PRIVATE,
566  MFImageAddProperty,
567  JS_PropertyStub,
568  MFImageGetProperty,
569  MFImageSetProperty,
570  JS_EnumerateStub,
571  JS_ResolveStub,
572  JS_ConvertStub,
573  JS_MY_Finalize
574 };
575 
576 JSFunctionSpec (MFImageFunctions)[] = {
577  {"toString", MFImageToString, 0},
578  {"assign", MFImageAssign, 0},
579  {0}
580 };
581 
582 
583 JSClass MFVec2dClass = {
584  "MFVec2d",
585  JSCLASS_HAS_PRIVATE,
586  MFVec2dAddProperty,
587  JS_PropertyStub,
588  MFVec2dGetProperty,
589  MFVec2dSetProperty,
590  JS_EnumerateStub,
591  JS_ResolveStub,
592  JS_ConvertStub,
593  JS_MY_Finalize
594 };
595 
596 JSFunctionSpec (MFVec2dFunctions)[] = {
597  {"toString", MFVec2dToString, 0},
598  {"assign", MFVec2dAssign, 0},
599  {0}
600 };
601 
602 JSClass MFVec3dClass = {
603  "MFVec3d",
604  JSCLASS_HAS_PRIVATE,
605  MFVec3dAddProperty,
606  JS_PropertyStub,
607  MFVec3dGetProperty,
608  MFVec3dSetProperty,
609  JS_EnumerateStub,
610  JS_ResolveStub,
611  JS_ConvertStub,
612  JS_MY_Finalize
613 };
614 
615 JSFunctionSpec (MFVec3dFunctions)[] = {
616  {"toString", MFVec3dToString, 0},
617  {"assign", MFVec3dAssign, 0},
618  {0}
619 };
620 
621 #endif /* NEWCLASSES */
622 
623 JSClass MFNodeClass = {
624  "MFNode",
625  JSCLASS_HAS_PRIVATE,
626  MFNodeAddProperty,
627  JS_PropertyStub,
628  MFNodeGetProperty,
629  MFNodeSetProperty,
630  JS_EnumerateStub,
631  JS_ResolveStub,
632  JS_ConvertStub,
633  JS_MY_Finalize
634 };
635 
636 JSFunctionSpec (MFNodeFunctions)[] = {
637  {"toString", MFNodeToString, 0},
638  {"assign", MFNodeAssign, 0},
639  {0}
640 };
641 
642 
643 
644 JSClass MFRotationClass = {
645  "MFRotation",
646  JSCLASS_HAS_PRIVATE,
647  MFRotationAddProperty,
648  JS_PropertyStub,
649  MFRotationGetProperty,
650  MFRotationSetProperty,
651  JS_EnumerateStub,
652  JS_ResolveStub,
653  JS_ConvertStub,
654  JS_MY_Finalize
655 };
656 
657 JSFunctionSpec (MFRotationFunctions)[] = {
658  {"toString", MFRotationToString, 0},
659  {"assign", MFRotationAssign, 0},
660  {0}
661 };
662 
663 
664 
665 /* this one is not static. */
666 JSClass MFStringClass = {
667  "MFString",
668  JSCLASS_HAS_PRIVATE,
669  MFStringAddProperty,
670  MFStringDeleteProperty, /* JS_PropertyStub, */
671  MFStringGetProperty,
672  MFStringSetProperty,
673  MFStringEnumerateProperty, /* JS_EnumerateStub, */
674  MFStringResolveProperty, /* JS_ResolveStub, */
675  MFStringConvertProperty, /* JS_ConvertStub, */
676  JS_MY_Finalize
677 };
678 
679 JSFunctionSpec (MFStringFunctions)[] = {
680  {"toString", MFStringToString, 0},
681  {"assign", MFStringAssign, 0},
682  {0}
683 };
684 
685 
686 
687 JSClass MFTimeClass = {
688  "MFTime",
689  JSCLASS_HAS_PRIVATE,
690  MFTimeAddProperty,
691  JS_PropertyStub,
692  MFTimeGetProperty,
693  MFTimeSetProperty,
694  JS_EnumerateStub,
695  JS_ResolveStub,
696  JS_ConvertStub,
697  JS_MY_Finalize
698 };
699 
700 JSPropertySpec (MFTimeProperties)[] = {
701  {0}
702 };
703 
704 JSFunctionSpec (MFTimeFunctions)[] = {
705  {"toString", MFTimeToString, 0},
706  {"assign", MFTimeAssign, 0},
707  {0}
708 };
709 
710 
711 
712 JSClass MFVec2fClass = {
713  "MFVec2f",
714  JSCLASS_HAS_PRIVATE,
715  MFVec2fAddProperty,
716  JS_PropertyStub,
717  MFVec2fGetProperty,
718  MFVec2fSetProperty,
719  JS_EnumerateStub,
720  JS_ResolveStub,
721  JS_ConvertStub,
722  JS_MY_Finalize
723 };
724 
725 JSFunctionSpec (MFVec2fFunctions)[] = {
726  {"toString", MFVec2fToString, 0},
727  {"assign", MFVec2fAssign, 0},
728  {0}
729 };
730 
731 
732 
733 JSClass MFVec3fClass = {
734  "MFVec3f",
735  JSCLASS_HAS_PRIVATE,
736  MFVec3fAddProperty,
737  JS_PropertyStub,
738  MFVec3fGetProperty,
739  MFVec3fSetProperty,
740  JS_EnumerateStub,
741  JS_ResolveStub,
742  JS_ConvertStub,
743  JS_MY_Finalize
744 };
745 
746 JSFunctionSpec (MFVec3fFunctions)[] = {
747  {"toString", MFVec3fToString, 0},
748  {"assign", MFVec3fAssign, 0},
749  {0}
750 };
751 
752 JSObject *proto_VrmlMatrix;
753 
754 JSClass VrmlMatrixClass = {
755  "VrmlMatrix",
756  JSCLASS_HAS_PRIVATE,
757  VrmlMatrixAddProperty,
758  JS_PropertyStub,
759  VrmlMatrixGetProperty,
760  VrmlMatrixSetProperty,
761  JS_EnumerateStub,
762  JS_ResolveStub,
763  JS_ConvertStub,
764  JS_MY_Finalize
765 };
766 
767 JSFunctionSpec (VrmlMatrixFunctions)[] = {
768  {"setTransform", VrmlMatrixsetTransform, 0},
769  {"getTransform", VrmlMatrixgetTransform, 0},
770  {"inverse", VrmlMatrixinverse, 0},
771  {"transpose", VrmlMatrixtranspose, 0},
772  {"multLeft", VrmlMatrixmultLeft, 0},
773  {"multRight", VrmlMatrixmultRight, 0},
774  {"multVecMatrix", VrmlMatrixmultVecMatrix, 0},
775  {"multMatrixVec", VrmlMatrixmultMatrixVec, 0},
776  {"toString", VrmlMatrixToString, 0},
777  {"assign", VrmlMatrixAssign, 0},
778  {0}
779 };
780 
781 
782 #ifdef NEWCLASSES
783 
784 JSObject *proto_X3DMatrix3;
785 
786 JSClass X3DMatrix3Class = {
787  "X3DMatrix3",
788  JSCLASS_HAS_PRIVATE,
789  X3DMatrix3AddProperty,
790  JS_PropertyStub,
791  X3DMatrix3GetProperty,
792  X3DMatrix3SetProperty,
793  JS_EnumerateStub,
794  JS_ResolveStub,
795  JS_ConvertStub,
796  JS_MY_Finalize
797 };
798 
799 JSFunctionSpec (X3DMatrix3Functions)[] = {
800  {"getTransform", X3DMatrix3getTransform, 0},
801  {"setTransform", X3DMatrix3setTransform, 0},
802  {"inverse", X3DMatrix3inverse, 0},
803  {"transpose", X3DMatrix3transpose, 0},
804  {"multLeft", X3DMatrix3multLeft, 0},
805  {"multRight", X3DMatrix3multRight, 0},
806  {"multVecMatrix", X3DMatrix3multVecMatrix, 0},
807  {"multMatrixVec", X3DMatrix3multMatrixVec, 0},
808  {"toString", X3DMatrix3ToString, 0},
809  {"assign", X3DMatrix3Assign, 0},
810  {0}
811 };
812 
813 
814 JSObject *proto_X3DMatrix4;
815 
816 JSClass X3DMatrix4Class = {
817  "X3DMatrix4",
818  JSCLASS_HAS_PRIVATE,
819  X3DMatrix4AddProperty,
820  JS_PropertyStub,
821  X3DMatrix4GetProperty,
822  X3DMatrix4SetProperty,
823  JS_EnumerateStub,
824  JS_ResolveStub,
825  JS_ConvertStub,
826  JS_MY_Finalize
827 };
828 
829 JSFunctionSpec (X3DMatrix4Functions)[] = {
830  {"toString", X3DMatrix4ToString, 0},
831  {"assign", X3DMatrix4Assign, 0},
832  {"getTransform", X3DMatrix4getTransform, 0},
833  {"setTransform", X3DMatrix4setTransform, 0},
834  {"inverse", X3DMatrix4inverse, 0},
835  {"transpose", X3DMatrix4transpose, 0},
836  {"multLeft", X3DMatrix4multLeft, 0},
837  {"multRight", X3DMatrix4multRight, 0},
838  {"multVecMatrix", X3DMatrix4multVecMatrix, 0},
839  {"multMatrixVec", X3DMatrix4multMatrixVec, 0},
840  {0}
841 };
842 
843 #endif /* NEWCLASSES */
844 
845 //#define MFFloatProperties NULL
846 //#define MFInt32Properties NULL
847 //#define MFColorProperties NULL
848 //#define MFVec2fProperties NULL
849 //#define MFVec3fProperties NULL
850 //#define MFRotationProperties NULL
851 //#define MFNodeProperties NULL
852 //#define MFStringProperties NULL
853 //#define VrmlMatrixProperties NULL
854 
855 
857  JSClass *class;
858  void *constr;
859  void *Functions;
860  void *Properties;
861  char *id;
862 };
863 
864 
865 struct JSLoadPropElement (JSLoadProps) [] = {
866 #ifdef NEWCLASSES
867  { &MFVec2dClass, MFVec2dConstr, &MFVec2dFunctions, &MFVec2dProperties, "MFVec2dClass"},
868  { &MFVec3dClass, MFVec3dConstr, &MFVec3dFunctions, &MFVec3dProperties, "MFVec3dClass"},
869  { &SFVec2dClass, SFVec2dConstr, &SFVec2dFunctions, &SFVec2dProperties, "SFVec2dClass"},
870  { &MFBoolClass, MFBoolConstr, &MFBoolFunctions, &MFBoolProperties, "MFBoolClass"},
871  { &MFDoubleClass, MFDoubleConstr, &MFDoubleFunctions, &MFDoubleProperties, "MFDoubleClass"},
872  { &MFImageClass, MFImageConstr, &MFImageFunctions, &MFImageProperties, "MFImageClass"},
873  { &X3DMatrix3Class, X3DMatrix3Constr, &X3DMatrix3Functions, &X3DMatrix3Properties, "X3DMatrix3Class"},
874  { &X4DMatrix4Class, X4DMatrix4Constr, &X4DMatrix4Functions, &X4DMatrix4Properties, "X4DMatrix4Class"},
875 #endif /* NEWCLASSES */
876 
877  { &SFColorClass, SFColorConstr, &SFColorFunctions, &SFColorProperties, "SFColorClass"},
878  { &SFVec2fClass, SFVec2fConstr, &SFVec2fFunctions, &SFVec2fProperties, "SFVec2fClass"},
879  { &SFColorRGBAClass, SFColorRGBAConstr, &SFColorRGBAFunctions, &SFColorRGBAProperties, "SFColorRGBAClass"},
880  { &SFVec3fClass, SFVec3fConstr, &SFVec3fFunctions, &SFVec3fProperties, "SFVec3fClass"},
881  { &SFVec3dClass, SFVec3dConstr, &SFVec3dFunctions, &SFVec3dProperties, "SFVec3dClass"},
882  { &SFRotationClass, SFRotationConstr, &SFRotationFunctions, &SFRotationProperties, "SFRotationClass"},
883  { &SFNodeClass, SFNodeConstr, &SFNodeFunctions, &SFNodeProperties, "SFNodeClass"},
884  { &MFFloatClass, MFFloatConstr, &MFFloatFunctions, NULL, "MFFloatClass"},
885  { &MFTimeClass, MFTimeConstr, &MFTimeFunctions, &MFTimeProperties, "MFTimeClass"},
886  { &MFInt32Class, MFInt32Constr, &MFInt32Functions, NULL, "MFInt32Class"},
887  { &MFColorClass, MFColorConstr, &MFColorFunctions, NULL, "MFColorClass"},
888  { &MFVec2fClass, MFVec2fConstr, &MFVec2fFunctions, NULL, "MFVec2fClass"},
889 
890  { &MFVec3fClass, MFVec3fConstr, &MFVec3fFunctions, NULL, "MFVec3fClass"},
891 
892  { &SFVec4fClass, SFVec4fConstr, &SFVec4fFunctions, &SFVec4fProperties, "SFVec4fClass"},
893  { &SFVec4dClass, SFVec4dConstr, &SFVec4dFunctions, &SFVec4dProperties, "SFVec4dClass"},
894 
895  { &MFRotationClass, MFRotationConstr, &MFRotationFunctions, NULL, "MFRotationClass"},
896  { &MFNodeClass, MFNodeConstr, &MFNodeFunctions, NULL, "MFNodeClass"},
897  { &SFImageClass, SFImageConstr, &SFImageFunctions, &SFImageProperties, "SFImageClass"},
898 /* { &MFColorRGBAClass, MFColorRGBAConstr, &MFColorRGBAFunctions, &MFColorRGBAProperties, "MFColorRGBAClass"},*/
899  { &MFStringClass, MFStringConstr, &MFStringFunctions, NULL, "MFStringClass"},
900  { &VrmlMatrixClass, VrmlMatrixConstr, &VrmlMatrixFunctions, NULL, "VrmlMatrixClass"},
901  {0}
902 };
903 
904 
905 
906 /* return the string representation of this class */
907 const char *classToString(JSClass *myClass) {
908 
909  int i;
910  i = 0;
911 
912  /* printf ("class to string starting\n"); */
913 
914  /* ok - this is an object, lets find out what class it is */
915  while (JSLoadProps[i].class != NULL) {
916  if (JSLoadProps[i].class == myClass) {
917  /* printf ("found it! it is a %s\n",JSLoadProps[i].id); */
918  return JSLoadProps[i].id;
919  }
920  i++;
921  }
922  return "class unknown";
923 }
924 
925 /* try and print what an element is in case of error */
926 void printJSNodeType (JSContext *context, JSObject *myobj) {
927  int i;
928  i=0;
929 
930  #ifdef JSVRMLCLASSESVERBOSE
931  printf ("printJSNodeType, obj pointer is %p\n",myobj);
932  #endif
933 
934  /* ok - this is an object, lets find out what class it is */
935  while (JSLoadProps[i].class != NULL) {
936  if (JS_InstanceOf(context, myobj, JSLoadProps[i].class, NULL)) {
937  printf ("'%s'\n",JSLoadProps[i].id);
938  return;
939  }
940  i++;
941  }
942  printf ("'unknown class'\n");
943 }
944 
945 /* do a simple copy; from, to, and count */
946 JSBool _simplecopyElements (JSContext *cx,
947  JSObject *fromObj,
948  JSObject *toObj,
949  int count,
950  int type) {
951  int i;
952  jsval val;
953  double dd;
954  int ii;
955 
956 
957  #ifdef JSVRMLCLASSESVERBOSE
958  printf ("simpleCopyElements, count %d\n",count);
959  #endif
960 
961  for (i = 0; i < count; i++) {
962  if (!JS_GetElement(cx, fromObj, (jsint) i, &val)) {
963  printf( "failed in get %d index %d.\n",type, i);
964  return JS_FALSE;
965  }
966  /* ensure that the types are ok */
967  if ((type == FIELDTYPE_SFFloat) || (type == FIELDTYPE_SFTime)) {
968  /* if we expect a double, and we have an INT... */
969  if (JSVAL_IS_INT(val)) {
970  ii = JSVAL_TO_INT(val);
971  dd = (double) ii;
972  /* printf ("integer is %d doulbe %lf\n",ii,dd); */
973  if (JS_NewNumberValue(cx,dd,&val) == JS_FALSE) {
974  printf( "JS_NewNumberValue failed for %f in simplecopyelements.\n",dd);
975  return JS_FALSE;
976  }
977  }
978  }
979 
980  /*
981  if (JSVAL_IS_OBJECT(val)) printf ("sc, element %d is an OBJECT\n",i);
982  if (JSVAL_IS_STRING(val)) printf ("sc, element %d is an STRING\n",i);
983  if (JSVAL_IS_NUMBER(val)) printf ("sc, element %d is an NUMBER\n",i);
984  if (JSVAL_IS_DOUBLE(val)) printf ("sc, element %d is an DOUBLE\n",i);
985  if (JSVAL_IS_INT(val)) printf ("sc, element %d is an INT\n",i);
986  */
987 
988  if (!JS_SetElement(cx, toObj, (jsint) i, &val)) {
989  printf( "failed in set %d index %d.\n", type, i);
990  return JS_FALSE;
991  }
992  }
993  return JS_TRUE;
994 }
995 
996 
997 /* make a standard assignment for MF variables */
998 JSBool _standardMFAssign(JSContext *cx,
999  JSObject *obj,
1000  uintN argc,
1001  jsval *argv,
1002  jsval *rval,
1003  JSClass *myClass,
1004  int type) {
1005 
1006  JSObject *_from_obj;
1007  jsval val;
1008  int32 len;
1009  SFImageNative *ptr;
1010 #if JS_VERSION < 185
1011  char *_id_str;
1012 #else
1013  JSString *_id_jsstr;
1014 #endif
1015 
1016  if (!JS_InstanceOf(cx, obj, myClass, argv)) {
1017  printf("JS_InstanceOf failed for fieldType %s.\n",stringFieldtypeType(type));
1018  return JS_FALSE;
1019  }
1020 
1021 #if JS_VERSION < 185
1022  if (!JS_ConvertArguments(cx, argc, argv, "o s", &_from_obj, &_id_str)) {
1023 #else
1024  if (!JS_ConvertArguments(cx, argc, argv, "oS", &_from_obj, &_id_jsstr)) {
1025 #endif
1026  printf("JS_ConvertArguments failed in %s.\n",stringFieldtypeType(type));
1027  return JS_FALSE;
1028  }
1029 
1030 
1031  if (!JS_InstanceOf(cx, _from_obj, myClass, argv)) {
1032  printf("JS_InstanceOf failed for fieldType %s.\n",stringFieldtypeType(type));
1033  return JS_FALSE;
1034  }
1035 
1036  if (!JS_GetProperty(cx, _from_obj, MF_LENGTH_FIELD, &val)) {
1037  printf("JS_GetProperty failed for \"%s\" in %s.\n",MF_LENGTH_FIELD,stringFieldtypeType(type));
1038  return JS_FALSE;
1039  }
1040 
1041  if (!JS_SetProperty(cx, obj, MF_LENGTH_FIELD, &val)) {
1042  printf("JS_SetProperty failed for \"%s\" in %s\n",MF_LENGTH_FIELD,stringFieldtypeType(type));
1043  return JS_FALSE;
1044  }
1045 
1046  len = JSVAL_TO_INT(val);
1047 
1048  #ifdef JSVRMLCLASSESVERBOSE
1049 #if JS_VERSION >= 185
1050  _id_str = JS_EncodeString(cx,_id_jsstr);
1051 #endif
1052  printf("StandardMFAssign %s: obj = %p, id = \"%s\", from = %p, len = %d\n",stringFieldtypeType(type),
1053  obj, _id_str, _from_obj, len);
1054 #if JS_VERSION >= 185
1055  JS_free(cx,_id_str);
1056 #endif
1057  #endif
1058 
1059  /* copyElements */
1060  *rval = OBJECT_TO_JSVAL(obj);
1061 
1062  /* SF* values that use this routine - check if we need to set valueChanged in private area */
1063 
1064  if (type == FIELDTYPE_SFImage) {
1065  if ((ptr = (SFImageNative *)JS_GetPrivate(cx, obj)) == NULL) {
1066  printf( "JS_GetPrivate failed in standard MF assign.\n");
1067  return JS_FALSE;
1068  }
1069  ptr->valueChanged = 1;
1070  }
1071 
1072  return _simplecopyElements(cx, _from_obj, obj, len,type);
1073 }
1074 
1075 /* standardized GetProperty for MF's */
1076 JSBool
1077 _standardMFGetProperty(JSContext *cx,
1078  JSObject *obj,
1079 #if JS_VERSION < 185
1080  jsval id,
1081 #else
1082  jsid iid,
1083 #endif
1084  jsval *vp,
1085  char *makeNewElement,
1086  int type) {
1087 
1088  int32 _length, _index;
1089  jsval _length_val;
1090 
1091  /* in case we need to run makeNewElement*/
1092  int newElemenLen;
1093  jsval newEle;
1094 #if JS_VERSION >= 185
1095  jsval id;
1096  if (!JS_IdToValue(cx,iid,&id)) {
1097  printf( "JS_IdToValue failed\n");
1098  return JS_FALSE;
1099  }
1100 #endif
1101 
1102  #ifdef JSVRMLCLASSESVERBOSE
1103  printf ("_standardMFGetProperty starting for type %d\n",type);
1104  printJSNodeType (cx,obj);
1105  #endif
1106 
1107  if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &_length_val)) {
1108  printf( "JS_GetProperty failed for \"%s\" in %d.\n",MF_LENGTH_FIELD,type);
1109  return JS_FALSE;
1110  }
1111 
1112  _length = JSVAL_TO_INT(_length_val);
1113  #ifdef JSVRMLCLASSESVERBOSE
1114  printf ("standarg get property, len %d\n",_length);
1115  #endif
1116 
1117  if (JSVAL_IS_INT(id)) {
1118  _index = JSVAL_TO_INT(id);
1119  #ifdef JSVRMLCLASSESVERBOSE
1120  printf ("standard get property, index requested %d length is %d\n",_index,_length);
1121  #endif
1122 
1123  if (_index >= _length) {
1124  #ifdef JSVRMLCLASSESVERBOSE
1125  printf ("\n\nconstructing new object\n");
1126  #endif
1127  /* we were making this with C calls, but it would fail with a*/
1128  /* segfault; so, now, we run a script to do it.*/
1129 
1130 
1131  newElemenLen = (int)strlen(makeNewElement);
1132 
1133  if (!JS_EvaluateScript(cx, obj, makeNewElement, newElemenLen,
1134  FNAME_STUB, LINENO_STUB, &newEle)) {
1135  ConsoleMessage ("standardMFGetProperty: JS_EvaluateScript failed for %s", makeNewElement);
1136  return JS_FALSE;
1137  }
1138 
1139 /* error? newEle is already a jsval
1140  *vp = OBJECT_TO_JSVAL(newEle); */
1141  *vp = newEle;
1142 
1143  #ifdef JSVRMLCLASSESVERBOSE
1144  printf ("defining element %d now... is %d %#x\n",_index,(int)*vp,(unsigned int)*vp);
1145  #endif
1146 
1147  if (!JS_DefineElement(cx, obj, (jsint) _index, *vp,
1148  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB8,
1149  JSPROP_ENUMERATE)) {
1150  printf( "JS_DefineElement failed in %d.\n",type);
1151  return JS_FALSE;
1152  }
1153 
1154  if (!doMFSetProperty(cx,obj,
1155 #if JS_VERSION < 185
1156  id,
1157 #else
1158  iid,
1159 #endif
1160  vp,type)) {
1161  printf ("wow, cant assign property\n");
1162  }
1163  }
1164  #ifdef JSVRMLCLASSESVERBOSE
1165  printf ("object might already have this index\n");
1166  #endif
1167  if (!JS_LookupElement(cx, obj, _index, vp)) {
1168  printf( "JS_LookupElement failed in %d.\n",type);
1169  return JS_FALSE;
1170  }
1171  if (JSVAL_IS_NULL(*vp)) {
1172  printf( "warning: %d: obj = %p, jsval = %d does not exist!\n",type,
1173  obj, (int) _index);
1174  return JS_TRUE;
1175  }
1176  } else if (JSVAL_IS_STRING(id)) {
1177  #ifdef JSVRMLCLASSESVERBOSE
1178  JSString *_str;
1179  char * asciiStr;
1180 
1181  printf ("HAVE STRING HERE!\n");
1182  _str = JS_ValueToString(cx, id);
1183 #if JS_VERSION < 185
1184  asciiStr = JS_GetStringBytes(_str);
1185 #else
1186  asciiStr = JS_EncodeString(cx,_str);
1187 #endif
1188  printf ("we have as a parameter :%s:\n",asciiStr);
1189 #if JS_VERSION >= 185
1190  JS_free(cx,asciiStr);
1191 #endif
1192  #endif
1193 
1194  }
1195  #ifdef JSVRMLCLASSESVERBOSE
1196  printf ("_standardMFGetProperty finishing; element is %u\n",(unsigned int)*vp);
1197  #endif
1198 
1199  return JS_TRUE;
1200 }
1201 
1202 JSBool doMFToString(JSContext *cx, JSObject *obj, const char *className, jsval *rval)
1203 {
1204  JSString *_str, *_tmpStr;
1205  jsval _v;
1206  char *_buff, *_tmp_valStr, *_tmp_buff;
1207  const char *_empty_array = "[]";
1208  int len = 0, i;
1209  size_t buff_size = 0, tmp_valStr_len = 0, tmp_buff_len = 0;
1210  JSBool isString = JS_FALSE;
1211  JSBool isImage = JS_FALSE;
1212 #if JS_VERSION >= 185
1213  JSBool encodedTmpValstr = JS_FALSE;
1214 #endif
1215 
1216  if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &_v)) {
1217  printf( "JS_GetProperty failed for \"%s\" in doMFToString for %s.\n",
1218  MF_LENGTH_FIELD,className);
1219  return JS_FALSE;
1220  }
1221  len = JSVAL_TO_INT(_v);
1222 
1223  #ifdef JSVRMLCLASSESVERBOSE
1224  printf ("doMFToString, obj %p len %d\n",obj, len);
1225  printJSNodeType (cx,obj);
1226  #endif
1227 
1228  if (len == 0) {
1229  _str = JS_NewStringCopyZ(cx, _empty_array);
1230  *rval = STRING_TO_JSVAL(_str);
1231  #ifdef JSVRMLCLASSESVERBOSE
1232  printf ("doMFToString, len is zero, returning JS_TRUE, and %d\n",(int)*rval);
1233  #endif
1234  return JS_TRUE;
1235  }
1236 
1237  if (!strcmp(className, "MFString")) {
1238  isString = JS_TRUE;
1239  }
1240  if (!strcmp(className, "SFImage")) {
1241  isImage = JS_TRUE;
1242  #ifdef JSVRMLCLASSESVERBOSE
1243  printf ("doMFToString - doing an image\n");
1244  #endif
1245  }
1246 
1247  buff_size = LARGESTRING;
1248  _buff = MALLOC(char *, buff_size * sizeof(char));
1249  memset(_buff, 0, buff_size);
1250 
1251  for (i = 0; i < len; i++) {
1252  if (!JS_GetElement(cx, obj, i, &_v)) {
1253  printf("warning, no element %d of %d in doMFToString for a type of %s.\n",
1254  i, len,className);
1255  _tmp_valStr = "NULL";
1256  } else {
1257 
1258  #ifdef JSVRMLCLASSESVERBOSE
1259  if (JSVAL_IS_NUMBER(_v)) printf ("is a number\n");
1260  if (JSVAL_IS_INT(_v)) printf ("is an integer\n");
1261  if (JSVAL_IS_DOUBLE(_v)) printf ("is an double\n");
1262  #endif
1263 
1264  _tmpStr = JS_ValueToString(cx, _v);
1265  if (_tmpStr==NULL) {
1266  _tmp_valStr = "NULL";
1267  } else {
1268 #if JS_VERSION < 185
1269  _tmp_valStr = JS_GetStringBytes(_tmpStr);
1270 #else
1271  _tmp_valStr = JS_EncodeString(cx,_tmpStr);
1272  encodedTmpValstr = JS_TRUE;
1273 #endif
1274  }
1275  }
1276 
1277  #ifdef JSVRMLCLASSESVERBOSE
1278  printf ("doMFToString, element %d is %#x, string %s\n",i,(unsigned int)_v,_tmp_valStr);
1279 
1280  #endif
1281  tmp_valStr_len = strlen(_tmp_valStr) + 1;
1282  tmp_buff_len = strlen(_buff);
1283 
1284  if ((buff_size - (tmp_buff_len + 1)) < (tmp_valStr_len + 1)) {
1285  buff_size += LARGESTRING;
1286  if ((_buff =
1287  (char *)
1288  JS_realloc(cx, _buff, buff_size * sizeof(char *)))
1289  == NULL) {
1290  printf( "JS_realloc failed for %d in doMFToString for %s.\n", i, className);
1291 #if JS_VERSION >= 185
1292  if (encodedTmpValstr == JS_TRUE) JS_free(cx,_tmp_valStr);
1293 #endif
1294  return JS_FALSE;
1295  }
1296  }
1297 
1298  if (len == 1) {
1299  if (isString) {
1300  sprintf(_buff, "[ \"%.*s\" ]", (int) tmp_valStr_len, _tmp_valStr);
1301  } else {
1302  sprintf(_buff, "[ %.*s ]", (int) tmp_valStr_len, _tmp_valStr);
1303  }
1304 #if JS_VERSION >= 185
1305  if (encodedTmpValstr == JS_TRUE) {
1306  JS_free(cx,_tmp_valStr);
1307  encodedTmpValstr = JS_FALSE;
1308  }
1309 #endif
1310  break;
1311  }
1312 
1313  _tmp_buff = MALLOC(char *, (tmp_buff_len + 1) * sizeof(char));
1314  memset(_tmp_buff, 0, tmp_buff_len + 1);
1315  memmove(_tmp_buff, _buff, tmp_buff_len);
1316  memset(_buff, 0, buff_size);
1317 
1318  if (i == 0 && len > 1) {
1319  if (isString) {
1320  sprintf(_buff, "[ \"%.*s\"",
1321  (int) tmp_valStr_len, _tmp_valStr);
1322  } else {
1323  sprintf(_buff, "[ %.*s", (int) tmp_valStr_len, _tmp_valStr);
1324  }
1325  } else if (i == (len - 1)) {
1326  if (isString) {
1327  sprintf(_buff, "%.*s, \"%.*s\" ]",
1328  (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1329  } else {
1330  sprintf(_buff, "%.*s, %.*s ]",
1331  (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1332  }
1333  } else {
1334  if (isString) {
1335  sprintf(_buff, "%.*s, \"%.*s\"",
1336  (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1337  } else {
1338  sprintf(_buff, "%.*s, %.*s",
1339  (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1340  }
1341  }
1342 
1343  FREE_IF_NZ (_tmp_buff);
1344 #if JS_VERSION >= 185
1345  if (encodedTmpValstr == JS_TRUE) {
1346  JS_free(cx,_tmp_valStr);
1347  encodedTmpValstr = JS_FALSE;
1348  }
1349 #endif
1350  }
1351 
1352  /* PixelTextures are stored in Javascript as MFInt32s but in FreeWRL/Perl as an ascii string.
1353  we have to remove some characters to make it into a valid VRML image string */
1354  if (isImage) {
1355  for (i=0; i<(int)strlen(_buff); i++) {
1356  if (_buff[i] == ',') _buff[i]=' ';
1357  if (_buff[i] == ']') _buff[i]=' ';
1358  if (_buff[i] == '[') _buff[i]=' ';
1359  }
1360  }
1361  /* printf ("domfstring, buff %s\n",_buff);*/
1362  _str = JS_NewStringCopyZ(cx, _buff);
1363  *rval = STRING_TO_JSVAL(_str);
1364 
1365  FREE_IF_NZ (_buff);
1366  return JS_TRUE;
1367 }
1368 
1369 JSBool
1370 #if JS_VERSION < 185
1371 doMFAddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, char *name) {
1372 #else
1373 doMFAddProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp, char *name) {
1374 #endif
1375  JSString *str;
1376  jsval v;
1377  char *p;
1378  int len, ind;
1379 #if JS_VERSION >= 185
1380  jsval id;
1381  if (!JS_IdToValue(cx,iid,&id)) {
1382  printf("\tdoMFAddProperty:%s JS_IdToValue failed\n",name);
1383  return JS_FALSE;
1384  }
1385 #endif
1386  len = 0;
1387  ind = JSVAL_TO_INT(id);
1388 
1389  #ifdef JSVRMLCLASSESVERBOSE
1390  printf("\tdoMFAddProperty:%s id %d (%d) NodeType: ",name,(int)id,ind);
1391  printJSNodeType(cx,obj);
1392  #endif
1393 
1394  str = JS_ValueToString(cx, id);
1395 #if JS_VERSION < 185
1396  p = JS_GetStringBytes(str);
1397 #else
1398  p = JS_EncodeString(cx,str);
1399 #endif
1400  #ifdef JSVRMLCLASSESVERBOSE
1401  printf("\tid string %s\n ",p);
1402  #endif
1403 
1404  if (!strcmp(p, MF_LENGTH_FIELD) ||
1405  !strcmp(p, "MF_ECMA_has_changed") ||
1406  !strcmp(p, "_parentField") ||
1407  !strcmp(p, "toString") ||
1408  !strcmp(p, "setTransform") ||
1409  !strcmp(p, "assign") ||
1410  !strcmp(p, "inverse") ||
1411  !strcmp(p, "transpose") ||
1412  !strcmp(p, "multLeft") ||
1413  !strcmp(p, "multRight") ||
1414  !strcmp(p, "multVecMatrix") ||
1415  !strcmp(p, "multMatrixVec") ||
1416  !strcmp(p, "constructor") ||
1417  !strcmp(p, "getTransform")) {
1418  #ifdef JSVRMLCLASSESVERBOSE
1419  printf("property \"%s\" is one of the standard properties. Do nothing.\n", p);
1420  #endif
1421 #if JS_VERSION >= 185
1422  JS_free(cx,p);
1423 #endif
1424  return JS_TRUE;
1425  }
1426 
1427  #ifdef JSVRMLCLASSESVERBOSE
1428  printf("\tdoMFAddProperty:%s id %d NodeType: ",name,(int)id);
1429  printJSNodeType(cx,obj);
1430  printf("\tdoMFAddProperty:%s id %d string %s ",name,(int)id,p);
1431  #endif
1432 #if JS_VERSION >= 185
1433  JS_free(cx,p);
1434 #endif
1435 
1436  if (!JSVAL_IS_INT(id)){
1437  printf( "JSVAL_IS_INT failed for id in doMFAddProperty.\n");
1438  return JS_FALSE;
1439  }
1440  if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &v)) {
1441  printf( "JS_GetProperty failed for \"%s\" in doMFAddProperty.\n",MF_LENGTH_FIELD);
1442  return JS_FALSE;
1443  }
1444 
1445  len = JSVAL_TO_INT(v);
1446  if (ind >= len) {
1447  len = ind + 1;
1448 
1449  #ifdef JSVRMLCLASSESVERBOSE
1450  printf ("doMFAddProperty, len %d ind %d\n",len,ind);
1451  #endif
1452 
1453  v = INT_TO_JSVAL(len);
1454  if (!JS_SetProperty(cx, obj, MF_LENGTH_FIELD, &v)) {
1455  printf( "JS_SetProperty failed for \"%s\" in doMFAddProperty.\n",MF_LENGTH_FIELD);
1456  return JS_FALSE;
1457  }
1458  }
1459 
1460  #ifdef JSVRMLCLASSESVERBOSE
1461  printf("index = %d, length = %d\n", ind, len);
1462  #endif
1463 
1464  return JS_TRUE;
1465 }
1466 
1467 
1468 JSBool
1469 #if JS_VERSION < 185
1470 doMFSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, int type) {
1471 #else
1472 doMFSetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp, int type) {
1473 #endif
1474  JSString *_sstr;
1475  jsval myv;
1476  int i;
1477  double dd;
1478 
1479  int ii;
1480 
1481  JSObject *par;
1482  JSObject *me;
1483  jsval pf;
1484  jsval nf;
1485  char * _cc;
1486  jsid oid;
1487 #if JS_VERSION >= 185
1488  jsval id;
1489  if (!JS_IdToValue(cx,iid,&id)) {
1490  printf("doMFSetProperty, JS_IdToValue failed.\n");
1491  return JS_FALSE;
1492  }
1493 #endif
1494 
1495  #ifdef JSVRMLCLASSESVERBOSE
1496  JSString *_str;
1497  char * _c;
1498  printf ("doMFSetProperty, for object %p, vp %u\n", obj,(unsigned int)*vp);
1499  _str = JS_ValueToString(cx, id);
1500 #if JS_VERSION < 185
1501  _c = JS_GetStringBytes(_str);
1502 #else
1503  _c = JS_EncodeString(cx,_str);
1504 #endif
1505  printf ("id is %s\n",_c);
1506 
1507  _sstr = JS_ValueToString(cx, *vp);
1508  printf ("looking up value for %d %#x object %p\n",(int)*vp,(unsigned int)*vp,obj);
1509 #if JS_VERSION < 185
1510  _cc = JS_GetStringBytes(_sstr);
1511 #else
1512  _cc = JS_EncodeString(cx,_sstr);
1513 #endif
1514  printf("\tdoMFSetProperty:%d: obj = %p, id = %s, vp = %s\n",type,
1515  obj, _c, _cc);
1516  if (JSVAL_IS_OBJECT(*vp)) { printf ("doMFSet, vp is an OBJECT\n"); }
1517  if (JSVAL_IS_PRIMITIVE(*vp)) { printf ("doMFSet, vp is an PRIMITIVE\n"); }
1518 
1519  printf ("parent is a "); printJSNodeType(cx,obj);
1520  /* printf ("jsval is is a "); printJSNodeType(cx,*vp); */
1521 #if JS_VERSION >= 185
1522  JS_free(cx,_c);
1523  JS_free(cx,_cc);
1524 #endif
1525  #endif
1526 
1527  /* should this value be checked for possible conversions */
1528  if (type == FIELDTYPE_MFInt32) {
1529  #ifdef JSVRMLCLASSESVERBOSE
1530  printf ("doMFSetProperty, this should be an int \n");
1531  #endif
1532 
1533  if (!JSVAL_IS_INT(*vp)) {
1534  #ifdef JSVRMLCLASSESVERBOSE
1535  printf ("is NOT an int\n");
1536  #endif
1537 
1538  if (!JS_ValueToInt32(cx, *vp, &i)) {
1539  _sstr = JS_ValueToString(cx, *vp);
1540 #if JS_VERSION < 185
1541  _cc = JS_GetStringBytes(_sstr);
1542 #else
1543  _cc = JS_EncodeString(cx,_sstr);
1544 #endif
1545  printf ("can not convert %s to an integer in doMFAddProperty for type %d\n",_cc,type);
1546 #if JS_VERSION >= 185
1547  JS_free(cx,_cc);
1548 #endif
1549  return JS_FALSE;
1550  }
1551 
1552  *vp = INT_TO_JSVAL(i);
1553  }
1554  } else if ((type == FIELDTYPE_MFFloat) || (type == FIELDTYPE_MFTime)) {
1555  #ifdef JSVRMLCLASSESVERBOSE
1556  printf ("doMFSetProperty - ensure that this is a DOUBLE ");
1557  _sstr = JS_ValueToString(cx, *vp);
1558 #if JS_VERSION < 185
1559  _cc = JS_GetStringBytes(_sstr);
1560 #else
1561  _cc = JS_EncodeString(cx,_sstr);
1562 #endif
1563  printf ("value is %s \n",_cc);
1564 #if JS_VERSION >= 185
1565  JS_free(cx,_cc);
1566 #endif
1567  #endif
1568 
1569  if (JSVAL_IS_INT(*vp)) {
1570  ii = JSVAL_TO_INT(*vp);
1571  dd = (double) ii;
1572  /* printf ("integer is %d doulbe %lf\n",ii,dd); */
1573  if (JS_NewNumberValue(cx,dd,vp) == JS_FALSE) {
1574  printf( "JS_NewNumberValue failed for %f in simplecopyelements.\n",dd);
1575  return JS_FALSE;
1576  }
1577  }
1578  }
1579 
1580  #ifdef JSVRMLCLASSESVERBOSE
1581  printf ("setting changed flag on %p\n",obj);
1582  #endif
1583 
1584  /* is this an MF ECMA type that uses the MF_ECMA_has_changed flag? */
1585  switch (type) {
1586  case FIELDTYPE_MFInt32:
1587  case FIELDTYPE_MFBool:
1588  case FIELDTYPE_MFTime:
1589  case FIELDTYPE_MFFloat:
1590  case FIELDTYPE_MFString: {
1591  SET_MF_ECMA_HAS_CHANGED
1592  break;
1593  }
1594  default: {}
1595  }
1596 
1597 
1598  if (JSVAL_IS_INT(id)) {
1599  /* save this element into the parent at index */
1600 
1601  #ifdef JSVRMLCLASSESVERBOSE
1602  printf ("saving element %d\n",JSVAL_TO_INT(id));
1603  #endif
1604 
1605  if (!JS_DefineElement(cx, obj, JSVAL_TO_INT(id), *vp,
1606  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_CHECK,
1607  JSPROP_ENUMERATE)) {
1608  printf( "JS_DefineElement failed in doMFSetProperty.\n");
1609  return JS_FALSE;
1610  }
1611 
1612  /* has the length changed? */
1613  if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &myv)) {
1614  printf("JS_GetProperty failed for \"%s\" in doMFSetProperty.\n", MF_LENGTH_FIELD);
1615  return JS_FALSE;
1616  }
1617 
1618  #ifdef JSVRMLCLASSESVERBOSE
1619  printf ("object %p old length %d, possibly new length is going to be %d\n",obj,JSVAL_TO_INT(myv), JSVAL_TO_INT(id)+1);
1620  #endif
1621 
1622  if (JSVAL_TO_INT(myv) < (JSVAL_TO_INT(id)+1)) {
1623  printf ("new length is %d\n",JSVAL_TO_INT(id)+1);
1624  myv = INT_TO_JSVAL(JSVAL_TO_INT(id)+1);
1625  if (!JS_SetProperty(cx, obj, MF_LENGTH_FIELD, &myv)) {
1626  printf("JS_SetProperty failed for \"%s\" in doMFSetProperty.\n", MF_LENGTH_FIELD);
1627  return JS_FALSE;
1628  }
1629  }
1630  }
1631 
1632  #ifdef JSVRMLCLASSESVERBOSE
1633  printf ("doMFSetProperty, lets see if we have an SFNode somewhere up the chain...\n");
1634  #endif
1635 
1636  /* ok - if we are setting an MF* field by a thing like myField[10] = new String(); the
1637  set method does not really get called. So, we go up the parental chain until we get
1638  either no parent, or a SFNode. If we get a SFNode, we call the "save this" function
1639  so that the X3D scene graph gets the updated array value. To make a long story short,
1640  here's the call to find the parent for the above. */
1641 
1642  me = obj;
1643  par = JS_GetParent(cx, me);
1644  while (par != NULL) {
1645  #ifdef JSVRMLCLASSESVERBOSE
1646  printf ("for obj %p: ",me);
1647  printJSNodeType(cx,me);
1648  printf ("... parent %p\n",par);
1649  printJSNodeType(cx,par);
1650  #endif
1651 
1652  if (JS_InstanceOf (cx, par, &SFNodeClass, NULL)) {
1653  #ifdef JSVRMLCLASSESVERBOSE
1654  printf (" the parent IS AN SFNODE - it is %p\n",par);
1655  #endif
1656 
1657 
1658  if (!JS_GetProperty(cx, obj, "_parentField", &pf)) {
1659  printf ("doMFSetProperty, can not get parent field from this object\n");
1660  return JS_FALSE;
1661  }
1662 
1663  nf = OBJECT_TO_JSVAL(me);
1664 
1665  #ifdef JSVRMLCLASSESVERBOSE
1666  #if JS_VERSION < 185
1667  printf ("parentField is %u \"%s\"\n", (unsigned int)pf, JS_GetStringBytes(JSVAL_TO_STRING(pf)));
1668  #else
1669  _cc = JS_EncodeString(cx,JSVAL_TO_STRING(pf));
1670  printf ("parentField is %u \"%s\"\n", (unsigned int)pf, _cc);
1671  JS_free(cx,_cc);
1672  #endif
1673  #endif
1674 
1675  if (!JS_ValueToId(cx,pf,&oid)) {
1676  printf("doMFSetProperty: JS_ValueToId failed.\n");
1677  return JS_FALSE;
1678  }
1679 
1680  if (!setSFNodeField (cx, par, oid,
1681 #if JS_VERSION >= 185
1682  JS_FALSE,
1683 #endif
1684  &nf)) {
1685  printf ("could not set field of SFNode\n");
1686  }
1687 
1688  }
1689  me = par;
1690  par = JS_GetParent(cx, me);
1691  }
1692 
1693  return JS_TRUE;
1694 }
1695 
1696 JSBool
1697 doMFStringUnquote(JSContext *cx, jsval *vp)
1698 {
1699  JSString *_str, *_vpStr;
1700  char *_buff, *_tmp_vpStr;
1701  size_t _buff_len;
1702  unsigned int i, j = 0;
1703 
1704  _str = JS_ValueToString(cx, *vp);
1705 #if JS_VERSION < 185
1706  _buff = JS_GetStringBytes(_str);
1707 #else
1708  _buff = JS_EncodeString(cx,_str);
1709 #endif
1710  _buff_len = strlen(_buff) + 1;
1711 
1712  #ifdef JSVRMLCLASSESVERBOSE
1713  printf("doMFStringUnquote: vp = \"%s\"\n", _buff);
1714  #endif
1715 
1716  if (memchr(_buff, '"', _buff_len) != NULL) {
1717  _tmp_vpStr = MALLOC(char *, _buff_len * sizeof(char));
1718 
1719  memset(_tmp_vpStr, 0, _buff_len);
1720 
1721  for (i = 0; i <= (_buff_len-1); i++) {
1722  if (_buff[i] != '"' ||
1723  (i > 0 && _buff[i - 1] == '\\')) {
1724  _tmp_vpStr[j++] = _buff[i];
1725  }
1726  }
1727  #ifdef JSVRMLCLASSESVERBOSE
1728  printf ("new unquoted string %s\n",_tmp_vpStr);
1729  #endif
1730 
1731  _vpStr = JS_NewStringCopyZ(cx, _tmp_vpStr);
1732  *vp = STRING_TO_JSVAL(_vpStr);
1733 
1734  FREE_IF_NZ (_tmp_vpStr);
1735  }
1736 #if JS_VERSION >= 185
1737  JS_free(cx,_buff);
1738 #endif
1739 
1740  return JS_TRUE;
1741 }
1742 
1743 
1744 JSBool
1745 #if JS_VERSION < 185
1746 globalResolve(JSContext *cx, JSObject *obj, jsval id)
1747 #else
1748 globalResolve(JSContext *cx, JSObject *obj, jsid id)
1749 #endif
1750 {
1751  UNUSED(cx);
1752  UNUSED(obj);
1753  UNUSED(id);
1754  return JS_TRUE;
1755 }
1756 
1757 
1758 /* load the FreeWRL extra classes */
1759 JSBool loadVrmlClasses(JSContext *context, JSObject *globalObj) {
1760  jsval v;
1761  int i;
1762 
1763  JSObject *myProto;
1764 
1765  i=0;
1766  while (JSLoadProps[i].class != NULL) {
1767  #ifdef JSVRMLCLASSESVERBOSE
1768  printf ("loading %s\n",JSLoadProps[i].id);
1769  #endif
1770 
1771  /* v = 0; */
1772  if (( myProto = JS_InitClass(context, globalObj, NULL, JSLoadProps[i].class,
1773  JSLoadProps[i].constr, INIT_ARGC, JSLoadProps[i].Properties,
1774  JSLoadProps[i].Functions, NULL, NULL)) == NULL) {
1775  printf("JS_InitClass for %s failed in loadVrmlClasses.\n",JSLoadProps[i].id);
1776  return JS_FALSE;
1777  }
1778  v = OBJECT_TO_JSVAL(myProto);
1779  if (!JS_SetProperty(context, globalObj, JSLoadProps[i].id, &v)) {
1780  printf("JS_SetProperty for %s failed in loadVrmlClasses.\n",JSLoadProps[i].id);
1781  return JS_FALSE;
1782  }
1783 
1784  i++;
1785  }
1786  return JS_TRUE;
1787 }
1788 
1789 /* go through and see if the setECMA routine touched this name */
1790 int findNameInECMATable(JSContext *context, char *toFind) {
1791  int i;
1792  ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
1793  #ifdef JSVRMLCLASSESVERBOSE
1794  printf ("findNameInECMATable, looking for %s context %p\n",toFind,context);
1795  #endif
1796 
1797  i=0;
1798  while (i < p->maxECMAVal) {
1799  #ifdef JSVRMLCLASSESVERBOSE
1800  printf (" %d: %s==%s cx %p==%p\n",i,p->ECMAValues[i].name,toFind,p->ECMAValues[i].context,context);
1801  #endif
1802 
1803 
1804  if ((p->ECMAValues[i].context == context) && (strcmp(p->ECMAValues[i].name,toFind)==0)) {
1805  #ifdef JSVRMLCLASSESVERBOSE
1806  printf ("fineInECMATable: found value at %d\n",i);
1807  #endif
1808  return p->ECMAValues[i].valueChanged;
1809  }
1810  i++;
1811  }
1812 
1813  /* did not find this one, add it */
1814  #ifdef JSVRMLCLASSESVERBOSE
1815  printf ("findInECMATable - did not find %s\n",toFind);
1816  #endif
1817 
1818  return FALSE;
1819 }
1820 
1821 /* go through the ECMA table, and reset the valueChanged flag. */
1822 void resetNameInECMATable(JSContext *context, char *toFind) {
1823  int i;
1824  ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
1825  #ifdef JSVRMLCLASSESVERBOSE
1826  printf ("findNameInECMATable, looking for %s\n",toFind);
1827  #endif
1828 
1829  i=0;
1830  while (i < p->maxECMAVal) {
1831  #ifdef JSVRMLCLASSESVERBOSE
1832  printf (" %d: %s==%s cx %p==%p\n",i,p->ECMAValues[i].name,toFind,p->ECMAValues[i].context,context);
1833  #endif
1834 
1835 
1836  if ((p->ECMAValues[i].context == context) && (strcmp(p->ECMAValues[i].name,toFind)==0)) {
1837  #ifdef JSVRMLCLASSESVERBOSE
1838  printf ("fineInECMATable: found value at %d\n",i);
1839  #endif
1840  p->ECMAValues[i].valueChanged = FALSE;
1841  return;
1842  }
1843  i++;
1844  }
1845 }
1846 
1847 /* set the valueChanged flag - add a new entry to the table if required */
1848 void setInECMATable(JSContext *context, char *toFind) {
1849  int i;
1850  ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
1851  #ifdef JSVRMLCLASSESVERBOSE
1852  printf ("setInECMATable, looking for %s\n",toFind);
1853  #endif
1854 
1855  i=0;
1856  while (i < p->maxECMAVal) {
1857  #ifdef JSVRMLCLASSESVERBOSE
1858  printf (" %d: %s==%s cx %p==%p\n",i,p->ECMAValues[i].name,toFind,p->ECMAValues[i].context,context);
1859  #endif
1860 
1861 
1862  if ((p->ECMAValues[i].context == context) && (strcmp(p->ECMAValues[i].name,toFind)==0)) {
1863  #ifdef JSVRMLCLASSESVERBOSE
1864  printf ("setInECMATable: found value at %d\n",i);
1865  #endif
1866  p->ECMAValues[i].valueChanged = TRUE;
1867  return;
1868  }
1869  i++;
1870  }
1871 
1872  /* did not find this one, add it */
1873  #ifdef JSVRMLCLASSESVERBOSE
1874  printf ("setInECMATable - new entry at %d for %s\n",p->maxECMAVal, toFind);
1875  #endif
1876 
1877  p->maxECMAVal ++;
1878  if (p->maxECMAVal == ECMAValueTableSize) {
1879  ConsoleMessage ("problem in setInECMATable for scripting\n");
1880  p->maxECMAVal = ECMAValueTableSize - 10;
1881  }
1882 #if JS_VERSION < 185
1883  /* Dangerous code, taking a string and casting it directly -- why does this happen? */
1884  p->ECMAValues[p->maxECMAVal-1].JS_address = (jsval) toFind;
1885 #else
1886  /* since this seems to never be used anyways .. */
1887  p->ECMAValues[p->maxECMAVal-1].JS_address = JSVAL_ZERO;
1888 #endif
1889  p->ECMAValues[p->maxECMAVal-1].valueChanged = TRUE;
1890  p->ECMAValues[p->maxECMAVal-1].name = STRDUP(toFind);
1891  p->ECMAValues[p->maxECMAVal-1].context = context;
1892 }
1893 
1894 JSBool
1895 #if JS_VERSION < 185
1896 setECMANative(JSContext *context, JSObject *obj, jsval id, jsval *vp)
1897 #else
1898 setECMANative(JSContext *context, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
1899 #endif
1900 {
1901  JSString *_idStr;
1902  JSString *_vpStr, *_newVpStr;
1903  JSBool ret = JS_TRUE;
1904  char *_id_c;
1905 
1906  char *_vp_c, *_new_vp_c;
1907  size_t len = 0;
1908 #if JS_VERSION >= 185
1909  jsval id;
1910  if (!JS_IdToValue(context,iid,&id)) {
1911  printf( "JS_IdToValue failed\n");
1912  return JS_FALSE;
1913  }
1914 #endif
1915 
1916  _idStr = JS_ValueToString(context, id);
1917 #if JS_VERSION < 185
1918  _id_c = JS_GetStringBytes(_idStr);
1919 #else
1920  _id_c = JS_EncodeString(context,_idStr);
1921 #endif
1922 
1923  /* "register" this ECMA value for routing changed flag stuff */
1924  setInECMATable(context, _id_c);
1925 
1926  if (JSVAL_IS_STRING(*vp)) {
1927  _vpStr = JS_ValueToString(context, *vp);
1928 #if JS_VERSION < 185
1929  _vp_c = JS_GetStringBytes(_vpStr);
1930 #else
1931  _vp_c = JS_EncodeString(context,_vpStr);
1932 #endif
1933 
1934  len = strlen(_vp_c);
1935 
1936 
1937  /* len + 3 for '\0' and "..." */
1938  _new_vp_c = MALLOC(char *, (len + 3) * sizeof(char));
1939  /* JAS - do NOT prepend/append double quotes to this string*/
1940  /* JAS - only for the null terminator*/
1941  /* JAS len += 3;*/
1942  len += 1;
1943 
1944  memset(_new_vp_c, 0, len);
1945  /* JAS sprintf(_new_vp_c, "\"%.*s\"", len, _vp_c);*/
1946  sprintf(_new_vp_c, "%.*s", (int) len, _vp_c);
1947  _newVpStr = JS_NewStringCopyZ(context, _new_vp_c);
1948  *vp = STRING_TO_JSVAL(_newVpStr);
1949 
1950  #ifdef JSVRMLCLASSESVERBOSE
1951  printf("setECMANative: have string obj = %p, id = \"%s\", vp = %s\n",
1952  obj, _id_c, _new_vp_c);
1953  #endif
1954  FREE_IF_NZ (_new_vp_c);
1955 #if JS_VERSION >= 185
1956  JS_free(context,_vp_c);
1957 #endif
1958  } else {
1959  #ifdef JSVRMLCLASSESVERBOSE
1960  _vpStr = JS_ValueToString(context, *vp);
1961 #if JS_VERSION < 185
1962  _vp_c = JS_GetStringBytes(_vpStr);
1963 #else
1964  _vp_c = JS_EncodeString(context,_vpStr);
1965 #endif
1966  printf("setECMANative: obj = %p, id = \"%s\", vp = %s\n",
1967  obj, _id_c, _vp_c);
1968 #if JS_VERSION >= 185
1969  JS_free(context,_vp_c);
1970 #endif
1971  #endif
1972  }
1973 #if JS_VERSION >= 185
1974  JS_free(context,_id_c);
1975 #endif
1976  return ret;
1977 }
1978 
1979 /* used mostly for debugging */
1980 JSBool
1981 #if JS_VERSION < 185
1982 getAssignProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
1983 #else
1984 getAssignProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
1985 #endif
1986 {
1987  #ifdef JSVRMLCLASSESVERBOSE
1988  JSString *_idStr, *_vpStr;
1989  char *_id_c, *_vp_c;
1990 
1991 #if JS_VERSION >= 185
1992  jsval id;
1993  if (!JS_IdToValue(cx,iid,&id)) {
1994  printf("getAssignProperty: JS_IdToValue failed -- returning JS_TRUE anyways\n");
1995  }
1996 #endif
1997 
1998  _idStr = JS_ValueToString(cx, id);
1999  _vpStr = JS_ValueToString(cx, *vp);
2000 #if JS_VERSION < 185
2001  _id_c = JS_GetStringBytes(_idStr);
2002  _vp_c = JS_GetStringBytes(_vpStr);
2003 #else
2004  _id_c = JS_EncodeString(cx,_idStr);
2005  _vp_c = JS_EncodeString(cx,_vpStr);
2006 #endif
2007  printf("getAssignProperty: obj = %p, id = \"%s\", vp = %s\n",
2008  obj, _id_c, _vp_c);
2009  printf ("what is vp? \n");
2010  if (JSVAL_IS_OBJECT(*vp)) printf ("is OBJECT\n");
2011  if (JSVAL_IS_STRING(*vp)) printf ("is STRING\n");
2012  if (JSVAL_IS_INT(*vp)) printf ("is INT\n");
2013  if (JSVAL_IS_DOUBLE(*vp)) printf ("is DOUBLE\n");
2014 
2015 #if JS_VERSION >= 185
2016  JS_free(cx,_id_c);
2017  JS_free(cx,_vp_c);
2018 #endif
2019  #endif
2020  return JS_TRUE;
2021 }
2022 
2023 
2024 /* a kind of hack to replace the use of JSPROP_ASSIGNHACK */
2025 JSBool
2026 #if JS_VERSION < 185
2027 setAssignProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2028 #else
2029 setAssignProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
2030 #endif
2031 {
2032  JSObject *_o;
2033  JSString *_str;
2034  const uintN _argc = 2;
2035 #ifdef _MSC_VER
2036  jsval newVal, initVal, _argv[2]; /* win32 complains cant allocate array of size 0 */
2037 #else
2038  jsval newVal, initVal, _argv[_argc];
2039 #endif
2040  char *_id_c;
2041 #if JS_VERSION >= 185
2042  jsval id;
2043  if (!JS_IdToValue(cx,iid,&id)) {
2044  printf("setAssignProperty: JS_IdToValue failed.\n");
2045  return JS_FALSE;
2046  }
2047 #endif
2048 
2049  if (JSVAL_IS_STRING(id)) {
2050  if (!JS_ConvertValue(cx, *vp, JSTYPE_OBJECT, &newVal)) {
2051  printf( "JS_ConvertValue failed in setAssignProperty.\n");
2052  return JS_FALSE;
2053  }
2054 
2055  _str = JSVAL_TO_STRING(id);
2056 #if JS_VERSION < 185
2057  _id_c = JS_GetStringBytes(_str);
2058 #else
2059  _id_c = JS_EncodeString(cx,_str);
2060 #endif
2061  if (!JS_GetProperty(cx, obj, _id_c, &initVal)) {
2062  printf( "JS_GetProperty failed in setAssignProperty.\n");
2063 #if JS_VERSION >= 185
2064  JS_free(cx,_id_c);
2065 #endif
2066  return JS_FALSE;
2067  }
2068  #ifdef JSVRMLCLASSESVERBOSE
2069  printf("setAssignProperty: obj = %p, id = \"%s\", from = %d, to = %d\n",
2070  obj, _id_c, (int)newVal, (int)initVal);
2071 
2072  if (JSVAL_IS_OBJECT(initVal)) printf ("initVal is an OBJECT\n");
2073  if (JSVAL_IS_STRING(initVal)) printf ("initVal is an STRING\n");
2074  if (JSVAL_IS_NUMBER(initVal)) printf ("initVal is an NUMBER\n");
2075  if (JSVAL_IS_DOUBLE(initVal)) printf ("initVal is an DOUBLE\n");
2076  if (JSVAL_IS_INT(initVal)) printf ("initVal is an INT\n");
2077 
2078  if (JSVAL_IS_OBJECT(newVal)) printf ("newVal is an OBJECT\n");
2079  if (JSVAL_IS_STRING(newVal)) printf ("newVal is an STRING\n");
2080  if (JSVAL_IS_NUMBER(newVal)) printf ("newVal is an NUMBER\n");
2081  if (JSVAL_IS_DOUBLE(newVal)) printf ("newVal is an DOUBLE\n");
2082  if (JSVAL_IS_INT(newVal)) printf ("newVal is an INT\n");
2083 
2084  if (JSVAL_IS_OBJECT(id)) printf ("id is an OBJECT\n");
2085  if (JSVAL_IS_STRING(id)) printf ("id is an STRING\n");
2086  if (JSVAL_IS_NUMBER(id)) printf ("id is an NUMBER\n");
2087  if (JSVAL_IS_DOUBLE(id)) printf ("id is an DOUBLE\n");
2088  if (JSVAL_IS_INT(id)) printf ("id is an INT\n");
2089 
2090 #if JS_VERSION < 185
2091  printf ("id is %s\n",JS_GetStringBytes(JS_ValueToString(cx,id)));
2092  printf ("initVal is %s\n",JS_GetStringBytes(JS_ValueToString(cx,initVal)));
2093  printf ("newVal is %s\n",JS_GetStringBytes(JS_ValueToString(cx,newVal)));
2094 #else
2095  printf ("id is %s\n",JS_EncodeString(cx,JS_ValueToString(cx,id)));
2096  printf ("initVal is %s\n",JS_EncodeString(cx,JS_ValueToString(cx,initVal)));
2097  printf ("newVal is %s\n",JS_EncodeString(cx,JS_ValueToString(cx,newVal)));
2098 #endif
2099  #endif
2100 #if JS_VERSION >= 185
2101  JS_free(cx,_id_c);
2102 #endif
2103 
2104 
2105  _o = JSVAL_TO_OBJECT(initVal);
2106 
2107  #ifdef xxJSVRMLCLASSESVERBOSE
2108  printf ("in setAssignProperty, o is %u type ",_o);
2109  printJSNodeType(cx,_o);
2110  printf ("\n");
2111  #endif
2112 
2113  _argv[0] = newVal;
2114  _argv[1] = id;
2115 
2116  if (!JS_CallFunctionName(cx, _o, "assign", _argc, _argv, vp)) {
2117  printf( "JS_CallFunctionName failed in setAssignProperty.\n");
2118  return JS_FALSE;
2119  }
2120  } else {
2121  #ifdef JSVRMLCLASSESVERBOSE
2122  _str = JS_ValueToString(cx, id);
2123 #if JS_VERSION < 185
2124  _id_c = JS_GetStringBytes(_str);
2125 #else
2126  _id_c = JS_EncodeString(cx,_str);
2127 #endif
2128  printf("setAssignProperty: obj = %p, id = \"%s\"\n",
2129  obj, _id_c);
2130 #if JS_VERSION >= 185
2131  JS_free(cx,_id_c);
2132 #endif
2133  #endif
2134  }
2135 
2136  return JS_TRUE;
2137 }
2138 
2139 #endif /* !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK) */