Salome HOME
PR: merge from BR_DATACONV_PR tag "mergeto_trunk_25oct06"
[modules/yacs.git] / src / runtime / TypeConversions.cxx
1
2 #include "TypeConversions.hxx"
3 #include "Exception.hxx"
4 #include "RuntimeSALOME.hxx"
5
6 #include <iostream>
7 #include <sstream>
8
9 using namespace std;
10
11 namespace YACS
12 {
13   namespace ENGINE
14   {
15
16     /*
17      * Fonctions qui retournent un TypeCode CORBA equivalent a un TypeCode Superviseur
18      */
19
20     CORBA::TypeCode_ptr getCorbaTCNull(TypeCode *t)
21     {
22       stringstream msg;
23       msg << "Conversion not implemented: kind= " << t->kind() << " : " << __FILE__ << ":" << __LINE__;
24       throw YACS::Exception(msg.str());
25     }
26
27     CORBA::TypeCode_ptr getCorbaTCDouble(TypeCode *t)
28     {
29       return CORBA::_tc_double;
30     }
31
32     CORBA::TypeCode_ptr getCorbaTCInt(TypeCode *t)
33     {
34       return CORBA::_tc_long;
35     }
36
37     CORBA::TypeCode_ptr getCorbaTCString(TypeCode *t)
38     {
39       return CORBA::_tc_string;
40     }
41
42     CORBA::TypeCode_ptr getCorbaTCObjref(TypeCode *t)
43     {
44       return CORBA::_tc_Object;
45     }
46
47     CORBA::TypeCode_ptr getCorbaTCSequence(TypeCode *t)
48     {
49       return getSALOMERuntime()->getOrb()->create_sequence_tc(0,getCorbaTC(t->content_type()));
50     }
51
52     getCorbaTCFn getCorbaTCFns[]=
53       {
54         getCorbaTCNull,
55         getCorbaTCDouble,
56         getCorbaTCInt,
57         getCorbaTCString,
58         getCorbaTCNull,
59         getCorbaTCObjref,
60         getCorbaTCSequence,
61         getCorbaTCNull,
62       };
63
64     CORBA::TypeCode_ptr getCorbaTC(TypeCode *t)
65     {
66       int tk=t->kind();
67       return getCorbaTCFns[tk](t);
68     }
69
70     /*
71      * Fin des Fonctions qui retournent un TypeCode CORBA equivalent a un TypeCode Superviseur
72      */
73
74     /*
75      * Fonctions de conversion d'un PyObject * quelconque en CORBA::Any *
76      * du type donné par le TypeCode passé en argument
77      */
78
79     //Le TypeCode passé en argument est celui du port qui recoit la donnée : InputCorbaPort
80
81     //CORBA::Any *convertCorbaPyObject(TypeCode* t,PyObject* ob);
82
83     CORBA::Any *convertCorbaPyObjectNull(TypeCode *t,PyObject *ob)
84     {
85       stringstream msg;
86       msg << "Conversion not implemented: kind= " << t->kind() << " : " << __FILE__ << ":" << __LINE__;
87       throw YACS::Exception(msg.str());
88     }
89
90     //kind = 1
91     //Conversion d'un objet Python "equivalent double" en CORBA::Any double
92
93     CORBA::Any *convertCorbaPyObjectDouble(TypeCode *t,PyObject *ob)
94     {
95       PyObject_Print(ob,stdout,Py_PRINT_RAW);
96       cerr << endl;
97       CORBA::Double d = 0;
98       if (PyFloat_Check(ob))
99         d = (CORBA::Double)PyFloat_AS_DOUBLE(ob);
100       else if (PyInt_Check(ob))
101         d = (CORBA::Double)PyInt_AS_LONG(ob);
102       else
103         d = (CORBA::Double)PyLong_AsDouble(ob);
104       CORBA::Any *any = new CORBA::Any();
105       *any <<= d;
106       return any;
107     }
108
109     //kind = 2
110
111     CORBA::Any *convertCorbaPyObjectInt(TypeCode *t,PyObject *ob)
112     {
113       PyObject_Print(ob,stdout,Py_PRINT_RAW);
114       cerr << endl;
115       CORBA::Long l;
116       if (PyInt_Check(ob))
117         l = PyInt_AS_LONG(ob);
118       else
119         l = PyLong_AsLong(ob);
120       CORBA::Any *any = new CORBA::Any();
121       *any <<= l;
122       return any;
123     }
124
125     //kind = 3
126
127     CORBA::Any *convertCorbaPyObjectString(TypeCode *t,PyObject *ob)
128     {
129       PyObject_Print(ob,stdout,Py_PRINT_RAW);
130       cerr << endl;
131       char * s=PyString_AsString(ob);
132       CORBA::Any *any = new CORBA::Any();
133       *any <<= s;
134       return any;
135     }
136
137     //kind = 5
138
139     CORBA::Any *convertCorbaPyObjectObjref(TypeCode *t,PyObject *ob)
140     {
141       PyObject_Print(ob,stdout,Py_PRINT_RAW);
142       cerr << endl;
143       PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),
144                                              "object_to_string", "O", ob);
145       CORBA::Object_ptr obref =
146         getSALOMERuntime()->getOrb()->string_to_object(PyString_AsString(pystring));
147       Py_DECREF(pystring);
148       CORBA::Any *any = new CORBA::Any();
149       *any <<= obref;
150       cerr << "typecode: " << any->type()->id() << endl;
151       return any;
152     };
153
154     //kind = 6
155
156     CORBA::Any *convertCorbaPyObjectSequence(TypeCode *t,PyObject *ob)
157     {
158       PyObject_Print(ob,stdout,Py_PRINT_RAW);
159       cerr << endl;
160       int length=PySequence_Size(ob);
161       cerr <<"length: " << length << endl;
162       CORBA::TypeCode_var tc_content;
163       DynamicAny::AnySeq as ;
164       as.length(length);
165       for(int i=0;i<length;i++)
166         {
167           PyObject *o=PySequence_ITEM(ob,i);
168           cerr <<"item[" << i << "]=";
169           PyObject_Print(o,stdout,Py_PRINT_RAW);
170           cerr << endl;
171           cerr << "o refcnt: " << o->ob_refcnt << endl;
172           CORBA::Any *a= convertCorbaPyObject(t->content_type(),o);
173           //ici on fait une copie. Peut-on l'éviter ?
174           as[i]=*a;
175           tc_content=a->type();
176           //delete a;
177           Py_DECREF(o);
178         }
179
180       CORBA::TypeCode_var tc = 
181         getSALOMERuntime()->getOrb()->create_sequence_tc(0,tc_content);
182       DynamicAny::DynAny_var dynany =
183         getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
184       DynamicAny::DynSequence_var ds =
185         DynamicAny::DynSequence::_narrow(dynany);
186
187       try
188         {
189           ds->set_elements(as);
190         }
191       catch(DynamicAny::DynAny::TypeMismatch& ex)
192         {
193           throw YACS::Exception("type mismatch");
194         }
195       catch(DynamicAny::DynAny::InvalidValue& ex)
196         {
197           throw YACS::Exception("invalid value");
198         }
199       CORBA::Any *any=ds->to_any();
200       return any;
201     }
202
203     convertCorbaPyObjectFn convertCorbaPyObjectFns[] =
204       {
205         convertCorbaPyObjectNull,
206         convertCorbaPyObjectDouble,
207         convertCorbaPyObjectInt,
208         convertCorbaPyObjectString,
209         convertCorbaPyObjectNull,
210         convertCorbaPyObjectObjref,
211         convertCorbaPyObjectSequence,
212       };
213
214     CORBA::Any *convertCorbaPyObject(TypeCode *t,PyObject *ob)
215     {
216       int tk=t->kind();
217       return convertCorbaPyObjectFns[tk](t,ob);
218     }
219
220     /*
221      * Fin des fonctions de conversion PyObject * -> CORBA::Any *
222      */
223
224     /*
225      * Fonctions de test d'adaptation pour conversion PyObject * (t1) -> CORBA::Any * (t2)
226      */
227     //t1 est le type du port output Python
228     //t2 est le type du port input Corba
229
230     int isAdaptableCorbaPyObjectNull(TypeCode *t1,TypeCode* t2)
231     {
232       return 0;
233     }
234
235     int isAdaptableCorbaPyObjectDouble(TypeCode *t1,TypeCode* t2)
236     {
237       if (t1->kind() == Double) return 1;
238       if (t1->kind() == Int) return 1;
239       return 0;
240     }
241
242     int isAdaptableCorbaPyObjectInt(TypeCode *t1,TypeCode* t2)
243     {
244       if (t1->kind() == Int) return 1;
245       return 0;
246     }
247
248     int isAdaptableCorbaPyObjectString(TypeCode *t1,TypeCode* t2)
249     {
250       if (t1->kind() == String)return 1;
251       return 0;
252     }
253
254     int isAdaptableCorbaPyObjectObjref(TypeCode *t1,TypeCode* t2)
255     {
256       if(t1->kind() == Objref)
257         {
258           //Il faut que le type du inport soit plus général que celui du outport
259           if ( t1->is_a(t2->id()) ) return 1;
260         }
261       return 0;
262     }
263
264     int isAdaptableCorbaPyObjectSequence(TypeCode *t1,TypeCode* t2)
265     {
266       if(t1->kind() == Sequence)
267         {
268           if(isAdaptableCorbaPyObject(t1->content_type(),t2->content_type()))
269             {
270               return 1;
271             }
272         }
273       return 0;
274     }
275
276     isAdaptableCorbaPyObjectFn isAdaptableCorbaPyObjectFns[]=
277       {
278         isAdaptableCorbaPyObjectNull,
279         isAdaptableCorbaPyObjectDouble,
280         isAdaptableCorbaPyObjectInt,
281         isAdaptableCorbaPyObjectString,
282         isAdaptableCorbaPyObjectNull,
283         isAdaptableCorbaPyObjectObjref,
284         isAdaptableCorbaPyObjectSequence,
285       };
286
287     int isAdaptableCorbaPyObject(TypeCode *t1,TypeCode *t2)
288     {
289       int tk=t2->kind();
290       return isAdaptableCorbaPyObjectFns[tk](t1,t2);
291     }
292
293     /*
294      * Fin des fonctions d'adaptation pour conversion PyObject * -> CORBA::Any *
295      */
296
297     /*
298      * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> Xml::char * (t2)
299      */
300     //t1 est le type du port output Corba
301     //t2 est le type du port input Xml
302
303     int isAdaptableXmlCorbaNull(TypeCode *t1,TypeCode* t2)
304     {
305       return 0;
306     }
307
308     int isAdaptableXmlCorbaDouble(TypeCode *t1,TypeCode* t2)
309     {
310       if(t1->kind() == Double)return 1;
311       if(t1->kind() == Int)return 1;
312       return 0;
313     }
314
315     int isAdaptableXmlCorbaInt(TypeCode *t1,TypeCode* t2)
316     {
317       if(t1->kind() == Int)return 1;
318       return 0;
319     }
320
321     int isAdaptableXmlCorbaString(TypeCode *t1,TypeCode* t2)
322     {
323       if(t1->kind() == String)return 1;
324       return 0;
325     }
326
327     int isAdaptableXmlCorbaObjref(TypeCode *t1,TypeCode* t2)
328     {
329       if(t1->kind() == Objref)
330         {
331           //Il faut que le type du inport soit plus général que celui du outport
332           if( t1->is_a(t2->id()) )return 1;
333         }
334       return 0;
335     }
336
337     int isAdaptableXmlCorbaSequence(TypeCode *t1,TypeCode* t2)
338     {
339       if(t1->kind() == Sequence)
340         {
341           if(isAdaptableXmlCorba(t1->content_type(),t2->content_type()))
342             {
343               return 1;
344             }
345         }
346       return 0;
347     }
348
349     isAdaptableXmlCorbaFn isAdaptableXmlCorbaFns[]=
350       {
351         isAdaptableXmlCorbaNull,
352         isAdaptableXmlCorbaDouble,
353         isAdaptableXmlCorbaInt,
354         isAdaptableXmlCorbaString,
355         isAdaptableXmlCorbaNull,
356         isAdaptableXmlCorbaObjref,
357         isAdaptableXmlCorbaSequence,
358       };
359
360     int isAdaptableXmlCorba(TypeCode *t1,TypeCode *t2)
361     {
362       int tk=t2->kind();
363       return isAdaptableXmlCorbaFns[tk](t1,t2);
364     }
365
366     /*
367      * Fin des fonctions d'adaptation pour conversion CORBA::Any * (t1) -> Xml::char * (t2)
368      */
369
370     /*
371      * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> CORBA::Any * (t2)
372      */
373     //t1 est le type du port output Corba
374     //t2 est le type du port input Corba
375
376     int isAdaptableCorbaCorbaNull(TypeCode *t1,TypeCode* t2)
377     {
378       return 0;
379     }
380
381     int isAdaptableCorbaCorbaDouble(TypeCode *t1,TypeCode* t2)
382     {
383       if(t1->kind() == Double)return 1;
384       if(t1->kind() == Int)return 1;
385       return 0;
386     }
387
388     int isAdaptableCorbaCorbaInt(TypeCode *t1,TypeCode* t2)
389     {
390       if(t1->kind() == Int)return 1;
391       return 0;
392     }
393
394     int isAdaptableCorbaCorbaString(TypeCode *t1,TypeCode* t2)
395     {
396       if(t1->kind() == String)return 1;
397       return 0;
398     }
399
400     int isAdaptableCorbaCorbaObjref(TypeCode *t1,TypeCode* t2)
401     {
402       if(t1->kind() == Objref){
403         //Il faut que le type du inport soit plus général que celui du outport
404         if( t1->is_a(t2->id()) )return 1;
405       }
406       return 0;
407     }
408
409     int isAdaptableCorbaCorbaSequence(TypeCode *t1,TypeCode* t2)
410     {
411       if(t1->kind() == Sequence)
412         {
413           if(isAdaptableCorbaCorba(t1->content_type(),t2->content_type()))
414             {
415               return 1;
416             }
417         }
418       return 0;
419     }
420
421     isAdaptableCorbaCorbaFn isAdaptableCorbaCorbaFns[]=
422       {
423         isAdaptableCorbaCorbaNull,
424         isAdaptableCorbaCorbaDouble,
425         isAdaptableCorbaCorbaInt,
426         isAdaptableCorbaCorbaString,
427         isAdaptableCorbaCorbaNull,
428         isAdaptableCorbaCorbaObjref,
429         isAdaptableCorbaCorbaSequence,
430       };
431
432     int isAdaptableCorbaCorba(TypeCode *t1,TypeCode *t2)
433     {
434       int tk=t2->kind();
435       return isAdaptableCorbaCorbaFns[tk](t1,t2);
436     }
437
438     /*
439      * Fin des fonctions d'adaptation pour conversion CORBA::Any * -> CORBA::Any *
440      */
441
442     /*
443      * Fonctions de test d'adaptation pour conversion PyObject * (t1) -> PyObject * (t2)
444      */
445     //t1 est le type du port output Python
446     //t2 est le type du port input Python
447
448     int isAdaptablePyObjectPyObjectNull(TypeCode *t1,TypeCode* t2)
449     {
450       return 0;
451     }
452
453     int isAdaptablePyObjectPyObjectDouble(TypeCode *t1,TypeCode* t2)
454     {
455       if(t1->kind() == Double)return 1;
456       if(t1->kind() == Int)return 1;
457       return 0;
458     }
459
460     int isAdaptablePyObjectPyObjectInt(TypeCode *t1,TypeCode* t2)
461     {
462       if(t1->kind() == Int)return 1;
463       return 0;
464     }
465
466     int isAdaptablePyObjectPyObjectString(TypeCode *t1,TypeCode* t2)
467     {
468       if(t1->kind() == String)return 1;
469       return 0;
470     }
471
472     int isAdaptablePyObjectPyObjectObjref(TypeCode *t1,TypeCode* t2)
473     {
474       if(t1->kind() == Objref)
475         {
476           //Il faut que le type du inport soit plus général que celui du outport
477           if( t1->is_a(t2->id()) )return 1;
478         }
479       return 0;
480     }
481
482     int isAdaptablePyObjectPyObjectSequence(TypeCode *t1,TypeCode* t2)
483     {
484       if(t1->kind() == Sequence)
485         {
486           if(isAdaptablePyObjectPyObject(t1->content_type(),t2->content_type()))
487             {
488               return 1;
489             }
490         }
491       return 0;
492     }
493
494     isAdaptablePyObjectPyObjectFn isAdaptablePyObjectPyObjectFns[]=
495       {
496         isAdaptablePyObjectPyObjectNull,
497         isAdaptablePyObjectPyObjectDouble,
498         isAdaptablePyObjectPyObjectInt,
499         isAdaptablePyObjectPyObjectString,
500         isAdaptablePyObjectPyObjectNull,
501         isAdaptablePyObjectPyObjectObjref,
502         isAdaptablePyObjectPyObjectSequence,
503       };
504
505     int isAdaptablePyObjectPyObject(TypeCode *t1,TypeCode *t2)
506     {
507       int tk=t2->kind();
508       return isAdaptablePyObjectPyObjectFns[tk](t1,t2);
509     }
510
511     /*
512      * Fin des fonctions d'adaptation pour conversion PyObject * -> PyObject *
513      */
514
515     /*
516      * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> PyObject * (t2)
517      */
518     //t1 est le type du port output Corba
519     //t2 est le type du port input Python
520
521     int isAdaptablePyObjectCorbaNull(TypeCode *t1,TypeCode* t2)
522     {
523       return 0;
524     }
525
526     //on peut convertir un double ou un int en CORBA double
527     int isAdaptablePyObjectCorbaDouble(TypeCode *t1,TypeCode* t2)
528     {
529       if(t1->kind() == Double)return 1;
530       if(t1->kind() == Int)return 1;
531       return 0;
532     }
533
534     int isAdaptablePyObjectCorbaInt(TypeCode *t1,TypeCode* t2)
535     {
536       if(t1->kind() == Int)return 1;
537       return 0;
538     }
539
540     int isAdaptablePyObjectCorbaString(TypeCode *t1,TypeCode* t2)
541     {
542       if(t1->kind() == String)return 1;
543       return 0;
544     }
545
546     int isAdaptablePyObjectCorbaObjref(TypeCode *t1,TypeCode* t2)
547     {
548       if(t1->kind() == Objref){
549         //Il faut que le type du inport soit plus général que celui du outport
550         if( t1->is_a(t2->id()) )return 1;
551       }
552       return 0;
553     }
554
555     int isAdaptablePyObjectCorbaSequence(TypeCode *t1,TypeCode* t2)
556     {
557       if(t1->kind() == Sequence)
558         {
559           if(isAdaptablePyObjectCorba(t1->content_type(),t2->content_type()))
560             {
561               return 1;
562             }
563         }
564       return 0;
565     }
566
567     isAdaptablePyObjectCorbaFn isAdaptablePyObjectCorbaFns[]={
568       isAdaptablePyObjectCorbaNull,
569       isAdaptablePyObjectCorbaDouble,
570       isAdaptablePyObjectCorbaInt,
571       isAdaptablePyObjectCorbaString,
572       isAdaptablePyObjectCorbaNull,
573       isAdaptablePyObjectCorbaObjref,
574       isAdaptablePyObjectCorbaSequence,
575     };
576
577     int isAdaptablePyObjectCorba(TypeCode *t1,TypeCode *t2)
578     {
579       int tk=t2->kind();
580       return isAdaptablePyObjectCorbaFns[tk](t1,t2);
581     }
582
583     /*
584      * Fin des fonctions d'adaptation pour conversion CORBA::Any * -> PyObject *
585      */
586
587     /*
588      * Fonctions de conversion CORBA::Any * -> PyObject *
589      */
590     //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort)
591     //On a le type Corba de l'objet sortant par ob->type()
592
593     PyObject *convertPyObjectCorbaNull(TypeCode *t,CORBA::Any *ob)
594     {
595       stringstream msg;
596       msg << "Conversion not implemented: kind= " << t->kind() ;
597       msg << " : " << __FILE__ << ":" << __LINE__;
598       throw YACS::Exception(msg.str());
599     }
600
601     //kind=1
602     //Convertit un CORBA::Any "equivalent double" en Python double
603
604     PyObject *convertPyObjectCorbaDouble(TypeCode *t,CORBA::Any *ob)
605     {
606       CORBA::TypeCode_var tc = ob->type();
607       if (tc->equivalent(CORBA::_tc_double)) 
608         {
609           CORBA::Double d;
610           *ob >>= d;
611           PyObject *pyob=PyFloat_FromDouble(d);
612           cerr << "pyob refcnt: " << pyob->ob_refcnt << endl;
613           return pyob;
614         }
615       if (tc->equivalent(CORBA::_tc_long))
616         {
617           CORBA::Long d;
618           *ob >>= d;
619           //Faudrait-il convertir en PyFloat ??
620           PyObject *pyob=PyInt_FromLong(d);
621           cerr << "pyob refcnt: " << pyob->ob_refcnt << endl;
622           return pyob;
623         }
624       stringstream msg;
625       msg << "Internal error " ;
626       msg << " : " << __FILE__ << ":" << __LINE__;
627       throw YACS::Exception(msg.str());
628     }
629
630     PyObject *convertPyObjectCorbaInt(TypeCode *t,CORBA::Any *ob)
631     {
632       CORBA::Long l;
633       *ob >>= l;
634       return PyInt_FromLong(l);
635     }
636
637     PyObject *convertPyObjectCorbaString(TypeCode *t,CORBA::Any *ob)
638     {
639       char *s;
640       *ob >>=s;
641       PyObject *pyob=PyString_FromString(s);
642       cerr << "pyob refcnt: " << pyob->ob_refcnt << endl;
643       return pyob;
644     }
645
646     PyObject *convertPyObjectCorbaObjref(TypeCode *t,CORBA::Any *ob)
647     {
648       CORBA::Object_ptr ObjRef ;
649       *ob >>= (CORBA::Any::to_object ) ObjRef ;
650       //hold_lock is true: caller is supposed to hold the GIL.
651       //omniorb will not take the GIL
652       PyObject *pyob = getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(ObjRef, 1);
653       cerr << "pyob refcnt: " << pyob->ob_refcnt << endl;
654       return pyob;
655     }
656
657     PyObject *convertPyObjectCorbaSequence(TypeCode *t,CORBA::Any *ob)
658     {
659       cerr << "convertPyObjectCorbaSequence" << endl;
660       DynamicAny::DynAny_var dynany= getSALOMERuntime()->getDynFactory()->create_dyn_any(*ob);
661       DynamicAny::DynSequence_var ds=DynamicAny::DynSequence::_narrow(dynany);
662       DynamicAny::AnySeq_var as=ds->get_elements();
663       int len=as->length();
664       PyObject *pyob = PyList_New(len);
665       for(int i=0;i<len;i++)
666         {
667           PyObject *e=convertPyObjectCorba(t->content_type(),&as[i]);
668           cerr << "e refcnt: " << e->ob_refcnt << endl;
669           PyList_SetItem(pyob,i,e);
670           cerr << "e refcnt: " << e->ob_refcnt << endl;
671         }
672       cerr << "pyob refcnt: " << pyob->ob_refcnt << endl;
673       cerr << "Sequence= ";
674       PyObject_Print(pyob,stdout,Py_PRINT_RAW);
675       cerr << endl;
676       return pyob;
677     }
678
679
680     convertPyObjectCorbaFn convertPyObjectCorbaFns[]=
681       {
682         convertPyObjectCorbaNull,
683         convertPyObjectCorbaDouble,
684         convertPyObjectCorbaInt,
685         convertPyObjectCorbaString,
686         convertPyObjectCorbaNull,
687         convertPyObjectCorbaObjref,
688         convertPyObjectCorbaSequence,
689       };
690
691     PyObject *convertPyObjectCorba(TypeCode *t,CORBA::Any *ob)
692     {
693       int tk=t->kind();
694       return convertPyObjectCorbaFns[tk](t,ob);
695     }
696
697     /*
698      * Fin des fonctions de conversion CORBA::Any * -> PyObject *
699      */
700
701     /*
702      * Fonctions de conversion CORBA::Any * -> Xml char *
703      */
704     //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort)
705     //On a le type Corba de l'objet sortant par ob->type()
706
707     char *convertXmlCorbaNull(TypeCode *t,CORBA::Any *ob)
708     {
709       stringstream msg;
710       msg << "Conversion not implemented: kind= " << t->kind() ;
711       msg << " : " << __FILE__ << ":" << __LINE__;
712       throw YACS::Exception(msg.str());
713     }
714
715     //kind=1
716     //Convertit un CORBA::Any "equivalent double" en Python double
717
718     char *convertXmlCorbaDouble(TypeCode *t,CORBA::Any *ob)
719     {
720       CORBA::TypeCode_var tc = ob->type();
721       if (tc->equivalent(CORBA::_tc_double))
722         {
723           CORBA::Double d;
724           *ob >>= d;
725           stringstream msg ;
726           msg << "<value><double>" << d << "</double></value>\n";
727           return (char *)msg.str().c_str();
728         }
729       if (tc->equivalent(CORBA::_tc_long))
730         {
731           CORBA::Long d;
732           *ob >>= d;
733           stringstream msg;
734           msg << "<value><double>" << d << "</double></value>\n";
735           return (char *)msg.str().c_str();
736         }
737       stringstream msg;
738       msg << "Internal error " ;
739       msg << " : " << __FILE__ << ":" << __LINE__;
740       throw YACS::Exception(msg.str());
741     }
742
743     char *convertXmlCorbaInt(TypeCode *t,CORBA::Any *ob)
744     {
745       CORBA::Long l;
746       *ob >>= l;
747       stringstream msg ;
748       msg << "<value><int>" << l << "</int></value>\n";
749       return (char *)msg.str().c_str();
750     }
751
752     char *convertXmlCorbaString(TypeCode *t,CORBA::Any *ob)
753     {
754       char *s;
755       *ob >>=s;
756       stringstream msg ;
757       msg << "<value><string>" << s << "</string></value>\n";
758       return (char *)msg.str().c_str();
759     }
760
761     char *convertXmlCorbaObjref(TypeCode *t,CORBA::Any *ob)
762     {
763       CORBA::Object_ptr ObjRef ;
764       *ob >>= (CORBA::Any::to_object ) ObjRef ;
765       stringstream msg ;
766       msg << "<value><objref>" << getSALOMERuntime()->getOrb()->object_to_string(ObjRef) << "</objref></value>\n";
767       return (char *)msg.str().c_str();
768     }
769
770     char *convertXmlCorbaSequence(TypeCode *t,CORBA::Any *ob)
771     {
772       cerr << "convertXmlCorbaSequence" << endl;
773       DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*ob);
774       DynamicAny::DynSequence_var ds=DynamicAny::DynSequence::_narrow(dynany);
775       DynamicAny::AnySeq_var as=ds->get_elements();
776       int len=as->length();
777       stringstream xmlob;
778       xmlob << "<value><array><data>\n";
779       for(int i=0;i<len;i++)
780         {
781           xmlob << convertXmlCorba(t->content_type(),&as[i]);
782         }
783       xmlob << "</data></array></value>\n";
784       cerr << "Sequence= ";
785       cerr << xmlob;
786       cerr << endl;
787       return (char *)xmlob.str().c_str();
788     }
789
790     convertXmlCorbaFn convertXmlCorbaFns[]=
791       {
792         convertXmlCorbaNull,
793         convertXmlCorbaDouble,
794         convertXmlCorbaInt,
795         convertXmlCorbaString,
796         convertXmlCorbaNull,
797         convertXmlCorbaObjref,
798         convertXmlCorbaSequence,
799       };
800
801     char *convertXmlCorba(TypeCode *t,CORBA::Any *ob)
802     {
803       int tk=t->kind();
804       return convertXmlCorbaFns[tk](t,ob);
805     }
806
807     /*
808      * Fin des fonctions de conversion CORBA::Any * -> Xml char *
809      */
810
811     /*
812      * Fonctions de conversion CORBA::Any * -> CORBA::Any *
813      */
814     //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort)
815     //On a le type Corba de l'objet sortant par ob->type()
816
817     CORBA::Any *convertCorbaCorbaNull(TypeCode *t,CORBA::Any *ob)
818     {
819       stringstream msg;
820       msg << "Conversion not implemented: kind= " << t->kind() ;
821       msg << " : " << __FILE__ << ":" << __LINE__;
822       throw YACS::Exception(msg.str());
823     };
824
825     //kind=1
826     //Convertit un CORBA::Any "equivalent double" en Python double
827
828     CORBA::Any *convertCorbaCorbaDouble(TypeCode *t,CORBA::Any *ob)
829     {
830       CORBA::TypeCode_var tc = ob->type();
831       if (tc->equivalent(CORBA::_tc_double)) 
832         {
833           return ob;
834         }
835       if (tc->equivalent(CORBA::_tc_long))
836         {
837           CORBA::Long d;
838           *ob >>= d;
839           CORBA::Any *any = new CORBA::Any();
840           *any <<= (CORBA::Double)d;
841           return any;
842         }
843       stringstream msg;
844       msg << "Internal error " ;
845       msg << " : " << __FILE__ << ":" << __LINE__;
846       throw YACS::Exception(msg.str());
847     }
848
849     CORBA::Any *convertCorbaCorbaInt(TypeCode *t,CORBA::Any *ob)
850     {
851       return ob;
852     }
853
854     CORBA::Any *convertCorbaCorbaString(TypeCode *t,CORBA::Any *ob)
855     {
856       return ob;
857     }
858
859     CORBA::Any *convertCorbaCorbaObjref(TypeCode *t,CORBA::Any *ob)
860     {
861       return ob;
862     }
863
864     CORBA::Any *convertCorbaCorbaSequence(TypeCode *t,CORBA::Any *ob)
865     {
866       cerr << "convertCorbaCorbaSequence" << endl;
867       DynamicAny::DynAny_var dynany= getSALOMERuntime()->getDynFactory()->create_dyn_any(*ob);
868       DynamicAny::DynSequence_var ds=DynamicAny::DynSequence::_narrow(dynany);
869       DynamicAny::AnySeq_var as=ds->get_elements();
870       int length=as->length();
871       CORBA::TypeCode_var tc_content;
872       DynamicAny::AnySeq asout ;
873       asout.length(length);
874       for(int i=0;i<length;i++)
875         {
876           CORBA::Any *a=convertCorbaCorba(t->content_type(),&as[i]);
877           //ici on fait une copie. Peut-on l'éviter ?
878           asout[i]=*a;
879           tc_content=a->type();
880           //delete a;
881         }
882       CORBA::TypeCode_var tc= getSALOMERuntime()->getOrb()->create_sequence_tc(0,tc_content);
883       DynamicAny::DynAny_var dynanyout=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
884       DynamicAny::DynSequence_var dsout=DynamicAny::DynSequence::_narrow(dynanyout);
885       try
886         {
887           dsout->set_elements(asout);
888         }
889       catch(DynamicAny::DynAny::TypeMismatch& ex)
890         {
891           throw YACS::Exception("type mismatch");
892         }
893       catch(DynamicAny::DynAny::InvalidValue& ex)
894         {
895           throw YACS::Exception("invalid value");
896         }
897       CORBA::Any *any=dsout->to_any();
898       return any;
899     }
900
901
902     convertCorbaCorbaFn convertCorbaCorbaFns[]=
903       {
904         convertCorbaCorbaNull,
905         convertCorbaCorbaDouble,
906         convertCorbaCorbaInt,
907         convertCorbaCorbaString,
908         convertCorbaCorbaNull,
909         convertCorbaCorbaObjref,
910         convertCorbaCorbaSequence,
911       };
912
913     CORBA::Any *convertCorbaCorba(TypeCode *t,CORBA::Any *ob)
914     {
915       int tk=t->kind();
916       return convertCorbaCorbaFns[tk](t,ob);
917     }
918
919     /*
920      * Fin des fonctions de conversion CORBA::Any * -> PyObject *
921      */
922
923     /*
924      * Fonctions de conversion Xml char * -> CORBA::Any *
925      */
926
927     //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort)
928     
929     CORBA::Any *convertCorbaXmlNull(TypeCode *t, xmlDocPtr doc, xmlNodePtr cur)
930     {
931       stringstream msg;
932       msg << "Conversion not implemented: kind= " << t->kind() ;
933       msg << " : " << __FILE__ << ":" << __LINE__;
934       throw YACS::Exception(msg.str());
935     }
936     
937     CORBA::Any *convertCorbaXmlDouble(TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
938     {
939       cur = cur->xmlChildrenNode;
940       while (cur != NULL)
941         {
942           if ((!xmlStrcmp(cur->name, (const xmlChar *)"double")))
943             {
944               //on attend un double, on a bien un double
945               xmlChar * s = NULL;
946               s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
947               CORBA::Any *any = new CORBA::Any();
948               cerr << "convertCorbaXmlDouble " << (const char *)s << endl;
949               *any <<= (CORBA::Double)atof((const char *)s);
950               xmlFree(s);
951               return any;
952             }
953           else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
954             {
955               //on attend un double, on a un int
956               xmlChar * s = NULL;
957               s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
958               CORBA::Any *any = new CORBA::Any();
959               cerr << "convertCorbaXmlDouble " << (const char *)s << endl;
960               *any <<= (CORBA::Double)atof((const char *)s);
961               xmlFree(s);
962               return any;
963             }
964           cur = cur->next;
965         }
966       stringstream msg;
967       msg << "Problem in conversion: kind= " << t->kind() ;
968       msg << " : " << __FILE__ << ":" << __LINE__;
969       throw YACS::Exception(msg.str());
970     }
971     
972     CORBA::Any *convertCorbaXmlSequence(TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
973     {
974       CORBA::TypeCode_var tc_content;
975       DynamicAny::AnySeq as ;
976       int len=0;
977       cur = cur->xmlChildrenNode;
978       while (cur != NULL)
979         {
980           if ((!xmlStrcmp(cur->name, (const xmlChar *)"array"))) 
981             {
982               cerr << "parse sequence " << endl;
983               xmlNodePtr cur1=cur->xmlChildrenNode;
984               while (cur1 != NULL)
985                 {
986                   if ((!xmlStrcmp(cur1->name, (const xmlChar *)"data")))
987                     {
988                       cerr << "parse data " << endl;
989                       xmlNodePtr cur2=cur1->xmlChildrenNode;
990                     while (cur2 != NULL)
991                       {
992                         //on recupere toutes les values
993                         if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
994                           {
995                             cerr << "parse value " << endl;
996                             CORBA::Any *a=convertCorbaXml(t->content_type(),doc,cur2);
997                             as.length(len+1);
998                             as[len++]=*a;
999                             tc_content=a->type();
1000                           }
1001                         cur2 = cur2->next;
1002                       } // end while value
1003                     break;
1004                     }
1005                   cur1 = cur1->next;
1006                 } // end while data
1007               break;
1008             }
1009           cur = cur->next;
1010         } // end while array
1011
1012       CORBA::TypeCode_var tc=getSALOMERuntime()->getOrb()->create_sequence_tc(0,tc_content);
1013       DynamicAny::DynAny_var dynanyout=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
1014       DynamicAny::DynSequence_var dsout=DynamicAny::DynSequence::_narrow(dynanyout);
1015     try
1016       {
1017         dsout->set_elements(as);
1018       }
1019     catch(DynamicAny::DynAny::TypeMismatch& ex)
1020       {
1021         throw YACS::Exception("type mismatch");
1022       }
1023     catch(DynamicAny::DynAny::InvalidValue& ex)
1024       {
1025         throw YACS::Exception("invalid value");
1026       }
1027     CORBA::Any *any=dsout->to_any();
1028     return any;
1029     }
1030
1031     convertCorbaXmlFn convertCorbaXmlFns[]=
1032       {
1033         convertCorbaXmlNull,
1034         convertCorbaXmlDouble,
1035         convertCorbaXmlNull,
1036         convertCorbaXmlNull,
1037         convertCorbaXmlNull,
1038         convertCorbaXmlNull,
1039         convertCorbaXmlSequence,
1040       };
1041
1042     CORBA::Any *convertCorbaXml(TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1043     {
1044       int tk=t->kind();
1045       return convertCorbaXmlFns[tk](t,doc,cur);
1046     }
1047
1048     /*
1049      * Fin des fonctions de conversion Xml char * -> CORBA::Any *
1050      */
1051
1052   }
1053 }