Salome HOME
updated copyright message
[modules/yacs.git] / src / runtime / TypeConversions.cxx
1 // Copyright (C) 2006-2023  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //#define REFCNT
21 //
22 #ifdef REFCNT
23 #define private public
24 #define protected public
25 #include <omniORB4/CORBA.h>
26 #include <omniORB4/internal/typecode.h>
27 #endif
28
29 #include "TypeConversions.hxx"
30 #include "ConversionException.hxx"
31 #include "RuntimeSALOME.hxx"
32 #include "Salome_file_i.hxx"
33 #include "TypeCode.hxx"
34 #include "Cstr2d.hxx"
35 #include "SALOME_GenericObj.hh"
36
37 #include <iostream>
38 #include <iomanip>
39 #include <sstream>
40
41 #ifdef WIN32
42 #include <fcntl.h>
43 #define _S_IREAD 256
44 #define _S_IWRITE 128
45 int mkstemp(char *tmpl)
46 {
47   int ret=-1;
48   mktemp(tmpl); ret=open(tmpl,O_RDWR|O_BINARY|O_CREAT|O_EXCL|_O_SHORT_LIVED, _S_IREAD|_S_IWRITE);
49   return ret;
50 }
51 #endif
52
53 //#define _DEVDEBUG_
54 #include "YacsTrace.hxx"
55
56 using namespace std;
57
58 namespace YACS
59 {
60   namespace ENGINE
61   {
62     std::string getImplName(ImplType impl)
63       {
64          switch(impl)
65            {
66            case CORBAImpl:
67              return "CORBA";
68            case PYTHONImpl:
69              return "PYTHON";
70            case NEUTRALImpl:
71              return "NEUTRAL";
72            case XMLImpl:
73              return "XML";
74            case CPPImpl:
75              return "CPP";
76            default:
77              return "UNKNOWN";
78            }
79       }
80     /*
81      * Functions to return a CORBA TypeCode equivalent to a YACS TypeCode
82      */
83
84     typedef CORBA::TypeCode_ptr (*getCorbaTCFn)(const TypeCode *);
85
86     CORBA::TypeCode_ptr getCorbaTCNull(const TypeCode *t)
87       {
88         stringstream msg;
89         msg << "Conversion not implemented: kind= " << t->kind();
90         msg << " : " << __FILE__ << ":" << __LINE__;
91         throw YACS::ENGINE::ConversionException(msg.str());
92       }
93
94     CORBA::TypeCode_ptr getCorbaTCDouble(const TypeCode *t)
95     {
96       return CORBA::TypeCode::_duplicate(CORBA::_tc_double);
97     }
98
99     CORBA::TypeCode_ptr getCorbaTCInt(const TypeCode *t)
100     {
101       return CORBA::TypeCode::_duplicate(CORBA::_tc_long);
102     }
103
104     CORBA::TypeCode_ptr getCorbaTCString(const TypeCode *t)
105     {
106       return CORBA::TypeCode::_duplicate(CORBA::_tc_string);
107     }
108
109     CORBA::TypeCode_ptr getCorbaTCBool(const TypeCode *t)
110     {
111       return CORBA::TypeCode::_duplicate(CORBA::_tc_boolean);
112     }
113
114     CORBA::TypeCode_ptr getCorbaTCObjref(const TypeCode *t)
115     {
116       DEBTRACE( t->name() << " " << t->shortName() << " " << t->id());
117       CORBA::TypeCode_ptr tc;
118       if(strncmp(t->id(),"python",6)==0 )
119         tc= CORBA::TypeCode::_duplicate(Engines::_tc_fileBlock);
120       else if(strncmp(t->id(),"json",4)==0)
121         tc= CORBA::TypeCode::_duplicate(CORBA::_tc_string);
122       else
123         tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName());
124 #ifdef REFCNT
125       DEBTRACE("refcount CORBA tc Objref: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
126 #endif
127       return tc;
128     }
129
130     CORBA::TypeCode_ptr getCorbaTCSequence(const TypeCode *t)
131     {
132       CORBA::TypeCode_var content_type=getCorbaTC(t->contentType());
133       CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_sequence_tc(0,content_type);
134 #ifdef REFCNT
135       DEBTRACE("refcount CORBA content_type: " << ((omni::TypeCode_base*)content_type.in())->pd_ref_count);
136       DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
137 #endif
138       return tc;
139     }
140
141     CORBA::TypeCode_ptr getCorbaTCStruct(const TypeCode *t)
142     {
143       CORBA::StructMemberSeq mseq;
144       YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
145       int nMember=tst->memberCount();
146       mseq.length(nMember);
147       for(int i=0;i<nMember;i++)
148         {
149           const char * name=tst->memberName(i);
150           TypeCode* tm=tst->memberType(i);
151           mseq[i].name=CORBA::string_dup(name);
152           mseq[i].type=getCorbaTC(tm);
153         }
154       CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_struct_tc(t->id(),t->shortName(),mseq);
155 #ifdef REFCNT
156       DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
157 #endif
158       return tc;
159     }
160
161     getCorbaTCFn getCorbaTCFns[]=
162       {
163         getCorbaTCNull,
164         getCorbaTCDouble,
165         getCorbaTCInt,
166         getCorbaTCString,
167         getCorbaTCBool,
168         getCorbaTCObjref,
169         getCorbaTCSequence,
170         getCorbaTCNull,
171         getCorbaTCStruct,
172       };
173
174     CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t)
175     {
176       int tk=t->kind();
177       return getCorbaTCFns[tk](t);
178     }
179
180     /*
181      * End of Functions to return a CORBA TypeCode equivalent to a YACS TypeCode
182      */
183
184     /*
185      * Section that defines functions to check adaptation from one implementation to another
186      * isAdaptable is template function that checks if TypeCode t1 from implementation IMPLIN
187      * can be converted to TypeCode t2 from implementation IMPLOUT
188      * IMPLIN is the implementation of an output port
189      * IMPLOUT is the implementation of an input port
190      * If the check is True, the input port can be adapted to the output port
191      */
192
193     template <ImplType IMPLIN,ImplType IMPLOUT> inline int isAdaptable(const TypeCode *t1,const TypeCode* t2);
194
195     template <ImplType IMPLIN,ImplType IMPLOUT>
196     struct isAdaptableDouble
197       {
198         static inline int apply(const TypeCode *t1,const TypeCode* t2)
199           {
200             if(t1->kind() == Double)return 1;
201             if(t1->kind() == Int)return 1;
202             return 0;
203           }
204       };
205     template <ImplType IMPLIN,ImplType IMPLOUT>
206     struct isAdaptableInt
207       {
208         static inline int apply(const TypeCode *t1,const TypeCode* t2)
209           {
210             if(t1->kind() == Int)return 1;
211             return 0;
212           }
213       };
214     template <ImplType IMPLIN,ImplType IMPLOUT>
215     struct isAdaptableString
216       {
217         static inline int apply(const TypeCode *t1,const TypeCode* t2)
218           {
219             if(t1->kind() == String)return 1;
220             return 0;
221           }
222       };
223     template <ImplType IMPLIN,ImplType IMPLOUT>
224     struct isAdaptableBool
225       {
226         static inline int apply(const TypeCode *t1,const TypeCode* t2)
227           {
228             if(t1->kind() == Bool)return 1;
229             if(t1->kind() == Int)return 1;
230             return 0;
231           }
232       };
233     template <ImplType IMPLIN,ImplType IMPLOUT>
234     struct isAdaptableObjref
235       {
236         static inline int apply(const TypeCode *t1,const TypeCode* t2)
237           {
238             if(t1->kind() == Objref)
239               {
240                 //The inport type must be more general than outport type
241                 if( t1->isA(t2->id()) )
242                   return 1;
243               }
244             else if(t1->kind() == Sequence)
245               {
246                 const TypeCodeSeq *t1c(dynamic_cast<const TypeCodeSeq *>(t1));
247                 if(!t1c)
248                   return 0;
249                 const TypeCode *t1cc(t1c->contentType());
250                 if(t1cc==t2)
251                   return 1;
252                 if(t1cc->kind() == Objref && std::string(t1cc->id())==std::string(t2->id()))
253                   return 1;
254               }
255             return 0;
256           }
257       };
258     template <ImplType IMPLIN,ImplType IMPLOUT>
259     struct isAdaptableSequence
260       {
261         static inline int apply(const TypeCode *t1,const TypeCode* t2)
262           {
263             if(t1->kind() == Sequence)
264               {
265                 if(isAdaptable<IMPLIN,IMPLOUT>(t1->contentType(),t2->contentType()))
266                   {
267                     return 1;
268                   }
269               }
270             return 0;
271           }
272       };
273     template <ImplType IMPLIN,ImplType IMPLOUT>
274     struct isAdaptableArray
275       {
276         static inline int apply(const TypeCode *t1,const TypeCode* t2)
277           {
278             return 0;
279           }
280       };
281     template <ImplType IMPLIN,ImplType IMPLOUT>
282     struct isAdaptableStruct
283       {
284         static inline int apply(const TypeCode *t1,const TypeCode* t2)
285           {
286             if(t1->kind() == Struct)
287               {
288                 if( t1->isA(t2) )
289                   return 1;
290               }
291             return 0;
292           }
293       };
294
295     /*
296      * Function to check adaptation from implementation 1 (IMPLIN,t1) to implementation 2 (IMPLOUT,t2)
297      * t1 is the IMPLIN output port type
298      * t2 is the IMPLOUT input port type
299      */
300     template <ImplType IMPLIN,ImplType IMPLOUT>
301     inline int isAdaptable(const TypeCode *t1,const TypeCode* t2)
302       {
303          switch(t2->kind())
304            {
305            case Double:
306              return isAdaptableDouble<IMPLIN,IMPLOUT>::apply(t1,t2);
307            case Int:
308              return isAdaptableInt<IMPLIN,IMPLOUT>::apply(t1,t2);
309            case String:
310              return isAdaptableString<IMPLIN,IMPLOUT>::apply(t1,t2);
311            case Bool:
312              return isAdaptableBool<IMPLIN,IMPLOUT>::apply(t1,t2);
313            case Objref:
314              return isAdaptableObjref<IMPLIN,IMPLOUT>::apply(t1,t2);
315            case Sequence:
316              return isAdaptableSequence<IMPLIN,IMPLOUT>::apply(t1,t2);
317            case Array:
318              return isAdaptableArray<IMPLIN,IMPLOUT>::apply(t1,t2);
319            case Struct:
320              return isAdaptableStruct<IMPLIN,IMPLOUT>::apply(t1,t2);
321            default:
322              break;
323            }
324          return 0;
325       }
326
327     //xxx to Python adaptations
328     int isAdaptableCorbaPyObject(const TypeCode *t1,const TypeCode *t2)
329     {
330       return isAdaptable<PYTHONImpl,CORBAImpl>(t1,t2);
331     }
332     int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2)
333     {
334       return isAdaptable<PYTHONImpl,NEUTRALImpl>(t1,t2);
335     }
336     int isAdaptablePyObjectPyObject(const TypeCode *t1,const TypeCode *t2)
337     {
338       return isAdaptable<PYTHONImpl,PYTHONImpl>(t1,t2);
339     }
340
341     //xxx to Neutral adaptations
342     int isAdaptableCorbaNeutral(const TypeCode *t1,const TypeCode *t2)
343     {
344       return isAdaptable<NEUTRALImpl,CORBAImpl>(t1,t2);
345     }
346     int isAdaptablePyObjectNeutral(const TypeCode *t1,const TypeCode *t2)
347     {
348       return isAdaptable<NEUTRALImpl,PYTHONImpl>(t1,t2);
349     }
350     int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2)
351     {
352       return isAdaptable<NEUTRALImpl,XMLImpl>(t1,t2);
353     }
354     int isAdaptableNeutralNeutral(const TypeCode *t1, const TypeCode *t2)
355     {
356       return isAdaptableNeutralCorba(t1, t2);
357     }
358
359     //xxx to XML adaptations
360     int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2)
361     {
362       return isAdaptable<XMLImpl,NEUTRALImpl>(t1,t2);
363     }
364
365     //xxx to Corba adaptations
366     int isAdaptableNeutralCorba(const TypeCode *t1,const TypeCode *t2)
367     {
368       return isAdaptable<CORBAImpl,NEUTRALImpl>(t1,t2);
369     }
370     int isAdaptableXmlCorba(const TypeCode *t1,const TypeCode *t2)
371     {
372       return isAdaptable<CORBAImpl,XMLImpl>(t1,t2);
373     }
374     int isAdaptableCorbaCorba(const TypeCode *t1,const TypeCode *t2)
375     {
376       return isAdaptable<CORBAImpl,CORBAImpl>(t1,t2);
377     }
378     int isAdaptablePyObjectCorba(const TypeCode *t1,const TypeCode *t2)
379     {
380       return isAdaptable<CORBAImpl,PYTHONImpl>(t1,t2);
381     }
382
383     //! Basic template convertor from type TIN to Yacs<TOUT> type
384     /*!
385      * This convertor does nothing : throws exception
386      * It must be partially specialize for a specific type (TIN)
387      */
388     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
389     struct convertToYacsDouble
390     {
391       static inline double convert(const TypeCode *t,TIN o,TIN2 aux)
392         {
393           stringstream msg;
394           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
395           msg << " : " << __FILE__ << ":" << __LINE__;
396           throw YACS::ENGINE::ConversionException(msg.str());
397         }
398     };
399     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
400     struct convertToYacsInt
401     {
402       static inline long convert(const TypeCode *t,TIN o,TIN2 aux)
403         {
404           stringstream msg;
405           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
406           msg << " : " << __FILE__ << ":" << __LINE__;
407           throw YACS::ENGINE::ConversionException(msg.str());
408         }
409     };
410     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
411     struct convertToYacsString
412     {
413       static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux)
414         {
415           stringstream msg;
416           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
417           msg << " : " << __FILE__ << ":" << __LINE__;
418           throw YACS::ENGINE::ConversionException(msg.str());
419         }
420     };
421     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
422     struct convertToYacsBool
423     {
424       static inline bool convert(const TypeCode *t,TIN o,TIN2 aux)
425         {
426           stringstream msg;
427           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
428           msg << " : " << __FILE__ << ":" << __LINE__;
429           throw YACS::ENGINE::ConversionException(msg.str());
430         }
431     };
432     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
433     struct convertToYacsObjref
434     {
435       static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux,int protocol)
436         {
437           stringstream msg;
438           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
439           msg << " : " << __FILE__ << ":" << __LINE__;
440           throw YACS::ENGINE::ConversionException(msg.str());
441         }
442     };
443     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
444     struct convertToYacsSequence
445     {
446       static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector<TOUT>& v)
447         {
448           stringstream msg;
449           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
450           msg << " : " << __FILE__ << ":" << __LINE__;
451           throw YACS::ENGINE::ConversionException(msg.str());
452         }
453     };
454     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
455     struct convertToYacsArray
456     {
457       static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector<TOUT>& v)
458         {
459           stringstream msg;
460           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
461           msg << " : " << __FILE__ << ":" << __LINE__;
462           throw YACS::ENGINE::ConversionException(msg.str());
463         }
464     };
465     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
466     struct convertToYacsStruct
467     {
468       static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::map<std::string,TOUT>& v)
469         {
470           stringstream msg;
471           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
472           msg << " : " << __FILE__ << ":" << __LINE__;
473           throw YACS::ENGINE::ConversionException(msg.str());
474         }
475     };
476
477     //! Basic convertor from Yacs<TOUT> type to full TOUT type
478     /*!
479      *
480      */
481     template <ImplType IMPLOUT, class TOUT>
482     struct convertFromYacsDouble
483     {
484       static inline TOUT convert(const TypeCode *t,double o)
485         {
486           stringstream msg;
487           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
488           msg << " : " << __FILE__ << ":" << __LINE__;
489           throw YACS::ENGINE::ConversionException(msg.str());
490         }
491     };
492     template <ImplType IMPLOUT, class TOUT>
493     struct convertFromYacsInt
494     {
495       static inline TOUT convert(const TypeCode *t,long o)
496         {
497           stringstream msg;
498           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
499           msg << " : " << __FILE__ << ":" << __LINE__;
500           throw YACS::ENGINE::ConversionException(msg.str());
501         }
502     };
503     template <ImplType IMPLOUT, class TOUT>
504     struct convertFromYacsString
505     {
506       static inline TOUT convert(const TypeCode *t,std::string o)
507         {
508           stringstream msg;
509           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
510           msg << " : " << __FILE__ << ":" << __LINE__;
511           throw YACS::ENGINE::ConversionException(msg.str());
512         }
513     };
514     template <ImplType IMPLOUT, class TOUT>
515     struct convertFromYacsBool
516     {
517       static inline TOUT convert(const TypeCode *t,bool o)
518         {
519           stringstream msg;
520           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
521           msg << " : " << __FILE__ << ":" << __LINE__;
522           throw YACS::ENGINE::ConversionException(msg.str());
523         }
524     };
525     template <ImplType IMPLOUT, class TOUT>
526     struct convertFromYacsObjref
527     {
528       static inline TOUT convert(const TypeCode *t,std::string o)
529         {
530           stringstream msg;
531           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
532           msg << " : " << __FILE__ << ":" << __LINE__;
533           throw YACS::ENGINE::ConversionException(msg.str());
534         }
535     };
536     template <ImplType IMPLOUT, class TOUT>
537     struct convertFromYacsSequence
538     {
539       static inline TOUT convert(const TypeCode *t,std::vector<TOUT>& v)
540         {
541           stringstream msg;
542           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
543           msg << " : " << __FILE__ << ":" << __LINE__;
544           throw YACS::ENGINE::ConversionException(msg.str());
545         }
546     };
547     template <ImplType IMPLOUT, class TOUT>
548     struct convertFromYacsArray
549     {
550       static inline TOUT convert(const TypeCode *t,std::vector<TOUT>& v)
551         {
552           stringstream msg;
553           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
554           msg << " : " << __FILE__ << ":" << __LINE__;
555           throw YACS::ENGINE::ConversionException(msg.str());
556         }
557     };
558     template <ImplType IMPLOUT, class TOUT>
559     struct convertFromYacsStruct
560     {
561       static inline TOUT convert(const TypeCode *t,std::map<std::string,TOUT>& v)
562         {
563           stringstream msg;
564           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
565           msg << " : " << __FILE__ << ":" << __LINE__;
566           throw YACS::ENGINE::ConversionException(msg.str());
567         }
568     };
569     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
570     inline TOUT convertDouble(const TypeCode *t,TIN o,TIN2 aux)
571     {
572       double d=convertToYacsDouble<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
573       DEBTRACE( d );
574       TOUT r=convertFromYacsDouble<IMPLOUT,TOUT>::convert(t,d);
575       return r;
576     }
577     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
578     inline TOUT convertInt(const TypeCode *t,TIN o,TIN2 aux)
579     {
580       long d=convertToYacsInt<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
581       DEBTRACE( d );
582       TOUT r=convertFromYacsInt<IMPLOUT,TOUT>::convert(t,d);
583       return r;
584     }
585     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
586     inline TOUT convertString(const TypeCode *t,TIN o,TIN2 aux)
587     {
588       std::string d=convertToYacsString<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
589       DEBTRACE( d );
590       TOUT r=convertFromYacsString<IMPLOUT,TOUT>::convert(t,d);
591       return r;
592     }
593     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
594     inline TOUT convertBool(const TypeCode *t,TIN o,TIN2 aux)
595     {
596       double d=convertToYacsBool<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
597       DEBTRACE( d );
598       TOUT r=convertFromYacsBool<IMPLOUT,TOUT>::convert(t,d);
599       return r;
600     }
601     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
602     inline TOUT convertObjref(const TypeCode *t,TIN o,TIN2 aux)
603     {
604       int protocol=-1;
605       if(IMPLOUT==XMLImpl)
606         protocol=0;//to avoid presence of \0 into XML generated file
607       if(IMPLOUT==NEUTRALImpl)
608         protocol=4;
609       std::string d=convertToYacsObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,protocol);
610       DEBTRACE( d );
611       TOUT r=convertFromYacsObjref<IMPLOUT,TOUT>::convert(t,d);
612       return r;
613     }
614
615     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
616     inline TOUT convertSequence(const TypeCode *t,TIN o,TIN2 aux)
617     {
618       std::vector<TOUT> v;
619       convertToYacsSequence<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
620       TOUT r=convertFromYacsSequence<IMPLOUT,TOUT>::convert(t,v);
621       return r;
622     }
623     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
624     inline TOUT convertArray(const TypeCode *t,TIN o,TIN2 aux)
625     {
626       std::vector<TOUT> v;
627       convertToYacsArray<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
628       TOUT r=convertFromYacsArray<IMPLOUT,TOUT>::convert(t,v);
629       return r;
630     }
631     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
632     inline TOUT convertStruct(const TypeCode *t,TIN o,TIN2 aux)
633     {
634       std::map<std::string,TOUT> v;
635       convertToYacsStruct<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
636       TOUT r=convertFromYacsStruct<IMPLOUT,TOUT>::convert(t,v);
637       return r;
638     }
639
640     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
641     inline TOUT YacsConvertor(const TypeCode *t,TIN o,TIN2 aux)
642       {
643          int tk=t->kind();
644          switch(t->kind())
645            {
646            case Double:
647              return convertDouble<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
648            case Int:
649              return convertInt<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
650            case String:
651              return convertString<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
652            case Bool:
653              return convertBool<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
654            case Objref:
655              return convertObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
656            case Sequence:
657              return convertSequence<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
658            case Array:
659              return convertArray<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
660            case Struct:
661              return convertStruct<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
662            default:
663              break;
664            }
665          stringstream msg;
666          msg << "Conversion not implemented: kind= " << tk << " Implementation: " << IMPLOUT;
667          msg << " : " << __FILE__ << ":" << __LINE__;
668          throw YACS::ENGINE::ConversionException(msg.str());
669       }
670
671     //! ToYacs Convertor for PYTHONImpl
672     /*!
673      * This convertor converts Python object to YACS<TOUT> types
674      * Partial specialization for Python implementation with type PyObject* (PYTHONImpl)
675      */
676     template <ImplType IMPLOUT, class TOUT>
677     struct convertToYacsDouble<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
678     {
679       static inline double convert(const TypeCode *t,PyObject* o,void*)
680         {
681           double x;
682           if (PyFloat_Check(o))
683             x=PyFloat_AS_DOUBLE(o);
684           else if(PyLong_Check(o))
685             x=PyLong_AsLong(o);
686           else
687             {
688               stringstream msg;
689               msg << "Not a python double. ";
690 #ifdef _DEVDEBUG_
691               msg << "kind=" << t->kind() ;
692               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
693 #endif
694               throw YACS::ENGINE::ConversionException(msg.str());
695             }
696           return x;
697         }
698     };
699     template <ImplType IMPLOUT, class TOUT>
700     struct convertToYacsInt<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
701     {
702       static inline long convert(const TypeCode *t,PyObject* o,void*)
703         {
704           long l;
705           if(PyLong_Check(o))
706             l=PyLong_AsLong(o);
707           else
708             {
709               stringstream msg;
710               msg << "Not a python integer. ";
711 #ifdef _DEVDEBUG_
712               msg << "kind=" << t->kind() ;
713               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
714 #endif
715               throw YACS::ENGINE::ConversionException(msg.str());
716             }
717           return l;
718         }
719     };
720     template <ImplType IMPLOUT, class TOUT>
721     struct convertToYacsString<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
722     {
723       static inline std::string convert(const TypeCode *t,PyObject* o,void*)
724         {
725           std::string s;
726           if (PyUnicode_Check(o))
727             {
728               Py_ssize_t size;
729               const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
730               if (!ptr)
731                 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
732               s.assign(ptr, size);
733             }
734           else
735             {
736               stringstream msg;
737               msg << "Not a python string. ";
738 #ifdef _DEVDEBUG_
739               msg << "kind=" << t->kind() ;
740               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
741 #endif
742               throw YACS::ENGINE::ConversionException(msg.str());
743             }
744           return s;
745         }
746     };
747     template <ImplType IMPLOUT, class TOUT>
748     struct convertToYacsBool<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
749     {
750       static inline bool convert(const TypeCode *t,PyObject* o,void*)
751         {
752           bool l;
753           if (PyBool_Check(o))
754               l=(o==Py_True);
755           else if(PyLong_Check(o))
756               l=(PyLong_AsLong(o)!=0);
757           else
758             {
759               stringstream msg;
760               msg << "Not a python boolean. ";
761 #ifdef _DEVDEBUG_
762               msg << "kind=" << t->kind() ;
763               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
764 #endif
765               throw YACS::ENGINE::ConversionException(msg.str());
766             }
767           return l;
768         }
769     };
770     template <ImplType IMPLOUT, class TOUT>
771     struct convertToYacsObjref<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
772     {
773       static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol)
774         {
775           if (PyUnicode_Check(o) && strncmp(t->id(),"python",6)!=0)
776             {
777               // the objref is used by Python as a string (prefix:value) keep it as a string
778               Py_ssize_t size;
779               std::string s;
780               const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
781               if (!ptr)
782                 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
783               s.assign(ptr, size);
784               return s;
785             }
786           if(strncmp(t->id(),"python",6)==0)
787             {
788               // It's a native Python object pickle it
789               PyObject* mod=PyImport_ImportModule("pickle");
790               PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol);
791               DEBTRACE(PyObject_Repr(pickled) );
792               Py_DECREF(mod);
793               if(pickled==NULL)
794                 {
795                   PyErr_Print();
796                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
797                 }
798               std::string mystr(PyBytes_AsString(pickled),PyBytes_Size(pickled));
799               Py_DECREF(pickled);
800               return mystr;
801             }
802           else if(strncmp(t->id(),"json",4)==0)
803             {
804               // It's a Python  object convert it to json 
805               PyObject* mod=PyImport_ImportModule("simplejson");
806               if(mod==NULL)
807                 {
808                   PyErr_Print();
809                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
810                 }
811               PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"O",o);
812               Py_DECREF(mod);
813               if(pickled==NULL)
814                 {
815                   PyErr_Print();
816                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
817                 }
818               std::string mystr=PyBytes_AsString(pickled);
819               Py_DECREF(pickled);
820               return mystr;
821             }
822           else
823             {
824               // It should be a CORBA Object convert it to an IOR string
825               PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),(char *)"object_to_string",(char *)"O",o);
826               if(pystring==NULL)
827                 {
828                   PyErr_Print();
829                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
830                 }
831               Py_ssize_t size;
832               std::string mystr;
833               const char *ptr = PyUnicode_AsUTF8AndSize(pystring, &size);
834               if (!ptr)
835                 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
836               mystr.assign(ptr, size);
837               Py_DECREF(pystring);
838               return mystr;
839             }
840         }
841     };
842     template <ImplType IMPLOUT, class TOUT>
843     struct convertToYacsSequence<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
844     {
845       static inline void convert(const TypeCode *t,PyObject* o,void*,std::vector<TOUT>& v)
846         {
847           if(!PySequence_Check(o))
848             {
849               stringstream msg;
850               msg << "Problem in conversion: the python object is not a sequence " << std::endl;
851 #ifdef _DEVDEBUG_
852               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
853 #endif
854               throw YACS::ENGINE::ConversionException(msg.str());
855             }
856           int length=PySequence_Size(o);
857           DEBTRACE("length: " << length );
858           v.resize(length);
859           for(int i=0;i<length;i++)
860             {
861               PyObject *item=PySequence_ITEM(o,i);
862 #ifdef _DEVDEBUG_
863               std::cerr <<"item[" << i << "]=";
864               PyObject_Print(item,stderr,Py_PRINT_RAW);
865               std::cerr << std::endl;
866 #endif
867               DEBTRACE( "item refcnt: " << item->ob_refcnt );
868               try
869                 {
870                   TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(t->contentType(),item,0);
871                   v[i]=ro;
872                   Py_DECREF(item);
873                 }
874               catch(ConversionException& ex)
875                 {
876                   stringstream msg;
877                   msg << ex.what() << " for sequence element " << i;
878                   throw YACS::ENGINE::ConversionException(msg.str(),false);
879                 }
880             }
881         }
882     };
883     template <ImplType IMPLOUT, class TOUT>
884     struct convertToYacsStruct<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
885     {
886       static inline void convert(const TypeCode *t,PyObject* o,void*,std::map<std::string,TOUT>& m)
887         {
888           DEBTRACE( "o refcnt: " << o->ob_refcnt );
889           PyObject *key, *value;
890           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
891           int nMember=tst->memberCount();
892           DEBTRACE("nMember="<<nMember);
893           for(int i=0;i<nMember;i++)
894             {
895               std::string name=tst->memberName(i);
896               DEBTRACE("Member name="<<name);
897               TypeCode* tm=tst->memberType(i);
898               value=PyDict_GetItemString(o, name.c_str());
899               if(value==NULL)
900                 {
901                   //member name not present
902                   //TODO delete all allocated objects in m
903 #ifdef _DEVDEBUG_
904                   PyObject_Print(o,stderr,Py_PRINT_RAW);
905                   std::cerr << std::endl;
906 #endif
907                   stringstream msg;
908                   msg << "member " << name << " not present " ;
909                   throw YACS::ENGINE::ConversionException(msg.str());
910                 }
911               DEBTRACE( "value refcnt: " << value->ob_refcnt );
912               try
913                 {
914                   TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(tm,value,0);
915                   m[name]=ro;
916                 }
917               catch(ConversionException& ex)
918                 {
919                   std::string s=" for struct member "+name;
920                   throw YACS::ENGINE::ConversionException(ex.what()+s,false);
921                 }
922             }
923         }
924     };
925     /* End of ToYacs Convertor for PYTHONImpl */
926
927     //! FromYacs Convertor for PYTHONImpl
928     /*!
929      * Convert YACS<PyObject*> intermediate types to PyObject* types (PYTHONImpl)
930      */
931     template <>
932     struct convertFromYacsDouble<PYTHONImpl,PyObject*>
933     {
934       static inline PyObject* convert(const TypeCode *t,double o)
935         {
936           PyObject *pyob=PyFloat_FromDouble(o);
937           return pyob;
938         }
939     };
940     template <>
941     struct convertFromYacsInt<PYTHONImpl,PyObject*>
942     {
943       static inline PyObject* convert(const TypeCode *t,long o)
944         {
945           PyObject *pyob=PyLong_FromLong(o);
946           return pyob;
947         }
948     };
949     template <>
950     struct convertFromYacsString<PYTHONImpl,PyObject*>
951     {
952       static inline PyObject* convert(const TypeCode *t,std::string& o)
953         {
954           return PyUnicode_FromString(o.c_str());
955         }
956     };
957     template <>
958     struct convertFromYacsBool<PYTHONImpl,PyObject*>
959     {
960       static inline PyObject* convert(const TypeCode *t,bool o)
961         {
962           return PyBool_FromLong ((long)o);
963         }
964     };
965     template <>
966     struct convertFromYacsObjref<PYTHONImpl,PyObject*>
967     {
968       static inline PyObject* convert(const TypeCode *t,std::string& o)
969         {
970           if(o=="")
971             {
972               Py_INCREF(Py_None);
973               return Py_None;
974             }
975           if(t->isA(Runtime::_tc_file))
976             {
977               //It's an objref file. Convert it specially
978               return PyUnicode_FromString(o.c_str());
979             }
980           if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0"
981             {
982               //It's a python pickled object, unpickled it
983               PyObject* mod=PyImport_ImportModule("pickle");
984               PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length());
985               DEBTRACE(PyObject_Repr(ob));
986               Py_DECREF(mod);
987               if(ob==NULL)
988                 {
989                   PyErr_Print();
990                   throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
991                 }
992               return ob;
993             }
994           if(strncmp(t->id(),"json",4)==0)
995             {
996               // It's a json object unpack it
997               PyObject* mod=PyImport_ImportModule("simplejson");
998               if(mod==NULL)
999                 {
1000                   PyErr_Print();
1001                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
1002                 }
1003               PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y",o.c_str());
1004               Py_DECREF(mod);
1005               if(ob==NULL)
1006                 {
1007                   PyErr_Print();
1008                   throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
1009                 }
1010               return ob;
1011             }
1012
1013           /* another way to convert IOR string to CORBA PyObject 
1014           PyObject* ob= PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"string_to_object","s",o.c_str());
1015           DEBTRACE( "Objref python refcnt: " << ob->ob_refcnt );
1016           return ob;
1017           */
1018
1019           //Objref CORBA. prefix=IOR,corbaname,corbaloc
1020           CORBA::Object_var obref;
1021           try
1022             {
1023               obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1024 #ifdef REFCNT
1025               DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1026 #endif
1027             }
1028           catch(CORBA::Exception& ex) 
1029             {
1030               DEBTRACE( "Can't get reference to object." );
1031               throw ConversionException("Can't get reference to object");
1032             }
1033
1034           if(obref->_non_existent())
1035             {
1036               throw ConversionException("non_existent object");
1037             }
1038
1039           if( CORBA::is_nil(obref) )
1040             {
1041               DEBTRACE( "Can't get reference to object (or it was nil)." );
1042               throw ConversionException("Can't get reference to object");
1043             }
1044
1045           if(!obref->_is_a(t->id()))
1046             {
1047               stringstream msg;
1048               msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1049               msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1050               msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1051               throw YACS::ENGINE::ConversionException(msg.str());
1052             }
1053 #ifdef REFCNT
1054           DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1055 #endif
1056 #ifdef _DEVDEBUG_
1057           std::cerr << "_PD_repoId: " << obref->_PD_repoId << std::endl;
1058           std::cerr << "_mostDerivedRepoId: " << obref->_PR_getobj()->_mostDerivedRepoId()  << std::endl;
1059 #endif
1060
1061           //hold_lock is true: caller is supposed to hold the GIL.
1062           //omniorb will not take the GIL
1063           PyObject* ob= getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(obref, 1);
1064
1065 #ifdef _DEVDEBUG_
1066           PyObject_Print(ob,stderr,Py_PRINT_RAW);
1067           std::cerr << std::endl;
1068           std::cerr << "obref is a generic: " << obref->_is_a("IDL:SALOME/GenericObj:1.0") << std::endl;
1069           PyObject_Print(getSALOMERuntime()->get_omnipy(),stderr,Py_PRINT_RAW);
1070           std::cerr << std::endl;
1071 #endif
1072
1073           //ob is a CORBA::Object. Try to convert it to more specific type SALOME/GenericObj
1074           if(obref->_is_a("IDL:SALOME/GenericObj:1.0"))
1075             {
1076               PyObject *result = PyObject_CallMethod(getSALOMERuntime()->get_omnipy(), (char *)"narrow", (char *)"Osi",ob,"IDL:SALOME/GenericObj:1.0",1);
1077               if(result==NULL)
1078                 PyErr_Clear();//Exception during narrow. Keep ob
1079               else if(result==Py_None)
1080                 Py_DECREF(result); //Can't narrow. Keep ob
1081               else
1082                 {
1083                   //Can narrow. Keep result
1084 #ifdef _DEVDEBUG_
1085                   PyObject_Print(result,stderr,Py_PRINT_RAW);
1086                   std::cerr << std::endl;
1087 #endif
1088                   Py_DECREF(ob);
1089                   ob=result;
1090                 }
1091             }
1092
1093 #ifdef REFCNT
1094           DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1095 #endif
1096           return ob;
1097         }
1098     };
1099
1100     template <>
1101     struct convertFromYacsSequence<PYTHONImpl,PyObject*>
1102     {
1103       static inline PyObject* convert(const TypeCode *t,std::vector<PyObject*>& v)
1104         {
1105           std::vector<PyObject*>::const_iterator iter;
1106           PyObject *pyob = PyList_New(v.size());
1107           int i=0;
1108           for(iter=v.begin();iter!=v.end();iter++)
1109             {
1110               PyObject* item=*iter;
1111               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1112               PyList_SetItem(pyob,i,item);
1113               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1114               i++;
1115             }
1116           return pyob;
1117         }
1118     };
1119     template <>
1120     struct convertFromYacsStruct<PYTHONImpl,PyObject*>
1121     {
1122       static inline PyObject* convert(const TypeCode *t,std::map<std::string,PyObject*>& m)
1123         {
1124           PyObject *pyob = PyDict_New();
1125           std::map<std::string, PyObject*>::const_iterator pt;
1126           for(pt=m.begin();pt!=m.end();pt++)
1127             {
1128               std::string name=(*pt).first;
1129               PyObject* item=(*pt).second;
1130               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1131               PyDict_SetItemString(pyob,name.c_str(),item);
1132               Py_DECREF(item);
1133               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1134             }
1135           DEBTRACE( "pyob refcnt: " << pyob->ob_refcnt );
1136           return pyob;
1137         }
1138     };
1139     /* End of FromYacs Convertor for PYTHONImpl */
1140
1141     //! ToYacs Convertor for XMLImpl
1142     /*!
1143      * Partial specialization for XML implementation (XMLImpl)
1144      * This convertor converts xml object to YACS<TOUT> types
1145      */
1146     template <ImplType IMPLOUT, class TOUT>
1147     struct convertToYacsDouble<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1148     {
1149       static inline double convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1150         {
1151           double d=0;
1152           cur = cur->xmlChildrenNode;
1153           while (cur != NULL)
1154             {
1155               if ((!xmlStrcmp(cur->name, (const xmlChar *)"double")))
1156                 {
1157                   //wait a double, got a double
1158                   xmlChar * s = NULL;
1159                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1160                   if (s)
1161                     {
1162                       DEBTRACE( "convertToYacsDouble " << (const char *)s );
1163                       d=Cstr2d((const char *)s);
1164                       xmlFree(s);
1165                     }
1166                   else
1167                     {
1168                       DEBTRACE("############### workaround to improve...");
1169                     }
1170                   return d;
1171                 }
1172               else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1173                 {
1174                   //wait a double, got an int
1175                   xmlChar * s = NULL;
1176                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1177                   if (s)
1178                     {
1179                       DEBTRACE( "convertToYacsDouble " << (const char *)s );
1180                       d=Cstr2d((const char *)s);
1181                       xmlFree(s);
1182                     }
1183                   else
1184                     {
1185                       DEBTRACE("############### workaround to improve...");
1186                     }
1187                   return d;
1188                 }
1189               cur = cur->next;
1190             }
1191           stringstream msg;
1192           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1193           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1194           throw YACS::ENGINE::ConversionException(msg.str());
1195         }
1196     };
1197     template <ImplType IMPLOUT, class TOUT>
1198     struct convertToYacsInt<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1199     {
1200       static inline long convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1201         {
1202           long d=0;
1203           cur = cur->xmlChildrenNode;
1204           while (cur != NULL)
1205             {
1206               if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1207                 {
1208                   xmlChar * s = NULL;
1209                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1210                   if (s)
1211                     {
1212                       DEBTRACE( "convertToYacsInt " << (const char *)s );
1213                       d=atol((const char *)s);
1214                       xmlFree(s);
1215                     }
1216                   else
1217                     {
1218                       DEBTRACE("############### workaround to improve...");
1219                     }
1220                   return d;
1221                 }
1222               cur = cur->next;
1223             }
1224           stringstream msg;
1225           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1226           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1227           throw YACS::ENGINE::ConversionException(msg.str());
1228         }
1229     };
1230     template <ImplType IMPLOUT, class TOUT>
1231     struct convertToYacsString<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1232     {
1233       static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1234         {
1235           cur = cur->xmlChildrenNode;
1236           while (cur != NULL)
1237             {
1238               if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))
1239                 {
1240                   //wait a string, got a string
1241                   xmlChar * s = NULL;
1242                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1243                   if(s==0)return "";
1244                   DEBTRACE( "convertToYacsString " << (const char *)s );
1245                   std::string mystr=std::string((const char *)s);
1246                   xmlFree(s);
1247                   return mystr;
1248                 }
1249               cur = cur->next;
1250             }
1251           stringstream msg;
1252           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1253           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1254           throw YACS::ENGINE::ConversionException(msg.str());
1255         }
1256     };
1257     template <ImplType IMPLOUT, class TOUT>
1258     struct convertToYacsBool<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1259     {
1260       static inline bool convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1261         {
1262           cur = cur->xmlChildrenNode;
1263           while (cur != NULL)
1264             {
1265               if ((!xmlStrcmp(cur->name, (const xmlChar *)"boolean")))
1266                 {
1267                   //wait a boolean, got a boolean
1268                   xmlChar * s = NULL;
1269                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1270                   bool ob =false;
1271                   if (s)
1272                     {
1273                       DEBTRACE( "convertToYacsBool " << (const char *)s );
1274                       ob=atoi((const char*)s)!=0;
1275                       xmlFree(s);
1276                     }
1277                   else
1278                     {
1279                       DEBTRACE("############### workaround to improve...");
1280                     }
1281                   return ob;
1282                 }
1283               cur = cur->next;
1284             }
1285           stringstream msg;
1286           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1287           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1288           throw YACS::ENGINE::ConversionException(msg.str());
1289         }
1290     };
1291     template <ImplType IMPLOUT, class TOUT>
1292     struct convertToYacsObjref<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1293     {
1294       static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,int protocol)
1295         {
1296           cur = cur->xmlChildrenNode;
1297           while (cur != NULL)
1298             {
1299               if ((!xmlStrcmp(cur->name, (const xmlChar *)"objref")))
1300                 {
1301                   //we wait a objref, we have got a objref
1302                   xmlChar * s = NULL;
1303                   std::string mystr = "";
1304                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1305                   if (s)
1306                     {
1307                       DEBTRACE( "convertToYacsObjref " << (const char *)s );
1308                       mystr = (const char *)s;
1309                       xmlFree(s);
1310                     }
1311                   else
1312                     {
1313                       DEBTRACE("############### workaround to improve...");
1314                     }
1315                   if(strncmp(t->id(),"python",6)==0 )
1316                     return FromBase64Safe(mystr);
1317                   else
1318                     return mystr;
1319                 }
1320               else if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))// <- here case where pyobj value has been stored in XML. pyobj has kind==ObjRef. And the stored format is String ! EDF11027
1321                 {
1322                   //wait a string, got a string
1323                   xmlChar * s = NULL;
1324                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1325                   if(s==0)return "";
1326                   DEBTRACE( "convertToYacsString " << (const char *)s );
1327                   std::string mystr=std::string((const char *)s);
1328                   xmlFree(s);
1329                   return mystr;
1330                 }
1331               cur = cur->next;
1332             }
1333           stringstream msg;
1334           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1335           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1336           throw YACS::ENGINE::ConversionException(msg.str());
1337         }
1338     };
1339     template <ImplType IMPLOUT, class TOUT>
1340     struct convertToYacsSequence<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1341     {
1342       static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::vector<TOUT>& v)
1343         {
1344           cur = cur->xmlChildrenNode;
1345           while (cur != NULL)
1346             {
1347               if ((!xmlStrcmp(cur->name, (const xmlChar *)"array")))
1348                 {
1349                   DEBTRACE( "parse sequence " );
1350                   xmlNodePtr cur1=cur->xmlChildrenNode;
1351                   while (cur1 != NULL)
1352                     {
1353                       if ((!xmlStrcmp(cur1->name, (const xmlChar *)"data")))
1354                         {
1355                           DEBTRACE( "parse data " );
1356                           xmlNodePtr cur2=cur1->xmlChildrenNode;
1357                           while (cur2 != NULL)
1358                             {
1359                               //collect all values
1360                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1361                                 {
1362                                   TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(t->contentType(),doc,cur2);
1363                                   v.push_back(ro);
1364                                 }
1365                               cur2 = cur2->next;
1366                             } // end while value
1367                           break;
1368                         }
1369                       cur1 = cur1->next;
1370                     } // end while data
1371                   break;
1372                 }
1373               cur = cur->next;
1374             } // end while array
1375         }
1376     };
1377     template <ImplType IMPLOUT, class TOUT>
1378     struct convertToYacsStruct<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1379     {
1380       static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::map<std::string,TOUT>& m)
1381         {
1382           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1383           int nMember=tst->memberCount();
1384           DEBTRACE("nMember="<<nMember);
1385           std::map<std::string,TypeCode*> mtc;
1386           for(int i=0;i<nMember;i++)
1387             {
1388               mtc[tst->memberName(i)]=tst->memberType(i);
1389             }
1390
1391           cur = cur->xmlChildrenNode;
1392           while (cur != NULL)
1393             {
1394               if ((!xmlStrcmp(cur->name, (const xmlChar *)"struct")))
1395                 {
1396                   DEBTRACE( "parse struct " );
1397                   xmlNodePtr cur1=cur->xmlChildrenNode;
1398                   while (cur1 != NULL)
1399                     {
1400                       if ((!xmlStrcmp(cur1->name, (const xmlChar *)"member")))
1401                         {
1402                           DEBTRACE( "parse member " );
1403                           xmlNodePtr cur2=cur1->xmlChildrenNode;
1404                           while (cur2 != NULL)
1405                             {
1406                               //member name
1407                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"name")))
1408                                 {
1409                                   xmlChar * s = NULL;
1410                                   s = xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
1411                                   std::string name= (char *)s;
1412                                   cur2 = cur2->next;
1413                                   while (cur2 != NULL)
1414                                     {
1415                                       if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1416                                         {
1417                                           TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(mtc[name],doc,cur2);
1418                                           m[name]=ro;
1419                                           break;
1420                                         }
1421                                       cur2 = cur2->next;
1422                                     }
1423                                   xmlFree(s);
1424                                   break;
1425                                 }
1426                               cur2 = cur2->next;
1427                             } // end while member/value
1428                         }
1429                       cur1 = cur1->next;
1430                     } // end while member
1431                   break;
1432                 }
1433               cur = cur->next;
1434             } // end while struct
1435         }
1436     };
1437     /* End of ToYacs Convertor for XMLImpl */
1438
1439     //! FromYacs Convertor for XMLImpl
1440     /*!
1441      * Convert YACS<std::string> intermediate types to std::string types (XMLImpl)
1442      */
1443     template <>
1444     struct convertFromYacsDouble<XMLImpl,std::string>
1445     {
1446       static inline std::string convert(const TypeCode *t,double o)
1447         {
1448           stringstream msg ;
1449           msg << "<value><double>" << setprecision(16) << o << "</double></value>\n";
1450           return msg.str();
1451         }
1452     };
1453     template <>
1454     struct convertFromYacsInt<XMLImpl,std::string>
1455     {
1456       static inline std::string convert(const TypeCode *t,long o)
1457         {
1458           stringstream msg ;
1459           msg << "<value><int>" << o << "</int></value>\n";
1460           return msg.str();
1461         }
1462     };
1463     template <>
1464     struct convertFromYacsString<XMLImpl,std::string>
1465     {
1466       static inline std::string convert(const TypeCode *t,std::string& o)
1467         {
1468           std::string msg="<value><string>";
1469           return msg+o+"</string></value>\n";
1470         }
1471     };
1472     template <>
1473     struct convertFromYacsBool<XMLImpl,std::string>
1474     {
1475       static inline std::string convert(const TypeCode *t,bool o)
1476         {
1477           stringstream msg ;
1478           msg << "<value><boolean>" << o << "</boolean></value>\n";
1479           return msg.str();
1480         }
1481     };
1482     template <>
1483     struct convertFromYacsObjref<XMLImpl,std::string>
1484     {
1485       static inline std::string convert(const TypeCode *t,std::string& o)
1486         {
1487           if(strncmp(t->id(),"python",6)==0 )
1488             return "<value><objref><![CDATA[" + ToBase64(o) + "]]></objref></value>\n";
1489           else if(strncmp(t->id(),"json",4)==0)
1490             return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
1491           else
1492             return "<value><objref>" + o + "</objref></value>\n";
1493         }
1494     };
1495
1496     template <>
1497     struct convertFromYacsSequence<XMLImpl,std::string>
1498     {
1499       static inline std::string convert(const TypeCode *t,std::vector<std::string>& v)
1500         {
1501           std::vector<std::string>::const_iterator iter;
1502           stringstream xmlob;
1503           xmlob << "<value><array><data>\n";
1504           for(iter=v.begin();iter!=v.end();iter++)
1505             {
1506               xmlob << *iter;
1507             }
1508           xmlob << "</data></array></value>\n";
1509           DEBTRACE("Sequence= " << xmlob);
1510           return xmlob.str();
1511         }
1512     };
1513     template <>
1514     struct convertFromYacsStruct<XMLImpl,std::string>
1515     {
1516       static inline std::string convert(const TypeCode *t,std::map<std::string,std::string>& m)
1517         {
1518           std::string result="<value><struct>\n";
1519           std::map<std::string, std::string>::const_iterator pt;
1520           for(pt=m.begin();pt!=m.end();pt++)
1521             {
1522               std::string name=(*pt).first;
1523               std::string item=(*pt).second;
1524               result=result+"<member>\n";
1525               result=result+"<name>"+name+"</name>\n";
1526               result=result+item;
1527               result=result+"</member>\n";
1528             }
1529           result=result+"</struct></value>\n";
1530           return result;
1531         }
1532     };
1533
1534     /* End of FromYacs Convertor for XMLImpl */
1535
1536     //! ToYacs Convertor for NEUTRALImpl
1537     /*!
1538      * This convertor converts Neutral objects to intermediate YACS<TOUT> types
1539      * Template : Partial specialization for Neutral implementation with types YACS::ENGINE::Any*
1540      */
1541     template <ImplType IMPLOUT, class TOUT>
1542     struct convertToYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1543     {
1544       static inline double convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1545         {
1546           if(o->getType()->kind()==Double)
1547             return o->getDoubleValue();
1548           else if(o->getType()->kind()==Int)
1549             return o->getIntValue();
1550
1551           stringstream msg;
1552           msg << "Problem in conversion: a double or int is expected " ;
1553           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1554           throw YACS::ENGINE::ConversionException(msg.str());
1555         }
1556     };
1557     template <ImplType IMPLOUT, class TOUT>
1558     struct convertToYacsInt<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1559     {
1560       static inline long convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1561         {
1562           if(o->getType()->kind()==Int)
1563             return o->getIntValue();
1564           stringstream msg;
1565           msg << "Problem in conversion: a int is expected " ;
1566           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1567           throw YACS::ENGINE::ConversionException(msg.str());
1568         }
1569     };
1570     template <ImplType IMPLOUT, class TOUT>
1571     struct convertToYacsString<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1572     {
1573       static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1574         {
1575           if(o->getType()->kind()==String)
1576             return o->getStringValue();
1577           stringstream msg;
1578           msg << "Problem in conversion: a string is expected " ;
1579           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1580           throw YACS::ENGINE::ConversionException(msg.str());
1581         }
1582     };
1583     template <ImplType IMPLOUT, class TOUT>
1584     struct convertToYacsBool<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1585     {
1586       static inline bool convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1587         {
1588           if(o->getType()->kind()==Bool)
1589             return o->getBoolValue();
1590           else if(o->getType()->kind()==Int)
1591             return o->getIntValue() != 0;
1592           stringstream msg;
1593           msg << "Problem in conversion: a bool or int is expected " ;
1594           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1595           throw YACS::ENGINE::ConversionException(msg.str());
1596         }
1597     };
1598     template <ImplType IMPLOUT, class TOUT>
1599     struct convertToYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1600     {
1601       static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,int protocol)
1602         {
1603           if(o->getType()->kind()==String || o->getType()->kind()==Objref)
1604             return o->getStringValue();
1605           stringstream msg;
1606           msg << "Problem in conversion: a objref(string) is expected " ;
1607           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1608           throw YACS::ENGINE::ConversionException(msg.str());
1609         }
1610     };
1611     template <ImplType IMPLOUT, class TOUT>
1612     struct convertToYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1613     {
1614       static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::vector<TOUT>& v)
1615         {
1616           SequenceAny* sdata= (SequenceAny*)o;
1617           int length=sdata->size();
1618           v.resize(length);
1619           for(int i=0;i<length;i++)
1620             {
1621               TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(t->contentType(),(*sdata)[i],0);
1622               v[i]=ro;
1623             }
1624         }
1625     };
1626     template <ImplType IMPLOUT, class TOUT>
1627     struct convertToYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1628     {
1629       static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::map<std::string,TOUT>& m)
1630         {
1631           StructAny * sdata = dynamic_cast<StructAny *>(o);
1632           YASSERT(sdata != NULL);
1633           const TypeCodeStruct * tst = dynamic_cast<const TypeCodeStruct *>(t);
1634           YASSERT(tst != NULL);
1635           for (int i=0 ; i<tst->memberCount() ; i++)
1636             {
1637               string name = tst->memberName(i);
1638               TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),(*sdata)[name.c_str()],0);
1639               m[name]=ro;
1640             }
1641         }
1642     };
1643     /* End of ToYacs Convertor for NEUTRALImpl */
1644
1645     //! FromYacs Convertor for NEUTRALImpl
1646     /*!
1647      * Convert YACS<YACS::ENGINE::Any*> intermediate types to YACS::ENGINE::Any* types (NEUTRALImpl)
1648      */
1649     template <>
1650     struct convertFromYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*>
1651     {
1652       static inline YACS::ENGINE::Any* convert(const TypeCode *t,double o)
1653         {
1654           YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(o);
1655           return ob;
1656         }
1657     };
1658     template <>
1659     struct convertFromYacsInt<NEUTRALImpl,YACS::ENGINE::Any*>
1660     {
1661       static inline YACS::ENGINE::Any* convert(const TypeCode *t,long o)
1662         {
1663           return YACS::ENGINE::AtomAny::New((int)o);
1664         }
1665     };
1666     template <>
1667     struct convertFromYacsString<NEUTRALImpl,YACS::ENGINE::Any*>
1668     {
1669       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1670         {
1671           return YACS::ENGINE::AtomAny::New(o);
1672         }
1673     };
1674     template <>
1675     struct convertFromYacsBool<NEUTRALImpl,YACS::ENGINE::Any*>
1676     {
1677       static inline YACS::ENGINE::Any* convert(const TypeCode *t,bool o)
1678         {
1679           return YACS::ENGINE::AtomAny::New(o);
1680         }
1681     };
1682     template <>
1683     struct convertFromYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*>
1684     {
1685       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1686         {
1687           //Check if objref is a GenericObj and register it if it is the case (workaround for bad management of GenericObj)
1688           if(o=="" || (t->isA(Runtime::_tc_file)) || (strncmp(t->id(),"python",6)==0) || (strncmp(t->id(),"json",4)==0))
1689             return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1690
1691           //Objref CORBA. prefix=IOR,corbaname,corbaloc
1692           CORBA::Object_var obref;
1693           try
1694             {
1695               obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1696             }
1697           catch(CORBA::Exception& ex)
1698             {
1699               throw ConversionException("Can't get reference to object");
1700             }
1701           if(obref->_non_existent())
1702             throw ConversionException("non_existent object");
1703           if( CORBA::is_nil(obref) )
1704             throw ConversionException("Can't get reference to object");
1705           if(!obref->_is_a(t->id()))
1706             {
1707               stringstream msg;
1708               msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1709               msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1710               msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1711               throw YACS::ENGINE::ConversionException(msg.str());
1712             }
1713
1714           SALOME::GenericObj_var gobj=SALOME::GenericObj::_narrow(obref);
1715           if(!CORBA::is_nil(gobj))
1716             {
1717               DEBTRACE("It's a SALOME::GenericObj register it");
1718               gobj->Register();
1719             }
1720           else
1721               DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
1722
1723           return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1724         }
1725     };
1726
1727     template <>
1728     struct convertFromYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*>
1729     {
1730       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::vector<YACS::ENGINE::Any*>& v)
1731         {
1732           std::vector<YACS::ENGINE::Any*>::const_iterator iter;
1733           //Objref are managed as string within YACS::ENGINE::Any objs
1734           SequenceAny* any;
1735           any=SequenceAny::New(t->contentType());
1736           for(iter=v.begin();iter!=v.end();iter++)
1737             {
1738               any->pushBack(*iter);
1739               (*iter)->decrRef();
1740             }
1741           DEBTRACE( "refcnt: " << any->getRefCnt() );
1742           return any;
1743         }
1744     };
1745
1746     template <>
1747     struct convertFromYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*>
1748     {
1749       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::map<std::string,YACS::ENGINE::Any*>& m)
1750         {
1751           StructAny * any = StructAny::New((TypeCodeStruct *)t);
1752           std::map<std::string,YACS::ENGINE::Any*>::const_iterator it;
1753           for (it=m.begin() ; it!=m.end() ; it++)
1754             {
1755               any->setEltAtRank(it->first.c_str(), it->second);
1756               it->second->decrRef();
1757             }
1758           return any;
1759         }
1760     };
1761     /* End of FromYacs Convertor for NEUTRALImpl */
1762
1763     //! ToYacs Convertor for CORBAImpl
1764     /*!
1765      * This convertor converts Corba objects to intermediate YACS<TOUT> types
1766      * Template : Partial specialization for CORBA implementation with types CORBA::Any*
1767      */
1768     template <ImplType IMPLOUT, class TOUT>
1769     struct convertToYacsDouble<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1770     {
1771       static inline double convert(const TypeCode *t,CORBA::Any* o,void*)
1772         {
1773           CORBA::TypeCode_var tc = o->type();
1774           if (tc->equivalent(CORBA::_tc_double))
1775             {
1776               CORBA::Double d;
1777               *o >>= d;
1778               return d;
1779             }
1780           if (tc->equivalent(CORBA::_tc_long))
1781             {
1782               CORBA::Long d;
1783               *o >>= d;
1784               return d;
1785             }
1786           stringstream msg;
1787           msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1788           msg << " : " << __FILE__ << ":" << __LINE__;
1789           throw YACS::ENGINE::ConversionException(msg.str());
1790         }
1791     };
1792     template <ImplType IMPLOUT, class TOUT>
1793     struct convertToYacsInt<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1794     {
1795       static inline long convert(const TypeCode *t,CORBA::Any* o,void*)
1796         {
1797           CORBA::Long d;
1798           if(*o >>= d)
1799             return d;
1800           stringstream msg;
1801           msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1802           msg << " : " << __FILE__ << ":" << __LINE__;
1803           throw YACS::ENGINE::ConversionException(msg.str());
1804         }
1805     };
1806     template <ImplType IMPLOUT, class TOUT>
1807     struct convertToYacsString<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1808     {
1809       static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*)
1810         {
1811           const char *s;
1812           if(*o >>=s)
1813             return s;
1814           stringstream msg;
1815           msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1816           msg << " : " << __FILE__ << ":" << __LINE__;
1817           throw YACS::ENGINE::ConversionException(msg.str());
1818         }
1819     };
1820     template <ImplType IMPLOUT, class TOUT>
1821     struct convertToYacsBool<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1822     {
1823       static inline bool convert(const TypeCode *t,CORBA::Any* o,void*)
1824         {
1825           CORBA::Boolean b;
1826           if(*o >>= CORBA::Any::to_boolean(b))
1827             return b;
1828           stringstream msg;
1829           msg << "Problem in Corba to TOUT conversion: kind= " << t->kind() ;
1830           msg << " : " << __FILE__ << ":" << __LINE__;
1831           throw YACS::ENGINE::ConversionException(msg.str());
1832         }
1833     };
1834     template <ImplType IMPLOUT, class TOUT>
1835     struct convertToYacsObjref<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1836     {
1837       static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*,int protocol)
1838         {
1839           char file[]="/tmp/XXXXXX";
1840           if(t->isA(Runtime::_tc_file))
1841             {
1842               Engines::Salome_file_ptr sf;
1843               *o >>= sf;
1844               Salome_file_i* f=new Salome_file_i();
1845               mkstemp(file);
1846               f->setDistributedFile(file);
1847               f->connect(sf);
1848               f->recvFiles();
1849               delete f;
1850               return file;
1851             }
1852           else if(strncmp(t->id(),"python",6)==0)
1853             {
1854               const char *s;
1855               Engines::fileBlock * buffer;
1856               if(*o >>=buffer)
1857                 {
1858                   s=(const char*)buffer->get_buffer();
1859
1860                   if(protocol !=4)
1861                     {
1862                       std::string mystr(s,buffer->length());
1863                       return mystr;
1864                     }
1865
1866                   PyGILState_STATE gstate = PyGILState_Ensure(); 
1867                   PyObject* mod=PyImport_ImportModule("pickle");
1868                   PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",s,buffer->length());
1869                   PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",ob,protocol);
1870                   DEBTRACE(PyObject_Repr(pickled));
1871                   std::string mystr=PyBytes_AsString(pickled);
1872                   Py_DECREF(mod);
1873                   Py_DECREF(ob);
1874                   Py_DECREF(pickled);
1875                   PyGILState_Release(gstate);
1876
1877                   return mystr;
1878                 }
1879               stringstream msg;
1880               msg << "Problem in CORBA (protocol python) to TOUT conversion: kind= " << t->kind() ;
1881               msg << " : " << __FILE__ << ":" << __LINE__;
1882               throw YACS::ENGINE::ConversionException(msg.str());
1883             }
1884           else if(strncmp(t->id(),"json",4)==0)
1885             {
1886               const char *s;
1887               if(*o >>=s)
1888                 {
1889                   return s;
1890                 }
1891               stringstream msg;
1892               msg << "Problem in CORBA (protocol json) to TOUT conversion: kind= " << t->kind() ;
1893               msg << " : " << __FILE__ << ":" << __LINE__;
1894               throw YACS::ENGINE::ConversionException(msg.str());
1895             }
1896           else
1897             {
1898               CORBA::Object_var ObjRef ;
1899               *o >>= CORBA::Any::to_object(ObjRef) ;
1900               CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef);
1901               return (char *)objref;
1902             }
1903         }
1904     };
1905     template <ImplType IMPLOUT, class TOUT>
1906     struct convertToYacsSequence<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1907     {
1908       static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::vector<TOUT>& v)
1909         {
1910           CORBA::TypeCode_var tc=o->type();
1911           if (tc->kind() != CORBA::tk_sequence)
1912             {
1913               stringstream msg;
1914               msg << "Not a sequence corba type " << tc->kind();
1915               msg << " : " << __FILE__ << ":" << __LINE__;
1916               throw YACS::ENGINE::ConversionException(msg.str());
1917             }
1918           DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1919           DynamicAny::DynSequence_ptr ds=DynamicAny::DynSequence::_narrow(dynany);
1920           CORBA::release(dynany);
1921           DynamicAny::AnySeq_var as=ds->get_elements();
1922           int len=as->length();
1923           v.resize(len);
1924           for(int i=0;i<len;i++)
1925             {
1926 #ifdef REFCNT
1927               DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1928 #endif
1929               TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(t->contentType(),&as[i],0);
1930               v[i]=ro;
1931             }
1932           ds->destroy();
1933           CORBA::release(ds);
1934           for(int i=0;i<len;i++)
1935             {
1936 #ifdef REFCNT
1937               DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1938 #endif
1939             }
1940         }
1941     };
1942     template <ImplType IMPLOUT, class TOUT>
1943     struct convertToYacsStruct<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1944     {
1945       static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::map<std::string,TOUT>& m)
1946         {
1947           CORBA::TypeCode_var tc=o->type();
1948           DEBTRACE(tc->kind());
1949           if (tc->kind() != CORBA::tk_struct)
1950             {
1951               stringstream msg;
1952               msg << "Not a struct corba type " << tc->kind();
1953               msg << " : " << __FILE__ << ":" << __LINE__;
1954               throw YACS::ENGINE::ConversionException(msg.str());
1955             }
1956           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1957           DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1958           DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(dynany);
1959           CORBA::release(dynany);
1960           DynamicAny::NameValuePairSeq_var as=ds->get_members();
1961           int len=as->length();
1962           for(int i=0;i<len;i++)
1963             {
1964               std::string name=as[i].id.in();
1965               DEBTRACE(name);
1966               CORBA::Any value=as[i].value;
1967 #ifdef REFCNT
1968               DEBTRACE("refcount CORBA value: " << ((omni::TypeCode_base*)value.pd_tc.in())->pd_ref_count);
1969 #endif
1970               TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),&value,0);
1971               m[name]=ro;
1972             }
1973           ds->destroy();
1974           CORBA::release(ds);
1975         }
1976     };
1977     /* End of ToYacs Convertor for CORBAImpl */
1978
1979     //! FromYacs Convertor for CORBAImpl
1980     /*!
1981      * Convert YACS<CORBA::Any*> intermediate types to CORBA::Any* types (CORBAImpl)
1982      */
1983     template <>
1984     struct convertFromYacsDouble<CORBAImpl,CORBA::Any*>
1985     {
1986       static inline CORBA::Any* convert(const TypeCode *t,double o)
1987         {
1988           CORBA::Any *any = new CORBA::Any();
1989           *any <<= (CORBA::Double)o;
1990           return any;
1991         }
1992     };
1993     template <>
1994     struct convertFromYacsInt<CORBAImpl,CORBA::Any*>
1995     {
1996       static inline CORBA::Any* convert(const TypeCode *t,long o)
1997         {
1998           CORBA::Any *any = new CORBA::Any();
1999           *any <<= (CORBA::Long)o;
2000           return any;
2001         }
2002     };
2003     template <>
2004     struct convertFromYacsString<CORBAImpl,CORBA::Any*>
2005     {
2006       static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2007         {
2008           CORBA::Any *any = new CORBA::Any();
2009           *any <<= o.c_str();
2010           return any;
2011         }
2012     };
2013     template <>
2014     struct convertFromYacsBool<CORBAImpl,CORBA::Any*>
2015     {
2016       static inline CORBA::Any* convert(const TypeCode *t,bool o)
2017         {
2018           CORBA::Any *any = new CORBA::Any();
2019           *any <<= CORBA::Any::from_boolean(o);
2020           return any;
2021         }
2022     };
2023     template <>
2024     struct convertFromYacsObjref<CORBAImpl,CORBA::Any*>
2025     {
2026       static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2027         {
2028           CORBA::Object_var obref;
2029
2030           if(t->isA(Runtime::_tc_file))
2031             {
2032               //It's an objref file. Convert it specially
2033               Salome_file_i* aSalome_file = new Salome_file_i();
2034               try
2035                 {
2036                   aSalome_file->setLocalFile(o.c_str());
2037                   obref = aSalome_file->_this();
2038                   aSalome_file->_remove_ref();
2039                 }
2040               catch (const SALOME::SALOME_Exception& e)
2041                 {
2042                   stringstream msg;
2043                   msg << e.details.text;
2044                   msg << " : " << __FILE__ << ":" << __LINE__;
2045                   throw YACS::ENGINE::ConversionException(msg.str());
2046                 }
2047             }
2048           else if(strncmp(t->id(),"python",6)==0 )
2049             {
2050               CORBA::Any *any = new CORBA::Any();
2051               Engines::fileBlock * buffer=new Engines::fileBlock();
2052               buffer->length(o.length());
2053               CORBA::Octet *buf=buffer->get_buffer();
2054               memcpy(buf,o.c_str(),o.length());
2055               *any <<= buffer;
2056               return any;
2057             }
2058           else if(strncmp(t->id(),"json",4)==0)
2059             {
2060               CORBA::Any *any = new CORBA::Any();
2061               *any <<= o.c_str();
2062               return any;
2063             }
2064           else
2065             {
2066               try
2067                 {
2068                   obref=getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
2069                 }
2070               catch(CORBA::Exception& ex)
2071                 {
2072                   throw ConversionException("Can't get reference to object");
2073                 }
2074               if( CORBA::is_nil(obref) )
2075                 {
2076                   throw ConversionException("Can't get reference to object");
2077                 }
2078             }
2079 #ifdef REFCNT
2080           DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2081 #endif
2082           CORBA::Any *any = new CORBA::Any();
2083           *any <<= obref;
2084 #ifdef REFCNT
2085           DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2086 #endif
2087           return any;
2088         }
2089     };
2090
2091     template <>
2092     struct convertFromYacsSequence<CORBAImpl,CORBA::Any*>
2093     {
2094       static inline CORBA::Any* convert(const TypeCode *t,std::vector<CORBA::Any*>& v)
2095         {
2096           CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2097           std::vector<CORBA::Any*>::const_iterator iter;
2098
2099           // Build an Any from vector v
2100           int isObjref=0;
2101           if(t->contentType()->kind() == Objref)
2102             isObjref=1;
2103
2104           CORBA::TypeCode_var tc=getCorbaTC(t);
2105
2106           DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2107           DynamicAny::DynSequence_var ds = DynamicAny::DynSequence::_narrow(dynany);
2108           ds->set_length(v.size());
2109
2110           for(iter=v.begin();iter!=v.end();iter++)
2111             {
2112               DynamicAny::DynAny_var temp=ds->current_component();
2113               CORBA::Any* a=*iter;
2114               //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2115               if(isObjref)
2116                 {
2117                   CORBA::Object_var zzobj ;
2118                   *a >>= CORBA::Any::to_object(zzobj) ;
2119                   temp->insert_reference(zzobj);
2120                 }
2121               else
2122                 temp->from_any(*a);
2123
2124               //delete intermediate any
2125               delete a;
2126               ds->next();
2127             }
2128
2129           CORBA::Any *any=ds->to_any();
2130           ds->destroy();
2131           return any;
2132         }
2133     };
2134     template <>
2135     struct convertFromYacsStruct<CORBAImpl,CORBA::Any*>
2136     {
2137       static inline CORBA::Any* convert(const TypeCode *t,std::map<std::string,CORBA::Any*>& m)
2138         {
2139           CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2140
2141           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2142           int nMember=tst->memberCount();
2143           DEBTRACE("nMember="<<nMember);
2144
2145           CORBA::TypeCode_var tc=getCorbaTC(t);
2146           DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2147           DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(dynany);
2148
2149           for(int i=0;i<nMember;i++)
2150             {
2151               DynamicAny::DynAny_var temp=ds->current_component();
2152               const char * name=tst->memberName(i);
2153               DEBTRACE("Member name="<<name);
2154               //do not test member presence : test has been done in ToYacs convertor
2155               CORBA::Any* a=m[name];
2156               //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2157               CORBA::TypeCode_var atc = tc->member_type(i);
2158               if(atc->kind()==CORBA::tk_objref)
2159                 {
2160                   //special treatment for objref
2161                   CORBA::Object_var zzobj ;
2162                   *a >>= CORBA::Any::to_object(zzobj) ;
2163                   temp->insert_reference(zzobj);
2164                 }
2165               else
2166                 {
2167                   temp->from_any(*a);
2168                 }
2169               //delete intermediate any
2170               delete a;
2171               ds->next();
2172             }
2173           CORBA::Any *any=ds->to_any();
2174           ds->destroy();
2175
2176           return any;
2177         }
2178     };
2179     /* End of FromYacs Convertor for CORBAImpl */
2180
2181     /* Some shortcuts for CORBA to CORBA conversion */
2182     template <>
2183     inline CORBA::Any* convertDouble<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2184     {
2185       CORBA::TypeCode_var tc = o->type();
2186       if (tc->equivalent(CORBA::_tc_double))
2187         {
2188           return o;
2189         }
2190       if (tc->equivalent(CORBA::_tc_long))
2191         {
2192           CORBA::Long d;
2193           *o >>= d;
2194           CORBA::Any *any = new CORBA::Any();
2195           *any <<= (CORBA::Double)d;
2196           return any;
2197         }
2198       stringstream msg;
2199       msg << "Not a double or long corba type " << tc->kind();
2200       msg << " : " << __FILE__ << ":" << __LINE__;
2201       throw YACS::ENGINE::ConversionException(msg.str());
2202     }
2203     template <>
2204     inline CORBA::Any* convertInt<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2205     {
2206       return o;
2207     }
2208     template <>
2209     inline CORBA::Any* convertString<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2210     {
2211       return o;
2212     }
2213     template <>
2214     inline CORBA::Any* convertBool<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2215     {
2216       return o;
2217     }
2218     template <>
2219     inline CORBA::Any* convertObjref<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2220     {
2221       return o;
2222     }
2223     template <>
2224     inline CORBA::Any* convertStruct<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2225     {
2226       return o;
2227     }
2228     /* End of shortcuts for CORBA to CORBA conversion */
2229
2230     //! ToYacs Convertor for CPPImpl
2231     /*!
2232      * This convertor converts Python object to YACS<TOUT> types
2233      * Partial specialization for Python implementation with type PyObject* (PYTHONImpl)
2234      */
2235     template <ImplType IMPLOUT, class TOUT>
2236     struct convertToYacsDouble<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2237     {
2238       static inline double convert(const TypeCode *t,void* o,const TypeCode* intype)
2239         {
2240           if(intype->kind()==YACS::ENGINE::Double)
2241             {
2242               return *(double*)o;
2243             }
2244           else if(intype->kind()==YACS::ENGINE::Int)
2245             {
2246               return *(long*)o;
2247             }
2248           stringstream msg;
2249           msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2250           msg << " : " << __FILE__ << ":" << __LINE__;
2251           throw YACS::ENGINE::ConversionException(msg.str());
2252         }
2253     };
2254     template <ImplType IMPLOUT, class TOUT>
2255     struct convertToYacsInt<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2256     {
2257       static inline long convert(const TypeCode *t,void* o,const TypeCode* intype)
2258         {
2259           if(intype->kind()==YACS::ENGINE::Int)
2260             {
2261               return *(long*)o;
2262             }
2263           stringstream msg;
2264           msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2265           msg << " : " << __FILE__ << ":" << __LINE__;
2266           throw YACS::ENGINE::ConversionException(msg.str());
2267         }
2268     };
2269     /* End of ToYacs Convertor for CPPImpl */
2270
2271     //Python conversions
2272     std::string convertPyObjectXml(const TypeCode *t,PyObject *data)
2273       {
2274         return YacsConvertor<PYTHONImpl,PyObject*,void*,XMLImpl,std::string>(t,data,0);
2275       }
2276     YACS::ENGINE::Any* convertPyObjectNeutral(const TypeCode *t,PyObject *data)
2277       {
2278         return YacsConvertor<PYTHONImpl,PyObject*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2279       }
2280     CORBA::Any* convertPyObjectCorba(const TypeCode *t,PyObject *data)
2281       {
2282         return YacsConvertor<PYTHONImpl,PyObject*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2283       }
2284     PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *data)
2285       {
2286         return YacsConvertor<PYTHONImpl,PyObject*,void*,PYTHONImpl,PyObject*>(t,data,0);
2287       }
2288
2289     std::string convertPyObjectToString(PyObject* ob)
2290     {
2291       PyObject *s;
2292       PyGILState_STATE gstate = PyGILState_Ensure(); 
2293       // TODO: separate treatment for string (maybe with bad encoding?) and other types of PyObject ?
2294       // Do we need str() or repr() and what are the possible causes of failure of str() ?
2295       // not clear, needs more analysis.
2296       s=PyObject_Str(ob);
2297       if (s == NULL) // for instance string with bad encoding, non utf-8
2298       {
2299         s=PyObject_ASCII(ob); // escape non ASCII characters and like repr(), which is not the same as str()...
2300       }
2301       Py_ssize_t size;
2302       const char* characters =  PyUnicode_AsUTF8AndSize(s, &size);
2303       std::string ss( characters, size);
2304       Py_DECREF(s);
2305       PyGILState_Release(gstate);
2306       return ss;
2307     }
2308
2309     //XML conversions
2310     PyObject* convertXmlPyObject(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2311       {
2312         return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,PYTHONImpl,PyObject*>(t,doc,cur);
2313       }
2314     YACS::ENGINE::Any* convertXmlNeutral(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2315       {
2316         return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,NEUTRALImpl,YACS::ENGINE::Any*>(t,doc,cur);
2317       }
2318     CORBA::Any* convertXmlCorba(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2319       {
2320         return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,CORBAImpl,CORBA::Any*>(t,doc,cur);
2321       }
2322     PyObject* convertXmlStrPyObject(const TypeCode *t,std::string data)
2323       {
2324         xmlDocPtr doc;
2325         xmlNodePtr cur;
2326         PyObject *ob=NULL;
2327         doc = xmlParseMemory(data.c_str(), strlen(data.c_str()));
2328         if (doc == NULL )
2329         {
2330           std::stringstream msg;
2331           msg << "Problem in conversion: XML Document not parsed successfully ";
2332           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2333           throw YACS::ENGINE::ConversionException(msg.str());
2334         }
2335         cur = xmlDocGetRootElement(doc);
2336         if (cur == NULL)
2337         {
2338           xmlFreeDoc(doc);
2339           std::stringstream msg;
2340           msg << "Problem in conversion: empty XML Document";
2341           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2342           throw YACS::ENGINE::ConversionException(msg.str());
2343         }
2344         while (cur != NULL)
2345         {
2346           if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
2347           {
2348             ob=convertXmlPyObject(t,doc,cur);
2349             break;
2350           }
2351           cur = cur->next;
2352         }
2353         xmlFreeDoc(doc);
2354         if(ob==NULL)
2355         {
2356           std::stringstream msg;
2357           msg << "Problem in conversion: incorrect XML value";
2358           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2359           throw YACS::ENGINE::ConversionException(msg.str());
2360         }
2361         return ob;
2362       }
2363     //NEUTRAL conversions
2364     PyObject* convertNeutralPyObject(const TypeCode *t,YACS::ENGINE::Any* data)
2365       {
2366         return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2367       }
2368     std::string convertNeutralXml(const TypeCode *t,YACS::ENGINE::Any* data)
2369       {
2370         return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,XMLImpl,std::string>(t,data,0);
2371       }
2372     CORBA::Any* convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any* data)
2373       {
2374         return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2375       }
2376     YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* data)
2377       {
2378         data->incrRef();
2379         return data;
2380       }
2381
2382     //CORBA conversions
2383     PyObject* convertCorbaPyObject(const TypeCode *t,CORBA::Any* data)
2384       {
2385         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2386       }
2387     std::string convertCorbaXml(const TypeCode *t,CORBA::Any* data)
2388       {
2389         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,XMLImpl,std::string>(t,data,0);
2390       }
2391     YACS::ENGINE::Any* convertCorbaNeutral(const TypeCode *t,CORBA::Any* data)
2392       {
2393         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2394       }
2395     CORBA::Any *convertCorbaCorba(const TypeCode *t,CORBA::Any *data)
2396       {
2397         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2398       }
2399
2400     //! Basic template checker from type TIN 
2401     /*!
2402      * This checker does nothing : throws exception
2403      * It must be partially specialize for a specific type (TIN)
2404      */
2405     template <ImplType IMPLIN,class TIN,class TIN2>
2406     static inline bool checkDouble(const TypeCode *t,TIN o,TIN2 aux)
2407         {
2408           stringstream msg;
2409           msg << "Check not implemented for Implementation: " << IMPLIN ;
2410           msg << " : " << __FILE__ << ":" << __LINE__;
2411           throw YACS::ENGINE::ConversionException(msg.str());
2412         }
2413     template <ImplType IMPLIN,class TIN,class TIN2>
2414     static inline bool checkInt(const TypeCode *t,TIN o,TIN2 aux)
2415         {
2416           stringstream msg;
2417           msg << "Check not implemented for Implementation: " << IMPLIN ;
2418           msg << " : " << __FILE__ << ":" << __LINE__;
2419           throw YACS::ENGINE::ConversionException(msg.str());
2420         }
2421     template <ImplType IMPLIN,class TIN,class TIN2>
2422     static inline bool checkBool(const TypeCode *t,TIN o,TIN2 aux)
2423         {
2424           stringstream msg;
2425           msg << "Check not implemented for Implementation: " << IMPLIN ;
2426           msg << " : " << __FILE__ << ":" << __LINE__;
2427           throw YACS::ENGINE::ConversionException(msg.str());
2428         }
2429     template <ImplType IMPLIN,class TIN,class TIN2>
2430     static inline bool checkString(const TypeCode *t,TIN o,TIN2 aux)
2431         {
2432           stringstream msg;
2433           msg << "Check not implemented for Implementation: " << IMPLIN ;
2434           msg << " : " << __FILE__ << ":" << __LINE__;
2435           throw YACS::ENGINE::ConversionException(msg.str());
2436         }
2437     template <ImplType IMPLIN,class TIN,class TIN2>
2438     static inline bool checkObjref(const TypeCode *t,TIN o,TIN2 aux)
2439         {
2440           stringstream msg;
2441           msg << "Check not implemented for Implementation: " << IMPLIN ;
2442           msg << " : " << __FILE__ << ":" << __LINE__;
2443           throw YACS::ENGINE::ConversionException(msg.str());
2444         }
2445     template <ImplType IMPLIN,class TIN,class TIN2>
2446     static inline bool checkSequence(const TypeCode *t,TIN o,TIN2 aux)
2447         {
2448           stringstream msg;
2449           msg << "Check not implemented for Implementation: " << IMPLIN ;
2450           msg << " : " << __FILE__ << ":" << __LINE__;
2451           throw YACS::ENGINE::ConversionException(msg.str());
2452         }
2453     template <ImplType IMPLIN,class TIN,class TIN2>
2454     static inline bool checkStruct(const TypeCode *t,TIN o,TIN2 aux)
2455         {
2456           stringstream msg;
2457           msg << "Check not implemented for Implementation: " << IMPLIN ;
2458           msg << " : " << __FILE__ << ":" << __LINE__;
2459           throw YACS::ENGINE::ConversionException(msg.str());
2460         }
2461     template <ImplType IMPLIN,class TIN,class TIN2>
2462     static inline bool checkArray(const TypeCode *t,TIN o,TIN2 aux)
2463         {
2464           stringstream msg;
2465           msg << "Check not implemented for Implementation: " << IMPLIN ;
2466           msg << " : " << __FILE__ << ":" << __LINE__;
2467           throw YACS::ENGINE::ConversionException(msg.str());
2468         }
2469
2470     template <ImplType IMPLIN,class TIN,class TIN2>
2471     inline bool YacsChecker(const TypeCode *t,TIN o,TIN2 aux)
2472       {
2473          int tk=t->kind();
2474          switch(t->kind())
2475            {
2476            case Double:
2477              return checkDouble<IMPLIN,TIN,TIN2>(t,o,aux);
2478            case Int:
2479              return checkInt<IMPLIN,TIN,TIN2>(t,o,aux);
2480            case String:
2481              return checkString<IMPLIN,TIN,TIN2>(t,o,aux);
2482            case Bool:
2483              return checkBool<IMPLIN,TIN,TIN2>(t,o,aux);
2484            case Objref:
2485              return checkObjref<IMPLIN,TIN,TIN2>(t,o,aux);
2486            case Sequence:
2487              return checkSequence<IMPLIN,TIN,TIN2>(t,o,aux);
2488            case Array:
2489              return checkArray<IMPLIN,TIN,TIN2>(t,o,aux);
2490            case Struct:
2491              return checkStruct<IMPLIN,TIN,TIN2>(t,o,aux);
2492            default:
2493              break;
2494            }
2495          stringstream msg;
2496          msg << "Check not implemented for kind= " << tk ;
2497          msg << " : " << __FILE__ << ":" << __LINE__;
2498          throw YACS::ENGINE::ConversionException(msg.str());
2499       }
2500     template<>
2501     inline bool checkDouble<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2502       {
2503         if (PyFloat_Check(o))
2504           return true;
2505         else if(PyLong_Check(o))
2506           return true;
2507         else
2508           {
2509             stringstream msg;
2510             msg << "Not a python double ";
2511             throw YACS::ENGINE::ConversionException(msg.str());
2512           }
2513       }
2514     template<>
2515     inline bool checkInt<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2516       {
2517           if (PyLong_Check(o))
2518             return true;
2519           else
2520             {
2521               stringstream msg;
2522               msg << "Not a python integer ";
2523               throw YACS::ENGINE::ConversionException(msg.str());
2524             }
2525       }
2526     template<>
2527     inline bool checkBool<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2528       {
2529           if (PyBool_Check(o))
2530               return true;
2531           else if(PyLong_Check(o))
2532               return true;
2533           else
2534             {
2535               stringstream msg;
2536               msg << "Not a python boolean " ;
2537               throw YACS::ENGINE::ConversionException(msg.str());
2538             }
2539
2540       }
2541     template<>
2542     inline bool checkString<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2543       {
2544           if (PyUnicode_Check(o))
2545             return true;
2546           else
2547             {
2548               stringstream msg;
2549               msg << "Not a python string " ;
2550               throw YACS::ENGINE::ConversionException(msg.str());
2551             }
2552       }
2553     template<>
2554     inline bool checkObjref<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2555       {
2556           if (PyUnicode_Check(o))
2557             return true;
2558           if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true)
2559             return true;
2560           else if(strncmp(t->id(),"json",4)==0) // The python object must be json pickable
2561             {
2562                // The python object should be json compliant (to improve)
2563                return true;
2564             }
2565           else
2566             {
2567               // The python object should be a CORBA obj (to improve)
2568                return true;
2569             }
2570       }
2571     template<>
2572     inline bool checkSequence<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2573       {
2574         if(!PySequence_Check(o))
2575           {
2576             stringstream msg;
2577             msg << "python object is not a sequence " ;
2578             throw YACS::ENGINE::ConversionException(msg.str());
2579           }
2580         int length=PySequence_Size(o);
2581         for(int i=0;i<length;i++)
2582           {
2583             PyObject *item=PySequence_ITEM(o,i);
2584             try
2585               {
2586                 YacsChecker<PYTHONImpl,PyObject*,void*>(t->contentType(),item,0);
2587               }
2588             catch(ConversionException& ex)
2589               {
2590                 stringstream msg;
2591                 msg << ex.what() << " for sequence element " << i;
2592                 throw YACS::ENGINE::ConversionException(msg.str(),false);
2593               }
2594             Py_DECREF(item);
2595           }
2596         return true;
2597       }
2598     template<>
2599     inline bool checkStruct<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2600       {
2601         PyObject *value;
2602         if(!PyDict_Check(o))
2603           {
2604             stringstream msg;
2605             msg << "python object is not a dict " ;
2606             throw YACS::ENGINE::ConversionException(msg.str());
2607           }
2608         YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2609         int nMember=tst->memberCount();
2610         for(int i=0;i<nMember;i++)
2611           {
2612             std::string name=tst->memberName(i);
2613             TypeCode* tm=tst->memberType(i);
2614             value=PyDict_GetItemString(o, name.c_str());
2615             if(value==NULL)
2616               {
2617                 stringstream msg;
2618                 msg << "member " << name << " not present " ;
2619                 throw YACS::ENGINE::ConversionException(msg.str());
2620               }
2621             try
2622               {
2623                 YacsChecker<PYTHONImpl,PyObject*,void*>(tm,value,0);
2624               }
2625             catch(ConversionException& ex)
2626               {
2627                 std::string s=" for struct member "+name;
2628                 throw YACS::ENGINE::ConversionException(ex.what()+s,false);
2629               }
2630           }
2631         return true;
2632       }
2633
2634     bool checkPyObject(const TypeCode *t,PyObject* ob)
2635       {
2636         return YacsChecker<PYTHONImpl,PyObject*,void*>(t,ob,0);
2637       }
2638   }
2639 }