FreeWRL / FreeX3D 4.3.0
EAI_C_swigExtras.c
1
2/****************************************************************************
3 This file is part of the FreeWRL/FreeX3D Distribution.
4
5 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
6
7 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
19****************************************************************************/
20
21
22#include "EAI_C.h"
23#include <config.h>
24
25//#include "EAI_swigMe.h"
26#include <stdio.h>
27//#define SWIG
28#ifdef SWIG
29int isMF(int nodetype)
30{
31 return (nodetype %2 == 1) && nodetype >= 0 && nodetype <= 41;
32}
33int isSF(int nodetype)
34{
35 return (nodetype % 2 == 0) && nodetype >= 0 && nodetype <= 41;
36}
37X3DNode *X3D_newSF(int nodetype)
38{
39 X3DNode* retval;
40 if(isSF(nodetype))
41 {
42 /*delegate default construction to the appropriate type */
43 switch(nodetype)
44 {
45 case FIELDTYPE_SFColor:
46 retval = X3D_newSFColor(0.0f,0.0f,0.0f); break;
47 case FIELDTYPE_SFFloat:
48 retval = X3D_newSFFloat(0.0f); break;
49 case FIELDTYPE_SFTime:
50 retval = X3D_newSFTime(0.0); break;
51 case FIELDTYPE_SFInt32:
52 retval = X3D_newSFInt32(0); break;
53 case FIELDTYPE_SFString:
54 retval = X3D_newSFString(""); break;
55 case FIELDTYPE_SFNode:
56 retval = X3D_newSFNode(); break;
57 case FIELDTYPE_SFRotation:
58 retval = X3D_newSFRotation(0.0f,1.0f,0.0f,0.0f); break;
59 case FIELDTYPE_SFVec2f:
60 retval = X3D_newSFVec2f(0.0f,0.0f); break;
61 case FIELDTYPE_SFVec3f:
62 retval = X3D_newSFVec3f(0.0f,0.0f,0.0f); break;
63 case FIELDTYPE_SFColorRGBA:
64 retval = X3D_newSFColorRGBA(.5f,.5f,.5f,1.0f); break;
65 case FIELDTYPE_SFBool:
66 retval = X3D_newSFBool(0); break;
67 case FIELDTYPE_SFVec3d:
68 retval = X3D_newSFVec3d(0.0,0.0,0.0); break;
69 case FIELDTYPE_SFVec2d:
70 retval = X3D_newSFVec2d(0.0,0.0); break;
71 }
72 return retval;
73 }
74 else
75 printf ("New node not implemented yet for this type\n");return NULL;
76 return NULL;
77}
78int X3D_sizeof(int fieldtype)
79{
80 /* how do you dynamic_cast<> in C? to keep the recent MF code both general and non-breaking we need the size by int type
81 if the code ever changes so the MF isn't malloced in a contiguous block ie **p instead of *p then we won't need this.
82 */
83 int retval;
84 switch(fieldtype)
85 {
86 case FIELDTYPE_SFColor:
87 retval = sizeof(_intX3D_SFColor); break;
88 case FIELDTYPE_SFFloat:
89 retval = sizeof(_intX3D_SFFloat); break;
90 case FIELDTYPE_SFTime:
91 retval = sizeof(_intX3D_SFTime); break;
92 case FIELDTYPE_SFInt32:
93 retval = sizeof(_intX3D_SFInt32); break;
94 case FIELDTYPE_SFString:
95 retval = sizeof(_intX3D_SFString); break;
96 case FIELDTYPE_SFNode:
97 retval = sizeof(_intX3D_SFNode); break;
98 case FIELDTYPE_SFRotation:
99 retval = sizeof(_intX3D_SFRotation); break;
100 case FIELDTYPE_SFVec2f:
101 retval = sizeof(_intX3D_SFVec2f); break;
102 case FIELDTYPE_SFVec3f:
103 retval = sizeof(_intX3D_SFVec3f); break;
104 case FIELDTYPE_SFColorRGBA:
105 retval = sizeof(_intX3D_SFColorRGBA); break;
106 case FIELDTYPE_SFBool:
107 retval = sizeof(_intX3D_SFBool); break;
108 case FIELDTYPE_SFVec3d:
109 retval = sizeof(_intX3D_SFVec3d); break;
110 case FIELDTYPE_SFVec2d:
111 retval = sizeof(_intX3D_SFVec2d); break;
112
113 case FIELDTYPE_MFColor:
114 retval = sizeof(_intX3D_MFColor); break;
115 case FIELDTYPE_MFFloat:
116 retval = sizeof(_intX3D_MFFloat); break;
117 case FIELDTYPE_MFTime:
118 retval = sizeof(_intX3D_MFTime); break;
119 case FIELDTYPE_MFInt32:
120 retval = sizeof(_intX3D_MFInt32); break;
121 case FIELDTYPE_MFString:
122 retval = sizeof(_intX3D_MFString); break;
123 case FIELDTYPE_MFNode:
124 retval = sizeof(_intX3D_MFNode); break;
125 case FIELDTYPE_MFRotation:
126 retval = sizeof(_intX3D_MFRotation); break;
127 case FIELDTYPE_MFVec2f:
128 retval = sizeof(_intX3D_MFVec2f); break;
129 case FIELDTYPE_MFVec3f:
130 retval = sizeof(_intX3D_MFVec3f); break;
131 case FIELDTYPE_MFColorRGBA:
132 retval = sizeof(_intX3D_MFColorRGBA); break;
133 case FIELDTYPE_MFBool:
134 retval = sizeof(_intX3D_MFBool); break;
135 case FIELDTYPE_MFVec3d:
136 retval = sizeof(_intX3D_MFVec3d); break;
137 case FIELDTYPE_MFVec2d:
138 retval = sizeof(_intX3D_MFVec2d); break;
139 default:
140 retval = 0;
141 }
142 return retval;
143}
144X3DNode *_swigNewMF(int itype, int num )
145{
146 int i;
147 char *p, *q;
148 X3DNode* retval;
149 retval = malloc (sizeof (X3DNode));
150 retval->type = itype;
151 retval->X3D_MFNode.n = num;
152 if(num > 0)
153 {
154 /* X3D_freeNode assumes the MF's SFs are in one block: free(node->X3D_MFString.p); */
155 p = malloc (sizeof (X3DNode) * num);
156 retval->X3D_MFNode.p = (_intX3D_SFNode*)p;
157 q = (char*)X3D_newSF(itype-1); /* initialized to defaults esp. strptr=NULL or whatever */
158 for (i = 0; i < num; i++) {
159 memcpy(p,q,X3D_sizeof(itype-1)); /*initialize the storage area to defaults*/
160 p+= X3D_sizeof(itype-1);
161 }
162 X3D_freeNode((X3DNode*)q);
163 }else
164 retval->X3D_MFNode.p = NULL;
165 return retval;
166
167}
168X3DNode *X3D_swigNewMF(char *fieldtype, int num )
169{
170 int itype, ftype;
171 itype = -1;
172 ftype = findFieldInFIELDTYPES(fieldtype);
173 if( isMF(ftype) ) itype = ftype;
174 if( isSF(ftype) ) itype = ftype+1; /*mf type is sf+1*/
175 if(itype > -1)
176 {
177 return _swigNewMF(itype,num);
178
179 }else{
180 printf ("New node not implemented yet for this type\n");return NULL;
181 }
182}
183void _X3D_setItemSF(X3DNode* node, int item, X3DNode* value)
184{
185 /* set a scalar value in the SF node array .r or .c */
186
187 int vtype, ntype;
188 double v;
189 vtype = value->type;
190 ntype = node->type;
191 if( !isSF(vtype) )return;
192 if( item < 0 || item > 3) return;
193 switch(vtype)
194 {
195 case FIELDTYPE_SFTime:
196 v = value->X3D_SFTime.value; break;
197 case FIELDTYPE_SFFloat:
198 v = (double)value->X3D_SFFloat.value; break;
199 case FIELDTYPE_SFInt32:
200 v = (double)value->X3D_SFInt32.value; break;
201 case FIELDTYPE_SFBool:
202 v = (double)value->X3D_SFBool.value; break;
203 /* should have SFString ? SFBool (int 1/0)? */
204 default:
205 return;
206 }
207 switch(ntype)
208 {
209 case FIELDTYPE_SFColor:
210 if(item > 2) break;
211 node->X3D_SFColor.c[item] = (float)v; break;
212 case FIELDTYPE_SFFloat:
213 if(item > 0) break;
214 node->X3D_SFFloat.value = (float)v; break;
215 case FIELDTYPE_SFTime:
216 if(item > 0) break;
217 node->X3D_SFTime.value = (float)v; break;
218 case FIELDTYPE_SFInt32:
219 if(item > 0) break;
220 node->X3D_SFInt32.value = (int)v; break;
221 case FIELDTYPE_SFString:
222 if(item > strlen(node->X3D_SFString.strptr)) break; /* int32>>char function*/
223 node->X3D_SFString.strptr[item] = (char)((int)v); break;
224 case FIELDTYPE_SFNode:
225 if(item > 0) break;
226 node->X3D_SFNode.adr = (int)v; break;
227 case FIELDTYPE_SFRotation:
228 if(item > 3) break;
229 node->X3D_SFRotation.r[item] = (float)v; break;
230 case FIELDTYPE_SFVec2f:
231 if(item > 1) break;
232 node->X3D_SFVec2f.c[item] = (float)v; break;
233 case FIELDTYPE_SFVec3f:
234 if(item > 2) break;
235 node->X3D_SFVec3f.c[item] = (float)v; break;
236 case FIELDTYPE_SFColorRGBA:
237 if(item > 3) break;
238 node->X3D_SFColorRGBA.r[item] = (float)v; break;
239 case FIELDTYPE_SFBool:
240 if(item > 0) break;
241 node->X3D_SFBool.value = ((int)v)?1:0; break;
242 case FIELDTYPE_SFVec3d:
243 if(item > 2) break;
244 node->X3D_SFVec3d.c[item] = (double)v; break;
245 case FIELDTYPE_SFVec2d:
246 if(item > 1) break;
247 node->X3D_SFVec2d.c[item] = (double)v; break;
248 default:
249 break;
250 }
251}
252X3DNode* _X3D_getItemSF(X3DNode* node, int item)
253{
254 /* get a scalar value in the SF node array .r or .c */
255
256 int vtype,ntype;
257 union{
258 double d;
259 float f;
260 int i;
261 } v;
262 vtype = -1;
263
264 ntype = node->type;
265 if( item < 0 || item > 3) return NULL;
266 switch(ntype)
267 {
268 case FIELDTYPE_SFColor:
269 if(item > 2) break;
270 v.f = node->X3D_SFColor.c[item]; vtype =FIELDTYPE_SFFloat; break;
271 case FIELDTYPE_SFFloat:
272 if(item > 0) break;
273 v.f = node->X3D_SFFloat.value; vtype =FIELDTYPE_SFFloat; break;
274 case FIELDTYPE_SFTime:
275 if(item > 0) break;
276 v.d = node->X3D_SFTime.value; vtype = FIELDTYPE_SFTime; break;
277 case FIELDTYPE_SFInt32:
278 if(item > 0) break;
279 v.i = node->X3D_SFInt32.value; vtype = FIELDTYPE_SFInt32; break;
280 case FIELDTYPE_SFString:
281 if(item > strlen(node->X3D_SFString.strptr)) break; /* int32>>char function*/
282 v.i = (int)(char)node->X3D_SFString.strptr[item]; vtype = FIELDTYPE_SFInt32; break;
283 case FIELDTYPE_SFNode:
284 if(item > 0) break;
285 v.i = (int)node->X3D_SFNode.adr; vtype = FIELDTYPE_SFInt32; break;
286 case FIELDTYPE_SFRotation:
287 if(item > 3) break;
288 v.f = node->X3D_SFRotation.r[item]; vtype =FIELDTYPE_SFFloat; break;
289 case FIELDTYPE_SFVec2f:
290 if(item > 1) break;
291 v.f = node->X3D_SFVec2f.c[item]; vtype =FIELDTYPE_SFFloat; break;
292 case FIELDTYPE_SFVec3f:
293 if(item > 2) break;
294 v.f = node->X3D_SFVec3f.c[item];vtype =FIELDTYPE_SFFloat; break;
295 case FIELDTYPE_SFColorRGBA:
296 if(item > 3) break;
297 v.f = node->X3D_SFColorRGBA.r[item]; vtype =FIELDTYPE_SFFloat; break;
298 case FIELDTYPE_SFBool:
299 if(item > 0) break;
300 v.i = node->X3D_SFBool.value; vtype = FIELDTYPE_SFInt32; break;
301 case FIELDTYPE_SFVec3d:
302 if(item > 2) break;
303 v.d = node->X3D_SFVec3d.c[item]; vtype =FIELDTYPE_SFTime; break;
304 case FIELDTYPE_SFVec2d:
305 if(item > 1) break;
306 v.d = node->X3D_SFVec2d.c[item]; vtype =FIELDTYPE_SFTime; break;
307 default:
308 break;
309 }
310 switch(vtype)
311 {
312 case FIELDTYPE_SFTime:
313 return X3D_newSFTime(v.d); break;
314 case FIELDTYPE_SFFloat:
315 return X3D_newSFFloat(v.f); break;
316 case FIELDTYPE_SFInt32:
317 return X3D_newSFInt32(v.i); break;
318 case FIELDTYPE_SFBool:
319 return X3D_newSFInt32(v.i); break;
320 default:
321 return NULL;
322 }
323 return NULL;
324}
325X3DNode* X3D_deepcopySF(X3DNode* node)
326{
327 X3DNode* retval;
328 /*returns deep copy of field*/
329 float* f;
330 double* d;
331 char* s;
332 int n;
333 int ntype = node->type;
334 switch(ntype)
335 {
336 case FIELDTYPE_SFColor:
337 f = node->X3D_SFColor.c;
338 retval = X3D_newSFColor(f[0],f[1],f[2]); break;
339 case FIELDTYPE_SFFloat:
340 retval = X3D_newSFFloat(node->X3D_SFFloat.value); break;
341 case FIELDTYPE_SFTime:
342 retval = X3D_newSFTime(node->X3D_SFTime.value); break;
343 case FIELDTYPE_SFInt32:
344 retval = X3D_newSFInt32(node->X3D_SFInt32.value); break;
345 case FIELDTYPE_SFString:
346 retval = X3D_newSFString(node->X3D_SFString.strptr);
347 s = node->X3D_SFString.strptr;
348 n = min(strlen(s)+1,STRLEN);
349 retval->X3D_SFString.strptr = malloc(n);
350 strncpy(retval->X3D_SFString.strptr,s,n);
351 retval->X3D_SFString.len = strlen(s);
352 break;
353 case FIELDTYPE_SFNode:
354 retval = X3D_newSFNode(); break;
355 case FIELDTYPE_SFRotation:
356 f = node->X3D_SFRotation.r;
357 retval = X3D_newSFRotation(f[0],f[1],f[2],f[3]); break;
358 case FIELDTYPE_SFVec2f:
359 f = node->X3D_SFVec2f.c;
360 retval = X3D_newSFVec2f(f[0],f[1]); break;
361 case FIELDTYPE_SFVec3f:
362 f = node->X3D_SFVec3f.c;
363 retval = X3D_newSFVec3f(f[0],f[1],f[2]); break;
364 case FIELDTYPE_SFColorRGBA:
365 f = node->X3D_SFColorRGBA.r;
366 retval = X3D_newSFColorRGBA(f[0],f[1],f[2],f[3]); break;
367 case FIELDTYPE_SFBool:
368 retval = X3D_newSFBool(node->X3D_SFBool.value); break;
369 case FIELDTYPE_SFVec3d:
370 retval = NULL;
371 break;
372 case FIELDTYPE_SFVec2d:
373 d = node->X3D_SFVec2d.c;
374 retval = X3D_newSFVec2d(d[0],d[1]); break;
375 default:
376 break;
377 }
378 return retval;
379}
380void _X3D_setItemMF(X3DNode* node, int item, X3DNode* value)
381{
382 unsigned long sz;
383 char * target;
384 char * newstr;
385 if( !isSF(value->type) )return; /* we're supposed to be setting an SF into an MF */
386 if( node->type != value->type+1 )return; /* must be same type ie mfstring and sfstring, or mfvec2d and sfvec2d */
387 if( item < 0 || item >= node->X3D_MFNode.n )return; /*space must have been allocated already, with swigNewMF(,#) or _grow(,,#) */
388 if( value->type == FIELDTYPE_SFString)
389 {
390 int len = min(value->X3D_SFString.len +1,STRLEN);
391 /*free(node->X3D_MFString.p[item].strptr); /* better be reasonably initialized ie to NULL in newSF */
392 FREE_IF_NZ(node->X3D_MFString.p[item].strptr);
393 newstr = malloc(len*sizeof(char));
394 strncpy(newstr,value->X3D_SFString.strptr,len); /*policy - a string is owned by only one node (no ref counting). so deep copy so SF and MF both own their own*/
395 }
396 sz = X3D_sizeof(value->type);
397 target = ((char *)(node->X3D_MFNode.p)) + sz*item;
398 memcpy(target,value,sz);
399 if( value->type == FIELDTYPE_SFString)
400 {
401 node->X3D_MFString.p[item].strptr = newstr;
402 node->X3D_MFString.p[item].len = strnlen(newstr,STRLEN);
403 }
404}
405X3DNode* _X3D_getItemMF(X3DNode* node, int item)
406{
407 X3DNode* retval;
408 if( item < 0 || item >= node->X3D_MFNode.n )return NULL;
409 /* MSVC increments a pointer by the size of the data structure being pointed to
410 the way we do the p[] it is by specific type
411 */
412 retval = X3D_deepcopySF((X3DNode*)(((char *)(node->X3D_MFNode.p)) + item*X3D_sizeof(node->X3D_MFNode.p[0].type)));
413 return retval;
414
415 /* if noncontiguous this would probably work
416 X3D_freeNode(node->X3D_MFNode.p[item]);
417 node->X3D_MFNode.p[item] = X3D_deepcopySF(value);
418 */
419 retval = X3D_newSF(node->type -1);
420 if( retval->type == FIELDTYPE_SFString) free(retval->X3D_SFString.strptr); /*should be '\0' */
421 memcpy(retval,&(node->X3D_MFNode.p[item]),X3D_sizeof(retval->type)); /*len should get copied here, strptr too though*/
422 if( retval->type == FIELDTYPE_SFString)
423 {
424 int len = min(node->X3D_SFString.len+1,STRLEN);
425 retval->X3D_SFString.strptr = malloc(len);
426 strncpy(retval->X3D_SFString.strptr,node->X3D_SFString.strptr,len);
427 }
428
429 return retval;
430}
431
432void X3D_swigSetItem(X3DNode* node, int item, X3DNode* value)
433{
434 if(isMF(node->type)) _X3D_setItemMF(node,item,value);
435 else if( isSF(value->type) )_X3D_setItemSF(node,item,value);
436}
437X3DNode* X3D_swigGetItem(X3DNode* node, int item)
438{
439 if(isMF(node->type)) return _X3D_getItemMF(node,item);
440 else if( isSF(node->type) ) return _X3D_getItemSF(node,item);
441 return NULL;
442}
443void _grow(X3DNode *node, int num, int more)
444{
445 _intX3D_SFNode *tmp,*p;
446 tmp = node->X3D_MFNode.p;
447 p = malloc(sizeof (X3DNode) * (num+more));
448 bzero(p,sizeof (X3DNode) * (num+more));
449 if(num > 0)
450 {
451 memcpy(p,tmp,sizeof(X3DNode)*num);
452 free(tmp);
453 }
454 node->X3D_MFNode.p = p;
455 node->X3D_MFNode.n = num + more;
456}
457void X3D_swigAppendToMF(X3DNode* node, X3DNode* value)
458{
459 int num, item;
460 if( node != NULL && value != NULL )
461 {
462 if(isMF(node->type) && isSF(value->type))
463 {
464 if(node->type == value->type+1)
465 {
466 num = node->X3D_MFNode.n;
467 _grow(node,num,1);
468 item = node->X3D_MFNode.n -1;
469 _X3D_setItemMF(node,item,value);
470 }
471 }
472 }
473}
474
475int getnumtokens(char* str,char *delim)
476{
477 int n;
478 char *tokens;
479 n = 0;
480 tokens = strtok(str,delim);
481 while(tokens != NULL)
482 {
483 n++;
484 tokens = strtok(NULL,delim);
485 }
486 return n;
487}
488char * _x3ditoa(int ival, char* bigbuf)
489{
490 char *retbuf;
491 int len;
492 sprintf(bigbuf,"%d ",ival); /*note blank separator */
493 len = strlen(bigbuf);
494 retbuf = MALLOC(char *, len+1);
495 strcpy(retbuf,bigbuf);
496 return retbuf;
497}
498char * _x3dftoa(float fval, char* bigbuf)
499{
500 char *retbuf;
501 int len;
502 sprintf(bigbuf,"%f ",fval); /*note blank separator */
503 len = strlen(bigbuf);
504 retbuf = MALLOC(char *, len+1);
505 strcpy(retbuf,bigbuf);
506 return retbuf;
507}
508char * _x3ddtoa(double dval, char* bigbuf)
509{
510 char *retbuf;
511 int len;
512 sprintf(bigbuf,"%f ",dval); /*note blank separator */
513 len = strlen(bigbuf);
514 retbuf = MALLOC(char *, len+1);
515 strcpy(retbuf,bigbuf);
516 return retbuf;
517}
518char * _x3datoa(char *aval, char* bigbuf)
519{
520 /* hello -> "hello", strlen(aval)==0? -> "" */
521 char *retbuf;
522 int len;
523 len = strlen(aval);
524 retbuf = MALLOC(char *, len+4);
525 sprintf(retbuf,"\"%s\" ",aval);
526 retbuf[len+3] = '\0';
527 return retbuf;
528}
529char * X3D_swigStringFromField(X3DNode* field)
530{
531 /*
532 issue: swig treats C arrays as opaque pointers - not very helpful. How to get a specific SF from an MF field?
533 but- swig does pass a char * as scalar string properly
534 goal: convert an MF (or SF) field to a string for easy parsing from a swigged scripting language
535 "itype n sf1 sf2 sf3"
536 sffloat "0 1 -123.456" - the count will always be 1
537 mffloat "1 2 -123.456 555.444"
538 sfstring "24 \"OK folks let's rock it!\""
539 mfstring "25 2 \"You know...\" \"I'm not so sure about 'rocking' it.\"'
540 */
541 int type, ismf, count, i, size;
542 char** tokens;
543 char *string;
544 char buf[500];
545 type = field->type;
546 if(type < 0 || type > 41 ) /*yikes - is there a MAXFIELDTYPE or other validity check? */
547 return NULL; /* or should it be " 'NULL' " */
548 ismf = type % 2;
549 count = 2;
550 if( ismf )
551 count = count + field->X3D_MFNode.n;
552 else
553 count = count + 1;
554 tokens = (char** )malloc(count*sizeof(char*));
555 /*buf = MALLOC(char *, 500); /*just for 1 token - sf string might be the largest*/
556 switch (type)
557 {
558 case FIELDTYPE_SFFloat:
559 tokens[0] = _x3ditoa(FIELDTYPE_SFFloat, buf);
560 tokens[1] = _x3ditoa(1,buf);
561 tokens[2] = _x3dftoa(field->X3D_SFFloat.value, buf);
562 break;
563 case FIELDTYPE_MFFloat:
564 tokens[0] = _x3ditoa(FIELDTYPE_MFFloat,buf);
565 tokens[1] = _x3ditoa(field->X3D_MFNode.n,buf);
566 for(i=0;i<count-2;i++)
567 tokens[i+2] = _x3dftoa(field->X3D_MFFloat.p[i].value,buf);
568 break;
569 case FIELDTYPE_MFString:
570 tokens[0] = _x3ditoa(FIELDTYPE_MFString,buf);
571 tokens[1] = _x3ditoa(field->X3D_MFString.n,buf);
572 for(i=0;i<count-2;i++)
573 tokens[i+2] = _x3datoa(field->X3D_MFString.p[i].strptr,buf);
574 break;
575 }
576 size = 0;
577 for(i=0;i<count;i++) size = size + strlen(tokens[i]);
578 /* FREE_IF_NZ(buf); */
579 string = MALLOC(char *, (size+1)*sizeof(char));
580 string[0] = '\0';
581 for(i=0;i<count;i++)
582 {
583 strcat(string,tokens[i]);
584 FREE_IF_NZ(tokens[i]);
585 }
586 FREE_IF_NZ(tokens);
587 return string; /* somebody else has to free this (option: return as X3D_SFString then X3D_free */
588}
589
590X3DNode* X3D_swigFieldFromString(char* fieldtype, char* values)
591{
592 /*
593 issue: swig treats C arrays as opaque pointers - not very helpful. How to create an MF from a sequence of SF fields?
594 goal: convert string into a field - sf or mf - for easy use from swigged scripting language
595 /* mf = X3D_fieldFromString("MFString","111.11 222.22"); will do SF as well */
596 X3DNode* retval;
597 int type,count;
598 char* vals; /* **carray, *c; */
599 int len,i,n,start,end, inum;
600 float f, *farray, **f2,**f3,**f4;
601 double d,*darray, **d2,**d3,**d4;
602 char *token = NULL;
603 char *delim = " ,";
604
605 if(fieldtype == NULL || values == NULL) return NULL;
606 type = findFieldInFIELDTYPES(fieldtype);
607 /* if( type == -1 ) return NULL; Q. is there an error return code? Where is ffift defined? */
608 /* do some qc */
609 len = strlen(values);
610 vals = (char*) malloc(len);
611 memcpy(vals,values,len); /* getnumtokens is destructive, and a const string produces error - so use copy from original*/
612 switch (type)
613 {
614 case FIELDTYPE_SFFloat:
615 /*
616 token = strtok(values,delim);
617 if( sscanf(token,"%f",&f) == 1)
618 retval = X3D_newSFFloat(f);
619 break;
620 */
621 case FIELDTYPE_MFFloat:
622 case FIELDTYPE_SFVec2f:
623 case FIELDTYPE_MFVec2f:
624 case FIELDTYPE_SFVec3f:
625 case FIELDTYPE_MFVec3f:
626 case FIELDTYPE_SFRotation:
627 case FIELDTYPE_MFRotation:
628 case FIELDTYPE_SFColorRGBA:
629 case FIELDTYPE_MFColorRGBA:
630 case FIELDTYPE_SFColor:
631 case FIELDTYPE_MFColor:
632
633 count = getnumtokens(vals,delim);
634 farray = MALLOC(float *, count*sizeof(float));
635 memcpy(vals,values,len);
636 token = strtok(vals,delim);
637 count = 0;
638 while (token != NULL) {
639 if( sscanf(token,"%f",&f)==1 )/* = strtof(tokens);*/
640 {
641 farray[count] = f;
642 count++;
643 }
644 token = strtok(NULL,delim);
645 }
646 f2 = MALLOC(float **, count*sizeof(float*));
647 f3 = MALLOC(float **, count*sizeof(float*));
648 f4 = MALLOC(float **, count*sizeof(float*));
649 for(i=0;i<count;i++)
650 {
651 f2[i] = &farray[i*2];
652 f3[i] = &farray[i*3];
653 f4[i] = &farray[i*4];
654 }
655 switch(type)
656 {
657 case FIELDTYPE_SFFloat:
658 retval = X3D_newSFFloat(farray[0]);
659 case FIELDTYPE_MFFloat:
660 retval = X3D_newMFFloat(count, farray); break;
661 case FIELDTYPE_SFVec2f:
662 retval = X3D_newSFVec2f(farray[0],farray[1]);break;
663 case FIELDTYPE_SFVec3f:
664 retval = X3D_newSFVec3f(farray[0],farray[1],farray[2]);break;
665 case FIELDTYPE_MFVec3f:
666 retval = X3D_newMFVec3f(count,f3);break;
667 case FIELDTYPE_SFRotation:
668 retval = X3D_newSFRotation(farray[0],farray[1],farray[2],farray[3]);break;
669 case FIELDTYPE_MFRotation:
670 retval = X3D_newMFRotation(count,f4);break;
671 case FIELDTYPE_SFColorRGBA:
672 retval = X3D_newSFColorRGBA(farray[0],farray[1],farray[2],farray[3]);break;
673 case FIELDTYPE_MFColorRGBA:
674 retval = X3D_newMFColorRGBA(count,f4);break;
675 case FIELDTYPE_MFColor:
676 retval = X3D_newMFColor(count,f3);break;
677
678 }
679 FREE_IF_NZ(farray);
680 FREE_IF_NZ(f2);
681 FREE_IF_NZ(f3);
682 FREE_IF_NZ(f4);
683 break;
684 case FIELDTYPE_SFBool:
685 case FIELDTYPE_SFInt32:
686 token = strtok(values,delim); /*string delims*/
687 if( sscanf(token,"%d",&inum) == 1)
688 {
689 if(type == FIELDTYPE_SFInt32) retval = X3D_newSFInt32(inum);
690 if(type == FIELDTYPE_SFBool) retval = X3D_newSFBool(inum);
691 }
692 break;
693 case FIELDTYPE_SFTime:
694 case FIELDTYPE_SFVec2d:
695 case FIELDTYPE_SFVec3d:
696 count = getnumtokens(vals,delim);
697 darray = MALLOC(double *, count*sizeof(double));
698 memcpy(vals,values,len);
699 token = strtok(vals,delim);
700 count = 0;
701 while (token != NULL) {
702 if( sscanf(token,"%lf",&d)==1 )/* = strtof(tokens);*/
703 {
704 darray[count] = d;
705 count++;
706 }
707 token = strtok(NULL,delim);
708 }
709 d2 = MALLOC(double **, count*sizeof(double*));
710 d3 = MALLOC(double **, count*sizeof(double*));
711 d4 = MALLOC(double **, count*sizeof(double*));
712 for(i=0;i<count;i++)
713 {
714 d2[i] = &darray[i*2];
715 d3[i] = &darray[i*3];
716 d4[i] = &darray[i*4];
717 }
718 switch(type)
719 {
720 case FIELDTYPE_SFTime:
721 retval = X3D_newSFTime(darray[0]); break;
722 case FIELDTYPE_SFVec2d:
723 retval = X3D_newSFVec2d(darray[0],darray[1]);break;
724 case FIELDTYPE_SFVec3d:
725 retval = X3D_newMFVec3d(count,d3); break;
726 }
727 FREE_IF_NZ(darray);
728 FREE_IF_NZ(d2);
729 FREE_IF_NZ(d3);
730 FREE_IF_NZ(d4);
731 break;
732
733
734 case FIELDTYPE_SFString:
735 /*
736 retval->X3D_SFString.type = FIELDTYPE_SFString;
737 len = strlen(values);
738 retval->X3D_SFString.p[count].strptr = MALLOC(char *, (len+1)*sizeof(char));
739 strncpy(retval->X3D_SFString.p[count].strptr,values,len);
740 retval->X3D_SFString.strptr[len] = '\0';
741 retval->X3D_SFString.len = len;
742 */
743 retval = X3D_newSFString(values);
744 break;
745
746 case FIELDTYPE_MFString:
747 retval = malloc(sizeof(X3DNode));
748 retval->X3D_MFString.type = FIELDTYPE_MFString;
749 n = 0;
750 for(i=0;i<(int)strlen(vals);i++)
751 if( vals[i] == '\"' )n++;
752 n = n/2;
753 /*
754 c = MALLOC(char *, n*STRLEN*sizeof(char));
755 carray = MALLOC(char **, n*(sizeof(char*)));
756 for(i=0;i<n;i++)
757 carray[i] = &c[i*STRLEN];
758 */
759 retval->X3D_MFString.n = n;
760 retval->X3D_MFString.p = malloc(sizeof(X3DNode)*retval->X3D_MFString.n);
761 count = 0;
762 for(i=0,n=0;i<(int)strlen(vals);i++)
763 {
764 if( vals[i] == '\"' )
765 {
766 n++;
767 if(n%2) start = i;
768 else
769 {
770 end = i;
771 len = end - start; /* if "Y" start=0,end=2 need a string 2 long for Y and \0. len=end-start= 2-0=2 */
772 retval->X3D_MFString.p[count].strptr = MALLOC(char *, len*sizeof(char));
773 strncpy(retval->X3D_MFString.p[count].strptr,&vals[start+1],len-1);
774 /*strncpy(carray[count],&vals[start+1],len-1);
775 carray[count][len-1] = '\0';*/
776 retval->X3D_MFString.p[count].strptr[len-1] = '\0';
777 retval->X3D_MFString.p[count].len = len-1;
778 count++;
779 }
780 }
781 }
782 /*retval = X3D_newMFString(count, carray);*/
783 break;
784 }
785 FREE_IF_NZ(vals); /*free(vals);*/
786 return retval;
787}
788X3DNode* anyVrml2X3DNode(int type, union anyVrml* node)
789{
790 /*
791 anyVrml - see CParseGeneral.h L.39 and VrmlTypeList.h and Structs.h L.1270
792 Uni_String - see structs.h L.38
793 X3DNode - see X3DNode.h
794 Strategy: deepcopy from anyVrml to X3DNode (put .type on front of everything) and return
795 */
796 X3DNode* retval;
797 retval = NULL;
798 if( type%2 == 0) /* SF */
799 {
800 int i;
801 retval = X3D_newSF(type);
802 switch(type)
803 {
804 case FIELDTYPE_SFInt32:
805 retval->X3D_SFInt32.value = node->sfint32; break;
806 case FIELDTYPE_SFBool:
807 retval->X3D_SFBool.value = node->sfbool; break;
808 case FIELDTYPE_SFFloat:
809 retval->X3D_SFFloat.value = node->sffloat; break;
810 case FIELDTYPE_SFTime:
811 retval->X3D_SFTime.value = node->sftime; break;
812 case FIELDTYPE_SFColorRGBA:
813 case FIELDTYPE_SFRotation:
814 for(i=0;i<4;i++)
815 retval->X3D_SFRotation.r[i] = node->sfrotation.r[i];
816 break;
817 case FIELDTYPE_SFVec2f:
818 for(i=0;i<2;i++)
819 retval->X3D_SFVec2f.c[i] = node->sfvec2f.c[i];
820 break;
821 case FIELDTYPE_SFVec3f:
822 case FIELDTYPE_SFColor:
823 for(i=0;i<3;i++)
824 retval->X3D_SFVec3f.c[i] = node->sfvec3f.c[i];
825 break;
826 case FIELDTYPE_SFVec3d:
827 for(i=0;i<3;i++)
828 retval->X3D_SFVec3d.c[i] = node->sfvec3d.c[i];
829 break;
830 case FIELDTYPE_SFVec2d:
831 for(i=0;i<2;i++)
832 retval->X3D_SFVec2d.c[i] = node->sfvec2d.c[i];
833 break;
834 case FIELDTYPE_SFString:
835 retval->X3D_SFString.len = node->sfstring->len;
836 retval->X3D_SFString.strptr = (char*)malloc(node->sfstring->len + 1);
837 strncpy(retval->X3D_SFString.strptr,node->sfstring->strptr,node->sfstring->len+1);
838 break;
839 }
840 }
841 if( type%2 != 0) /* MF */
842 {
843 int i,j,n, sftype;
844
845 n = node->mfnode.n;
846 retval = _swigNewMF(type, n);
847 sftype = type -1;
848 switch(sftype)
849 {
850 case FIELDTYPE_SFInt32:
851 for(j=0;j<n;j++)
852 retval->X3D_MFInt32.p[j].value = node->mfint32.p[j];
853 break;
854 case FIELDTYPE_SFBool:
855 for(j=0;j<n;j++)
856 retval->X3D_MFBool.p[j].value = node->mfbool.p[j];
857 break;
858 case FIELDTYPE_SFFloat:
859 for(j=0;j<n;j++)
860 retval->X3D_MFFloat.p[j].value = node->mffloat.p[j];
861 break;
862 case FIELDTYPE_SFTime:
863 for(j=0;j<n;j++)
864 retval->X3D_MFTime.p[j].value = node->mftime.p[j];
865 break;
866 case FIELDTYPE_SFColorRGBA:
867 case FIELDTYPE_SFRotation:
868 for(j=0;j<n;j++)
869 for(i=0;i<4;i++)
870 retval->X3D_MFRotation.p[j].r[i] = node->mfrotation.p[j].r[i];
871 break;
872 case FIELDTYPE_SFVec2f:
873 for(j=0;j<n;j++)
874 for(i=0;i<2;i++)
875 retval->X3D_MFVec2f.p[j].c[i] = node->mfvec2f.p[j].c[i];
876 break;
877 case FIELDTYPE_SFVec3f:
878 case FIELDTYPE_SFColor:
879 for(j=0;j<n;j++)
880 for(i=0;i<3;i++)
881 retval->X3D_MFVec3f.p[j].c[i] = node->mfvec3f.p[j].c[i];
882 break;
883 case FIELDTYPE_SFVec3d:
884 for(j=0;j<n;j++)
885 for(i=0;i<3;i++)
886 retval->X3D_MFVec3d.p[j].c[i] = node->mfvec3d.p[j].c[i];
887 break;
888 case FIELDTYPE_SFString:
889 for(j=0;j<n;j++)
890 {
891 retval->X3D_MFString.p[j].len = node->mfstring.p[j]->len;
892 retval->X3D_MFString.p[j].strptr = (char*)malloc(node->mfstring.p[j]->len + 1);
893 strncpy(retval->X3D_MFString.p[j].strptr,node->mfstring.p[j]->strptr,node->mfstring.p[j]->len+1);
894 }
895 break;
896 }
897 }
898 return retval;
899}
900union anyVrml* getListenerData(int index);
901int getListenerType(int index);
902X3DNode* X3D_swigCallbackDataFetch(char *ListenerTableIndex)
903{
904 /* relies on:
905 a) what sarah said:
906 "the data is sent as a binary block of data, basically as the contents of X3DNode.p or equivalent.
907 If you know what type of data you are receiving from the socket (which you should after reading
908 the first number: the advise index should tie you to a specific callback function),
909 can you not read the information from the socket directly?"
910 b) doug's assumption - anyVrml:
911 When I trace it looks like if you pass coffset=0 into Parser_scanStringValueToMem as we are doing in _handleFreeWRLcallback(),
912 you get back something like SFVec2f L.1278 Structs.h which looks like our X3DNode except missing the .type,
913 and I assume it is:
914 union anyVrml - see CParseGeneral.h L.39 and VrmlTypeList.h and Structs.h L.1270
915 c) slow - the events are coming spaced out with enough time for you to fetch the data from the listenertable before it gets overwritten
916 there's no table locking.
917 Alternative: But if this isn't a good assumption, then in the handler below you can anyVrml2X3DNode right there
918 and send the malloced address instead of the listenertable index. Then on fetch, cast the address to an X3DNode.
919 */
920
921 int index, type;
922 X3DNode* retval;
923 union anyVrml* anynode;
924
925 retval = NULL;
926 if( sscanf(ListenerTableIndex,"%d",&index) < 1)
927 return retval;
928 //anynode = (union anyVrml*)EAI_ListenerTable[index].dataArea;
929 //type = EAI_ListenerTable[index].type;
930 anynode = getListenerData(index);
931 type = getListenerType(index);
932 retval = anyVrml2X3DNode(type, anynode);
933 return retval;
934}
935
936#endif