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