Salome HOME
23701e50eb7c7a7e8352d3c1968d178071f8593a
[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           if (PyFloat_Check(o))
684             x=PyFloat_AS_DOUBLE(o);
685           else if(PyLong_Check(o))
686             x=PyLong_AsLong(o);
687           else
688             {
689               stringstream msg;
690               msg << "Not a python double. ";
691 #ifdef _DEVDEBUG_
692               msg << "kind=" << t->kind() ;
693               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
694 #endif
695               throw YACS::ENGINE::ConversionException(msg.str());
696             }
697           return x;
698         }
699     };
700     template <ImplType IMPLOUT, class TOUT>
701     struct convertToYacsInt<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
702     {
703       static inline long convert(const TypeCode *t,PyObject* o,void*)
704         {
705           long l;
706           if(PyLong_Check(o))
707             l=PyLong_AsLong(o);
708           else
709             {
710               stringstream msg;
711               msg << "Not a python integer. ";
712 #ifdef _DEVDEBUG_
713               msg << "kind=" << t->kind() ;
714               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
715 #endif
716               throw YACS::ENGINE::ConversionException(msg.str());
717             }
718           return l;
719         }
720     };
721     template <ImplType IMPLOUT, class TOUT>
722     struct convertToYacsString<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
723     {
724       static inline std::string convert(const TypeCode *t,PyObject* o,void*)
725         {
726           std::string s;
727           if (PyUnicode_Check(o))
728             {
729               Py_ssize_t size;
730               const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
731               if (!ptr)
732                 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
733               s.assign(ptr, size);
734             }
735           else
736             {
737               stringstream msg;
738               msg << "Not a python string. ";
739 #ifdef _DEVDEBUG_
740               msg << "kind=" << t->kind() ;
741               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
742 #endif
743               throw YACS::ENGINE::ConversionException(msg.str());
744             }
745           return s;
746         }
747     };
748     template <ImplType IMPLOUT, class TOUT>
749     struct convertToYacsBool<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
750     {
751       static inline bool convert(const TypeCode *t,PyObject* o,void*)
752         {
753           bool l;
754           if (PyBool_Check(o))
755               l=(o==Py_True);
756           else if(PyLong_Check(o))
757               l=(PyLong_AsLong(o)!=0);
758           else
759             {
760               stringstream msg;
761               msg << "Not a python boolean. ";
762 #ifdef _DEVDEBUG_
763               msg << "kind=" << t->kind() ;
764               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
765 #endif
766               throw YACS::ENGINE::ConversionException(msg.str());
767             }
768           return l;
769         }
770     };
771     template <ImplType IMPLOUT, class TOUT>
772     struct convertToYacsObjref<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
773     {
774       static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol)
775         {
776           if (PyUnicode_Check(o) && strncmp(t->id(),"python",6)!=0)
777             {
778               // the objref is used by Python as a string (prefix:value) keep it as a string
779               Py_ssize_t size;
780               std::string s;
781               const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
782               if (!ptr)
783                 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
784               s.assign(ptr, size);
785               return s;
786             }
787           if(strncmp(t->id(),"python",6)==0)
788             {
789               bool somthingToDo = YACS::ENGINE::PythonEntry::GetDestroyStatus(o);
790               if( somthingToDo )
791                 YACS::ENGINE::PythonEntry::DoNotTouchFileIfProxy(o);
792               // It's a native Python object pickle it
793               PyObject* mod=PyImport_ImportModule("pickle");
794               PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol);
795               if( somthingToDo )
796                 YACS::ENGINE::PythonEntry::UnlinkOnDestructorIfProxy(o);
797               DEBTRACE(PyObject_Repr(pickled) );
798               Py_DECREF(mod);
799               if(pickled==NULL)
800                 {
801                   PyErr_Print();
802                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
803                 }
804               std::string mystr(PyBytes_AsString(pickled),PyBytes_Size(pickled));
805               Py_DECREF(pickled);
806               return mystr;
807             }
808           else if(strncmp(t->id(),"json",4)==0)
809             {
810               // It's a Python  object convert it to json 
811               PyObject* mod=PyImport_ImportModule("simplejson");
812               if(mod==NULL)
813                 {
814                   PyErr_Print();
815                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
816                 }
817               PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"O",o);
818               Py_DECREF(mod);
819               if(pickled==NULL)
820                 {
821                   PyErr_Print();
822                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
823                 }
824               std::string mystr=PyBytes_AsString(pickled);
825               Py_DECREF(pickled);
826               return mystr;
827             }
828           else
829             {
830               // It should be a CORBA Object convert it to an IOR string
831               PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),(char *)"object_to_string",(char *)"O",o);
832               if(pystring==NULL)
833                 {
834                   PyErr_Print();
835                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
836                 }
837               Py_ssize_t size;
838               std::string mystr;
839               const char *ptr = PyUnicode_AsUTF8AndSize(pystring, &size);
840               if (!ptr)
841                 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
842               mystr.assign(ptr, size);
843               Py_DECREF(pystring);
844               return mystr;
845             }
846         }
847     };
848     template <ImplType IMPLOUT, class TOUT>
849     struct convertToYacsSequence<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
850     {
851       static inline void convert(const TypeCode *t,PyObject* o,void*,std::vector<TOUT>& v)
852         {
853           if(!PySequence_Check(o))
854             {
855               stringstream msg;
856               msg << "Problem in conversion: the python object is not a sequence " << std::endl;
857 #ifdef _DEVDEBUG_
858               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
859 #endif
860               throw YACS::ENGINE::ConversionException(msg.str());
861             }
862           int length=PySequence_Size(o);
863           DEBTRACE("length: " << length );
864           v.resize(length);
865           for(int i=0;i<length;i++)
866             {
867               PyObject *item=PySequence_ITEM(o,i);
868 #ifdef _DEVDEBUG_
869               std::cerr <<"item[" << i << "]=";
870               PyObject_Print(item,stderr,Py_PRINT_RAW);
871               std::cerr << std::endl;
872 #endif
873               DEBTRACE( "item refcnt: " << item->ob_refcnt );
874               try
875                 {
876                   TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(t->contentType(),item,0);
877                   v[i]=ro;
878                   Py_DECREF(item);
879                 }
880               catch(ConversionException& ex)
881                 {
882                   stringstream msg;
883                   msg << ex.what() << " for sequence element " << i;
884                   throw YACS::ENGINE::ConversionException(msg.str(),false);
885                 }
886             }
887         }
888     };
889     template <ImplType IMPLOUT, class TOUT>
890     struct convertToYacsStruct<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
891     {
892       static inline void convert(const TypeCode *t,PyObject* o,void*,std::map<std::string,TOUT>& m)
893         {
894           DEBTRACE( "o refcnt: " << o->ob_refcnt );
895           PyObject *key, *value;
896           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
897           int nMember=tst->memberCount();
898           DEBTRACE("nMember="<<nMember);
899           for(int i=0;i<nMember;i++)
900             {
901               std::string name=tst->memberName(i);
902               DEBTRACE("Member name="<<name);
903               TypeCode* tm=tst->memberType(i);
904               value=PyDict_GetItemString(o, name.c_str());
905               if(value==NULL)
906                 {
907                   //member name not present
908                   //TODO delete all allocated objects in m
909 #ifdef _DEVDEBUG_
910                   PyObject_Print(o,stderr,Py_PRINT_RAW);
911                   std::cerr << std::endl;
912 #endif
913                   stringstream msg;
914                   msg << "member " << name << " not present " ;
915                   throw YACS::ENGINE::ConversionException(msg.str());
916                 }
917               DEBTRACE( "value refcnt: " << value->ob_refcnt );
918               try
919                 {
920                   TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(tm,value,0);
921                   m[name]=ro;
922                 }
923               catch(ConversionException& ex)
924                 {
925                   std::string s=" for struct member "+name;
926                   throw YACS::ENGINE::ConversionException(ex.what()+s,false);
927                 }
928             }
929         }
930     };
931     /* End of ToYacs Convertor for PYTHONImpl */
932
933     //! FromYacs Convertor for PYTHONImpl
934     /*!
935      * Convert YACS<PyObject*> intermediate types to PyObject* types (PYTHONImpl)
936      */
937     template <>
938     struct convertFromYacsDouble<PYTHONImpl,PyObject*>
939     {
940       static inline PyObject* convert(const TypeCode *t,double o)
941         {
942           PyObject *pyob=PyFloat_FromDouble(o);
943           return pyob;
944         }
945     };
946     template <>
947     struct convertFromYacsInt<PYTHONImpl,PyObject*>
948     {
949       static inline PyObject* convert(const TypeCode *t,long o)
950         {
951           PyObject *pyob=PyLong_FromLong(o);
952           return pyob;
953         }
954     };
955     template <>
956     struct convertFromYacsString<PYTHONImpl,PyObject*>
957     {
958       static inline PyObject* convert(const TypeCode *t,std::string& o)
959         {
960           return PyUnicode_FromString(o.c_str());
961         }
962     };
963     template <>
964     struct convertFromYacsBool<PYTHONImpl,PyObject*>
965     {
966       static inline PyObject* convert(const TypeCode *t,bool o)
967         {
968           return PyBool_FromLong ((long)o);
969         }
970     };
971     template <>
972     struct convertFromYacsObjref<PYTHONImpl,PyObject*>
973     {
974       static inline PyObject* convert(const TypeCode *t,std::string& o)
975         {
976           if(o=="")
977             {
978               Py_INCREF(Py_None);
979               return Py_None;
980             }
981           if(t->isA(Runtime::_tc_file))
982             {
983               //It's an objref file. Convert it specially
984               return PyUnicode_FromString(o.c_str());
985             }
986           if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0"
987             {
988               //It's a python pickled object, unpickled it
989               PyObject* mod=PyImport_ImportModule("pickle");
990               PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length());
991               DEBTRACE(PyObject_Repr(ob));
992               Py_DECREF(mod);
993               if(ob==NULL)
994                 {
995                   PyErr_Print();
996                   throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
997                 }
998               return ob;
999             }
1000           if(strncmp(t->id(),"json",4)==0)
1001             {
1002               // It's a json object unpack it
1003               PyObject* mod=PyImport_ImportModule("simplejson");
1004               if(mod==NULL)
1005                 {
1006                   PyErr_Print();
1007                   throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
1008                 }
1009               PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y",o.c_str());
1010               Py_DECREF(mod);
1011               if(ob==NULL)
1012                 {
1013                   PyErr_Print();
1014                   throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
1015                 }
1016               return ob;
1017             }
1018
1019           /* another way to convert IOR string to CORBA PyObject 
1020           PyObject* ob= PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"string_to_object","s",o.c_str());
1021           DEBTRACE( "Objref python refcnt: " << ob->ob_refcnt );
1022           return ob;
1023           */
1024
1025           //Objref CORBA. prefix=IOR,corbaname,corbaloc
1026           CORBA::Object_var obref;
1027           try
1028             {
1029               obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1030 #ifdef REFCNT
1031               DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1032 #endif
1033             }
1034           catch(CORBA::Exception& ex) 
1035             {
1036               DEBTRACE( "Can't get reference to object." );
1037               throw ConversionException("Can't get reference to object");
1038             }
1039
1040           if(obref->_non_existent())
1041             {
1042               throw ConversionException("non_existent object");
1043             }
1044
1045           if( CORBA::is_nil(obref) )
1046             {
1047               DEBTRACE( "Can't get reference to object (or it was nil)." );
1048               throw ConversionException("Can't get reference to object");
1049             }
1050
1051           if(!obref->_is_a(t->id()))
1052             {
1053               stringstream msg;
1054               msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1055               msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1056               msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1057               throw YACS::ENGINE::ConversionException(msg.str());
1058             }
1059 #ifdef REFCNT
1060           DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1061 #endif
1062 #ifdef _DEVDEBUG_
1063           std::cerr << "_PD_repoId: " << obref->_PD_repoId << std::endl;
1064           std::cerr << "_mostDerivedRepoId: " << obref->_PR_getobj()->_mostDerivedRepoId()  << std::endl;
1065 #endif
1066
1067           //hold_lock is true: caller is supposed to hold the GIL.
1068           //omniorb will not take the GIL
1069           PyObject* ob= getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(obref, 1);
1070
1071 #ifdef _DEVDEBUG_
1072           PyObject_Print(ob,stderr,Py_PRINT_RAW);
1073           std::cerr << std::endl;
1074           std::cerr << "obref is a generic: " << obref->_is_a("IDL:SALOME/GenericObj:1.0") << std::endl;
1075           PyObject_Print(getSALOMERuntime()->get_omnipy(),stderr,Py_PRINT_RAW);
1076           std::cerr << std::endl;
1077 #endif
1078
1079           //ob is a CORBA::Object. Try to convert it to more specific type SALOME/GenericObj
1080           if(obref->_is_a("IDL:SALOME/GenericObj:1.0"))
1081             {
1082               PyObject *result = PyObject_CallMethod(getSALOMERuntime()->get_omnipy(), (char *)"narrow", (char *)"Osi",ob,"IDL:SALOME/GenericObj:1.0",1);
1083               if(result==NULL)
1084                 PyErr_Clear();//Exception during narrow. Keep ob
1085               else if(result==Py_None)
1086                 Py_DECREF(result); //Can't narrow. Keep ob
1087               else
1088                 {
1089                   //Can narrow. Keep result
1090 #ifdef _DEVDEBUG_
1091                   PyObject_Print(result,stderr,Py_PRINT_RAW);
1092                   std::cerr << std::endl;
1093 #endif
1094                   Py_DECREF(ob);
1095                   ob=result;
1096                 }
1097             }
1098
1099 #ifdef REFCNT
1100           DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1101 #endif
1102           return ob;
1103         }
1104     };
1105
1106     template <>
1107     struct convertFromYacsSequence<PYTHONImpl,PyObject*>
1108     {
1109       static inline PyObject* convert(const TypeCode *t,std::vector<PyObject*>& v)
1110         {
1111           std::vector<PyObject*>::const_iterator iter;
1112           PyObject *pyob = PyList_New(v.size());
1113           int i=0;
1114           for(iter=v.begin();iter!=v.end();iter++)
1115             {
1116               PyObject* item=*iter;
1117               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1118               PyList_SetItem(pyob,i,item);
1119               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1120               i++;
1121             }
1122           return pyob;
1123         }
1124     };
1125     template <>
1126     struct convertFromYacsStruct<PYTHONImpl,PyObject*>
1127     {
1128       static inline PyObject* convert(const TypeCode *t,std::map<std::string,PyObject*>& m)
1129         {
1130           PyObject *pyob = PyDict_New();
1131           std::map<std::string, PyObject*>::const_iterator pt;
1132           for(pt=m.begin();pt!=m.end();pt++)
1133             {
1134               std::string name=(*pt).first;
1135               PyObject* item=(*pt).second;
1136               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1137               PyDict_SetItemString(pyob,name.c_str(),item);
1138               Py_DECREF(item);
1139               DEBTRACE( "item refcnt: " << item->ob_refcnt );
1140             }
1141           DEBTRACE( "pyob refcnt: " << pyob->ob_refcnt );
1142           return pyob;
1143         }
1144     };
1145     /* End of FromYacs Convertor for PYTHONImpl */
1146
1147     //! ToYacs Convertor for XMLImpl
1148     /*!
1149      * Partial specialization for XML implementation (XMLImpl)
1150      * This convertor converts xml object to YACS<TOUT> types
1151      */
1152     template <ImplType IMPLOUT, class TOUT>
1153     struct convertToYacsDouble<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1154     {
1155       static inline double convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1156         {
1157           double d=0;
1158           cur = cur->xmlChildrenNode;
1159           while (cur != NULL)
1160             {
1161               if ((!xmlStrcmp(cur->name, (const xmlChar *)"double")))
1162                 {
1163                   //wait a double, got a double
1164                   xmlChar * s = NULL;
1165                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1166                   if (s)
1167                     {
1168                       DEBTRACE( "convertToYacsDouble " << (const char *)s );
1169                       d=Cstr2d((const char *)s);
1170                       xmlFree(s);
1171                     }
1172                   else
1173                     {
1174                       DEBTRACE("############### workaround to improve...");
1175                     }
1176                   return d;
1177                 }
1178               else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1179                 {
1180                   //wait a double, got an int
1181                   xmlChar * s = NULL;
1182                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1183                   if (s)
1184                     {
1185                       DEBTRACE( "convertToYacsDouble " << (const char *)s );
1186                       d=Cstr2d((const char *)s);
1187                       xmlFree(s);
1188                     }
1189                   else
1190                     {
1191                       DEBTRACE("############### workaround to improve...");
1192                     }
1193                   return d;
1194                 }
1195               cur = cur->next;
1196             }
1197           stringstream msg;
1198           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1199           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1200           throw YACS::ENGINE::ConversionException(msg.str());
1201         }
1202     };
1203     template <ImplType IMPLOUT, class TOUT>
1204     struct convertToYacsInt<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1205     {
1206       static inline long convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1207         {
1208           long d=0;
1209           cur = cur->xmlChildrenNode;
1210           while (cur != NULL)
1211             {
1212               if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1213                 {
1214                   xmlChar * s = NULL;
1215                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1216                   if (s)
1217                     {
1218                       DEBTRACE( "convertToYacsInt " << (const char *)s );
1219                       d=atol((const char *)s);
1220                       xmlFree(s);
1221                     }
1222                   else
1223                     {
1224                       DEBTRACE("############### workaround to improve...");
1225                     }
1226                   return d;
1227                 }
1228               cur = cur->next;
1229             }
1230           stringstream msg;
1231           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1232           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1233           throw YACS::ENGINE::ConversionException(msg.str());
1234         }
1235     };
1236     template <ImplType IMPLOUT, class TOUT>
1237     struct convertToYacsString<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1238     {
1239       static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1240         {
1241           cur = cur->xmlChildrenNode;
1242           while (cur != NULL)
1243             {
1244               if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))
1245                 {
1246                   //wait a string, got a string
1247                   xmlChar * s = NULL;
1248                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1249                   if(s==0)return "";
1250                   DEBTRACE( "convertToYacsString " << (const char *)s );
1251                   std::string mystr=std::string((const char *)s);
1252                   xmlFree(s);
1253                   return mystr;
1254                 }
1255               cur = cur->next;
1256             }
1257           stringstream msg;
1258           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1259           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1260           throw YACS::ENGINE::ConversionException(msg.str());
1261         }
1262     };
1263     template <ImplType IMPLOUT, class TOUT>
1264     struct convertToYacsBool<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1265     {
1266       static inline bool convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1267         {
1268           cur = cur->xmlChildrenNode;
1269           while (cur != NULL)
1270             {
1271               if ((!xmlStrcmp(cur->name, (const xmlChar *)"boolean")))
1272                 {
1273                   //wait a boolean, got a boolean
1274                   xmlChar * s = NULL;
1275                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1276                   bool ob =false;
1277                   if (s)
1278                     {
1279                       DEBTRACE( "convertToYacsBool " << (const char *)s );
1280                       ob=atoi((const char*)s)!=0;
1281                       xmlFree(s);
1282                     }
1283                   else
1284                     {
1285                       DEBTRACE("############### workaround to improve...");
1286                     }
1287                   return ob;
1288                 }
1289               cur = cur->next;
1290             }
1291           stringstream msg;
1292           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1293           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1294           throw YACS::ENGINE::ConversionException(msg.str());
1295         }
1296     };
1297     template <ImplType IMPLOUT, class TOUT>
1298     struct convertToYacsObjref<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1299     {
1300       static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,int protocol)
1301         {
1302           cur = cur->xmlChildrenNode;
1303           while (cur != NULL)
1304             {
1305               if ((!xmlStrcmp(cur->name, (const xmlChar *)"objref")))
1306                 {
1307                   //we wait a objref, we have got a objref
1308                   xmlChar * s = NULL;
1309                   std::string mystr = "";
1310                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1311                   if (s)
1312                     {
1313                       DEBTRACE( "convertToYacsObjref " << (const char *)s );
1314                       mystr = (const char *)s;
1315                       xmlFree(s);
1316                     }
1317                   else
1318                     {
1319                       DEBTRACE("############### workaround to improve...");
1320                     }
1321                   if(strncmp(t->id(),"python",6)==0 )
1322                     return FromBase64Safe(mystr);
1323                   else
1324                     return mystr;
1325                 }
1326               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
1327                 {
1328                   //wait a string, got a string
1329                   xmlChar * s = NULL;
1330                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1331                   if(s==0)return "";
1332                   DEBTRACE( "convertToYacsString " << (const char *)s );
1333                   std::string mystr=std::string((const char *)s);
1334                   xmlFree(s);
1335                   return mystr;
1336                 }
1337               cur = cur->next;
1338             }
1339           stringstream msg;
1340           msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
1341           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1342           throw YACS::ENGINE::ConversionException(msg.str());
1343         }
1344     };
1345     template <ImplType IMPLOUT, class TOUT>
1346     struct convertToYacsSequence<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1347     {
1348       static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::vector<TOUT>& v)
1349         {
1350           cur = cur->xmlChildrenNode;
1351           while (cur != NULL)
1352             {
1353               if ((!xmlStrcmp(cur->name, (const xmlChar *)"array")))
1354                 {
1355                   DEBTRACE( "parse sequence " );
1356                   xmlNodePtr cur1=cur->xmlChildrenNode;
1357                   while (cur1 != NULL)
1358                     {
1359                       if ((!xmlStrcmp(cur1->name, (const xmlChar *)"data")))
1360                         {
1361                           DEBTRACE( "parse data " );
1362                           xmlNodePtr cur2=cur1->xmlChildrenNode;
1363                           while (cur2 != NULL)
1364                             {
1365                               //collect all values
1366                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1367                                 {
1368                                   TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(t->contentType(),doc,cur2);
1369                                   v.push_back(ro);
1370                                 }
1371                               cur2 = cur2->next;
1372                             } // end while value
1373                           break;
1374                         }
1375                       cur1 = cur1->next;
1376                     } // end while data
1377                   break;
1378                 }
1379               cur = cur->next;
1380             } // end while array
1381         }
1382     };
1383     template <ImplType IMPLOUT, class TOUT>
1384     struct convertToYacsStruct<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1385     {
1386       static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::map<std::string,TOUT>& m)
1387         {
1388           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1389           int nMember=tst->memberCount();
1390           DEBTRACE("nMember="<<nMember);
1391           std::map<std::string,TypeCode*> mtc;
1392           for(int i=0;i<nMember;i++)
1393             {
1394               mtc[tst->memberName(i)]=tst->memberType(i);
1395             }
1396
1397           cur = cur->xmlChildrenNode;
1398           while (cur != NULL)
1399             {
1400               if ((!xmlStrcmp(cur->name, (const xmlChar *)"struct")))
1401                 {
1402                   DEBTRACE( "parse struct " );
1403                   xmlNodePtr cur1=cur->xmlChildrenNode;
1404                   while (cur1 != NULL)
1405                     {
1406                       if ((!xmlStrcmp(cur1->name, (const xmlChar *)"member")))
1407                         {
1408                           DEBTRACE( "parse member " );
1409                           xmlNodePtr cur2=cur1->xmlChildrenNode;
1410                           while (cur2 != NULL)
1411                             {
1412                               //member name
1413                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"name")))
1414                                 {
1415                                   xmlChar * s = NULL;
1416                                   s = xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
1417                                   std::string name= (char *)s;
1418                                   cur2 = cur2->next;
1419                                   while (cur2 != NULL)
1420                                     {
1421                                       if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1422                                         {
1423                                           TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(mtc[name],doc,cur2);
1424                                           m[name]=ro;
1425                                           break;
1426                                         }
1427                                       cur2 = cur2->next;
1428                                     }
1429                                   xmlFree(s);
1430                                   break;
1431                                 }
1432                               cur2 = cur2->next;
1433                             } // end while member/value
1434                         }
1435                       cur1 = cur1->next;
1436                     } // end while member
1437                   break;
1438                 }
1439               cur = cur->next;
1440             } // end while struct
1441         }
1442     };
1443     /* End of ToYacs Convertor for XMLImpl */
1444
1445     //! FromYacs Convertor for XMLImpl
1446     /*!
1447      * Convert YACS<std::string> intermediate types to std::string types (XMLImpl)
1448      */
1449     template <>
1450     struct convertFromYacsDouble<XMLImpl,std::string>
1451     {
1452       static inline std::string convert(const TypeCode *t,double o)
1453         {
1454           stringstream msg ;
1455           msg << "<value><double>" << setprecision(16) << o << "</double></value>\n";
1456           return msg.str();
1457         }
1458     };
1459     template <>
1460     struct convertFromYacsInt<XMLImpl,std::string>
1461     {
1462       static inline std::string convert(const TypeCode *t,long o)
1463         {
1464           stringstream msg ;
1465           msg << "<value><int>" << o << "</int></value>\n";
1466           return msg.str();
1467         }
1468     };
1469     template <>
1470     struct convertFromYacsString<XMLImpl,std::string>
1471     {
1472       static inline std::string convert(const TypeCode *t,std::string& o)
1473         {
1474           std::string msg="<value><string>";
1475           return msg+o+"</string></value>\n";
1476         }
1477     };
1478     template <>
1479     struct convertFromYacsBool<XMLImpl,std::string>
1480     {
1481       static inline std::string convert(const TypeCode *t,bool o)
1482         {
1483           stringstream msg ;
1484           msg << "<value><boolean>" << o << "</boolean></value>\n";
1485           return msg.str();
1486         }
1487     };
1488     template <>
1489     struct convertFromYacsObjref<XMLImpl,std::string>
1490     {
1491       static inline std::string convert(const TypeCode *t,std::string& o)
1492         {
1493           if(strncmp(t->id(),"python",6)==0 )
1494             return "<value><objref><![CDATA[" + ToBase64(o) + "]]></objref></value>\n";
1495           else if(strncmp(t->id(),"json",4)==0)
1496             return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
1497           else
1498             return "<value><objref>" + o + "</objref></value>\n";
1499         }
1500     };
1501
1502     template <>
1503     struct convertFromYacsSequence<XMLImpl,std::string>
1504     {
1505       static inline std::string convert(const TypeCode *t,std::vector<std::string>& v)
1506         {
1507           std::vector<std::string>::const_iterator iter;
1508           stringstream xmlob;
1509           xmlob << "<value><array><data>\n";
1510           for(iter=v.begin();iter!=v.end();iter++)
1511             {
1512               xmlob << *iter;
1513             }
1514           xmlob << "</data></array></value>\n";
1515           DEBTRACE("Sequence= " << xmlob);
1516           return xmlob.str();
1517         }
1518     };
1519     template <>
1520     struct convertFromYacsStruct<XMLImpl,std::string>
1521     {
1522       static inline std::string convert(const TypeCode *t,std::map<std::string,std::string>& m)
1523         {
1524           std::string result="<value><struct>\n";
1525           std::map<std::string, std::string>::const_iterator pt;
1526           for(pt=m.begin();pt!=m.end();pt++)
1527             {
1528               std::string name=(*pt).first;
1529               std::string item=(*pt).second;
1530               result=result+"<member>\n";
1531               result=result+"<name>"+name+"</name>\n";
1532               result=result+item;
1533               result=result+"</member>\n";
1534             }
1535           result=result+"</struct></value>\n";
1536           return result;
1537         }
1538     };
1539
1540     /* End of FromYacs Convertor for XMLImpl */
1541
1542     //! ToYacs Convertor for NEUTRALImpl
1543     /*!
1544      * This convertor converts Neutral objects to intermediate YACS<TOUT> types
1545      * Template : Partial specialization for Neutral implementation with types YACS::ENGINE::Any*
1546      */
1547     template <ImplType IMPLOUT, class TOUT>
1548     struct convertToYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1549     {
1550       static inline double convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1551         {
1552           if(o->getType()->kind()==Double)
1553             return o->getDoubleValue();
1554           else if(o->getType()->kind()==Int)
1555             return o->getIntValue();
1556
1557           stringstream msg;
1558           msg << "Problem in conversion: a double or int is expected " ;
1559           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1560           throw YACS::ENGINE::ConversionException(msg.str());
1561         }
1562     };
1563     template <ImplType IMPLOUT, class TOUT>
1564     struct convertToYacsInt<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1565     {
1566       static inline long convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1567         {
1568           if(o->getType()->kind()==Int)
1569             return o->getIntValue();
1570           stringstream msg;
1571           msg << "Problem in conversion: a int is expected " ;
1572           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1573           throw YACS::ENGINE::ConversionException(msg.str());
1574         }
1575     };
1576     template <ImplType IMPLOUT, class TOUT>
1577     struct convertToYacsString<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1578     {
1579       static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1580         {
1581           if(o->getType()->kind()==String)
1582             return o->getStringValue();
1583           stringstream msg;
1584           msg << "Problem in conversion: a string is expected " ;
1585           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1586           throw YACS::ENGINE::ConversionException(msg.str());
1587         }
1588     };
1589     template <ImplType IMPLOUT, class TOUT>
1590     struct convertToYacsBool<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1591     {
1592       static inline bool convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1593         {
1594           if(o->getType()->kind()==Bool)
1595             return o->getBoolValue();
1596           else if(o->getType()->kind()==Int)
1597             return o->getIntValue() != 0;
1598           stringstream msg;
1599           msg << "Problem in conversion: a bool or int is expected " ;
1600           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1601           throw YACS::ENGINE::ConversionException(msg.str());
1602         }
1603     };
1604     template <ImplType IMPLOUT, class TOUT>
1605     struct convertToYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1606     {
1607       static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,int protocol)
1608         {
1609           if(o->getType()->kind()==String || o->getType()->kind()==Objref)
1610             return o->getStringValue();
1611           stringstream msg;
1612           msg << "Problem in conversion: a objref(string) is expected " ;
1613           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1614           throw YACS::ENGINE::ConversionException(msg.str());
1615         }
1616     };
1617     template <ImplType IMPLOUT, class TOUT>
1618     struct convertToYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1619     {
1620       static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::vector<TOUT>& v)
1621         {
1622           SequenceAny* sdata= (SequenceAny*)o;
1623           int length=sdata->size();
1624           v.resize(length);
1625           for(int i=0;i<length;i++)
1626             {
1627               TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(t->contentType(),(*sdata)[i],0);
1628               v[i]=ro;
1629             }
1630         }
1631     };
1632     template <ImplType IMPLOUT, class TOUT>
1633     struct convertToYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1634     {
1635       static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::map<std::string,TOUT>& m)
1636         {
1637           StructAny * sdata = dynamic_cast<StructAny *>(o);
1638           YASSERT(sdata != NULL);
1639           const TypeCodeStruct * tst = dynamic_cast<const TypeCodeStruct *>(t);
1640           YASSERT(tst != NULL);
1641           for (int i=0 ; i<tst->memberCount() ; i++)
1642             {
1643               string name = tst->memberName(i);
1644               TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),(*sdata)[name.c_str()],0);
1645               m[name]=ro;
1646             }
1647         }
1648     };
1649     /* End of ToYacs Convertor for NEUTRALImpl */
1650
1651     //! FromYacs Convertor for NEUTRALImpl
1652     /*!
1653      * Convert YACS<YACS::ENGINE::Any*> intermediate types to YACS::ENGINE::Any* types (NEUTRALImpl)
1654      */
1655     template <>
1656     struct convertFromYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*>
1657     {
1658       static inline YACS::ENGINE::Any* convert(const TypeCode *t,double o)
1659         {
1660           YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(o);
1661           return ob;
1662         }
1663     };
1664     template <>
1665     struct convertFromYacsInt<NEUTRALImpl,YACS::ENGINE::Any*>
1666     {
1667       static inline YACS::ENGINE::Any* convert(const TypeCode *t,long o)
1668         {
1669           return YACS::ENGINE::AtomAny::New((int)o);
1670         }
1671     };
1672     template <>
1673     struct convertFromYacsString<NEUTRALImpl,YACS::ENGINE::Any*>
1674     {
1675       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1676         {
1677           return YACS::ENGINE::AtomAny::New(o);
1678         }
1679     };
1680     template <>
1681     struct convertFromYacsBool<NEUTRALImpl,YACS::ENGINE::Any*>
1682     {
1683       static inline YACS::ENGINE::Any* convert(const TypeCode *t,bool o)
1684         {
1685           return YACS::ENGINE::AtomAny::New(o);
1686         }
1687     };
1688     template <>
1689     struct convertFromYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*>
1690     {
1691       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1692         {
1693           //Check if objref is a GenericObj and register it if it is the case (workaround for bad management of GenericObj)
1694           if(o=="" || (t->isA(Runtime::_tc_file)) || (strncmp(t->id(),"python",6)==0) || (strncmp(t->id(),"json",4)==0))
1695             return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1696
1697           //Objref CORBA. prefix=IOR,corbaname,corbaloc
1698           CORBA::Object_var obref;
1699           try
1700             {
1701               obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1702             }
1703           catch(CORBA::Exception& ex)
1704             {
1705               throw ConversionException("Can't get reference to object");
1706             }
1707           if(obref->_non_existent())
1708             throw ConversionException("non_existent object");
1709           if( CORBA::is_nil(obref) )
1710             throw ConversionException("Can't get reference to object");
1711           if(!obref->_is_a(t->id()))
1712             {
1713               stringstream msg;
1714               msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1715               msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1716               msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1717               throw YACS::ENGINE::ConversionException(msg.str());
1718             }
1719
1720           SALOME::GenericObj_var gobj=SALOME::GenericObj::_narrow(obref);
1721           if(!CORBA::is_nil(gobj))
1722             {
1723               DEBTRACE("It's a SALOME::GenericObj register it");
1724               gobj->Register();
1725             }
1726           else
1727               DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
1728
1729           return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1730         }
1731     };
1732
1733     template <>
1734     struct convertFromYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*>
1735     {
1736       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::vector<YACS::ENGINE::Any*>& v)
1737         {
1738           std::vector<YACS::ENGINE::Any*>::const_iterator iter;
1739           //Objref are managed as string within YACS::ENGINE::Any objs
1740           SequenceAny* any;
1741           any=SequenceAny::New(t->contentType());
1742           for(iter=v.begin();iter!=v.end();iter++)
1743             {
1744               any->pushBack(*iter);
1745               (*iter)->decrRef();
1746             }
1747           DEBTRACE( "refcnt: " << any->getRefCnt() );
1748           return any;
1749         }
1750     };
1751
1752     template <>
1753     struct convertFromYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*>
1754     {
1755       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::map<std::string,YACS::ENGINE::Any*>& m)
1756         {
1757           StructAny * any = StructAny::New((TypeCodeStruct *)t);
1758           std::map<std::string,YACS::ENGINE::Any*>::const_iterator it;
1759           for (it=m.begin() ; it!=m.end() ; it++)
1760             {
1761               any->setEltAtRank(it->first.c_str(), it->second);
1762               it->second->decrRef();
1763             }
1764           return any;
1765         }
1766     };
1767     /* End of FromYacs Convertor for NEUTRALImpl */
1768
1769     //! ToYacs Convertor for CORBAImpl
1770     /*!
1771      * This convertor converts Corba objects to intermediate YACS<TOUT> types
1772      * Template : Partial specialization for CORBA implementation with types CORBA::Any*
1773      */
1774     template <ImplType IMPLOUT, class TOUT>
1775     struct convertToYacsDouble<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1776     {
1777       static inline double convert(const TypeCode *t,CORBA::Any* o,void*)
1778         {
1779           CORBA::TypeCode_var tc = o->type();
1780           if (tc->equivalent(CORBA::_tc_double))
1781             {
1782               CORBA::Double d;
1783               *o >>= d;
1784               return d;
1785             }
1786           if (tc->equivalent(CORBA::_tc_long))
1787             {
1788               CORBA::Long d;
1789               *o >>= d;
1790               return d;
1791             }
1792           stringstream msg;
1793           msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1794           msg << " : " << __FILE__ << ":" << __LINE__;
1795           throw YACS::ENGINE::ConversionException(msg.str());
1796         }
1797     };
1798     template <ImplType IMPLOUT, class TOUT>
1799     struct convertToYacsInt<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1800     {
1801       static inline long convert(const TypeCode *t,CORBA::Any* o,void*)
1802         {
1803           CORBA::Long d;
1804           if(*o >>= d)
1805             return d;
1806           stringstream msg;
1807           msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1808           msg << " : " << __FILE__ << ":" << __LINE__;
1809           throw YACS::ENGINE::ConversionException(msg.str());
1810         }
1811     };
1812     template <ImplType IMPLOUT, class TOUT>
1813     struct convertToYacsString<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1814     {
1815       static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*)
1816         {
1817           const char *s;
1818           if(*o >>=s)
1819             return s;
1820           stringstream msg;
1821           msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1822           msg << " : " << __FILE__ << ":" << __LINE__;
1823           throw YACS::ENGINE::ConversionException(msg.str());
1824         }
1825     };
1826     template <ImplType IMPLOUT, class TOUT>
1827     struct convertToYacsBool<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1828     {
1829       static inline bool convert(const TypeCode *t,CORBA::Any* o,void*)
1830         {
1831           CORBA::Boolean b;
1832           if(*o >>= CORBA::Any::to_boolean(b))
1833             return b;
1834           stringstream msg;
1835           msg << "Problem in Corba to TOUT conversion: kind= " << t->kind() ;
1836           msg << " : " << __FILE__ << ":" << __LINE__;
1837           throw YACS::ENGINE::ConversionException(msg.str());
1838         }
1839     };
1840     template <ImplType IMPLOUT, class TOUT>
1841     struct convertToYacsObjref<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1842     {
1843       static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*,int protocol)
1844         {
1845           char file[]="/tmp/XXXXXX";
1846           if(t->isA(Runtime::_tc_file))
1847             {
1848               Engines::Salome_file_ptr sf;
1849               *o >>= sf;
1850               Salome_file_i* f=new Salome_file_i();
1851               mkstemp(file);
1852               f->setDistributedFile(file);
1853               f->connect(sf);
1854               f->recvFiles();
1855               delete f;
1856               return file;
1857             }
1858           else if(strncmp(t->id(),"python",6)==0)
1859             {
1860               const char *s;
1861               Engines::fileBlock * buffer;
1862               if(*o >>=buffer)
1863                 {
1864                   s=(const char*)buffer->get_buffer();
1865
1866                   if(protocol !=4)
1867                     {
1868                       std::string mystr(s,buffer->length());
1869                       return mystr;
1870                     }
1871
1872                   PyGILState_STATE gstate = PyGILState_Ensure(); 
1873                   PyObject* mod=PyImport_ImportModule("pickle");
1874                   PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",s,buffer->length());
1875                   PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",ob,protocol);
1876                   DEBTRACE(PyObject_Repr(pickled));
1877                   std::string mystr=PyBytes_AsString(pickled);
1878                   Py_DECREF(mod);
1879                   Py_DECREF(ob);
1880                   Py_DECREF(pickled);
1881                   PyGILState_Release(gstate);
1882
1883                   return mystr;
1884                 }
1885               stringstream msg;
1886               msg << "Problem in CORBA (protocol python) to TOUT conversion: kind= " << t->kind() ;
1887               msg << " : " << __FILE__ << ":" << __LINE__;
1888               throw YACS::ENGINE::ConversionException(msg.str());
1889             }
1890           else if(strncmp(t->id(),"json",4)==0)
1891             {
1892               const char *s;
1893               if(*o >>=s)
1894                 {
1895                   return s;
1896                 }
1897               stringstream msg;
1898               msg << "Problem in CORBA (protocol json) to TOUT conversion: kind= " << t->kind() ;
1899               msg << " : " << __FILE__ << ":" << __LINE__;
1900               throw YACS::ENGINE::ConversionException(msg.str());
1901             }
1902           else
1903             {
1904               CORBA::Object_var ObjRef ;
1905               *o >>= CORBA::Any::to_object(ObjRef) ;
1906               CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef);
1907               return (char *)objref;
1908             }
1909         }
1910     };
1911     template <ImplType IMPLOUT, class TOUT>
1912     struct convertToYacsSequence<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1913     {
1914       static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::vector<TOUT>& v)
1915         {
1916           CORBA::TypeCode_var tc=o->type();
1917           if (tc->kind() != CORBA::tk_sequence)
1918             {
1919               stringstream msg;
1920               msg << "Not a sequence corba type " << tc->kind();
1921               msg << " : " << __FILE__ << ":" << __LINE__;
1922               throw YACS::ENGINE::ConversionException(msg.str());
1923             }
1924           DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1925           DynamicAny::DynSequence_ptr ds=DynamicAny::DynSequence::_narrow(dynany);
1926           CORBA::release(dynany);
1927           DynamicAny::AnySeq_var as=ds->get_elements();
1928           int len=as->length();
1929           v.resize(len);
1930           for(int i=0;i<len;i++)
1931             {
1932 #ifdef REFCNT
1933               DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1934 #endif
1935               TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(t->contentType(),&as[i],0);
1936               v[i]=ro;
1937             }
1938           ds->destroy();
1939           CORBA::release(ds);
1940           for(int i=0;i<len;i++)
1941             {
1942 #ifdef REFCNT
1943               DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1944 #endif
1945             }
1946         }
1947     };
1948     template <ImplType IMPLOUT, class TOUT>
1949     struct convertToYacsStruct<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1950     {
1951       static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::map<std::string,TOUT>& m)
1952         {
1953           CORBA::TypeCode_var tc=o->type();
1954           DEBTRACE(tc->kind());
1955           if (tc->kind() != CORBA::tk_struct)
1956             {
1957               stringstream msg;
1958               msg << "Not a struct corba type " << tc->kind();
1959               msg << " : " << __FILE__ << ":" << __LINE__;
1960               throw YACS::ENGINE::ConversionException(msg.str());
1961             }
1962           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1963           DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1964           DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(dynany);
1965           CORBA::release(dynany);
1966           DynamicAny::NameValuePairSeq_var as=ds->get_members();
1967           int len=as->length();
1968           for(int i=0;i<len;i++)
1969             {
1970               std::string name=as[i].id.in();
1971               DEBTRACE(name);
1972               CORBA::Any value=as[i].value;
1973 #ifdef REFCNT
1974               DEBTRACE("refcount CORBA value: " << ((omni::TypeCode_base*)value.pd_tc.in())->pd_ref_count);
1975 #endif
1976               TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),&value,0);
1977               m[name]=ro;
1978             }
1979           ds->destroy();
1980           CORBA::release(ds);
1981         }
1982     };
1983     /* End of ToYacs Convertor for CORBAImpl */
1984
1985     //! FromYacs Convertor for CORBAImpl
1986     /*!
1987      * Convert YACS<CORBA::Any*> intermediate types to CORBA::Any* types (CORBAImpl)
1988      */
1989     template <>
1990     struct convertFromYacsDouble<CORBAImpl,CORBA::Any*>
1991     {
1992       static inline CORBA::Any* convert(const TypeCode *t,double o)
1993         {
1994           CORBA::Any *any = new CORBA::Any();
1995           *any <<= (CORBA::Double)o;
1996           return any;
1997         }
1998     };
1999     template <>
2000     struct convertFromYacsInt<CORBAImpl,CORBA::Any*>
2001     {
2002       static inline CORBA::Any* convert(const TypeCode *t,long o)
2003         {
2004           CORBA::Any *any = new CORBA::Any();
2005           *any <<= (CORBA::Long)o;
2006           return any;
2007         }
2008     };
2009     template <>
2010     struct convertFromYacsString<CORBAImpl,CORBA::Any*>
2011     {
2012       static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2013         {
2014           CORBA::Any *any = new CORBA::Any();
2015           *any <<= o.c_str();
2016           return any;
2017         }
2018     };
2019     template <>
2020     struct convertFromYacsBool<CORBAImpl,CORBA::Any*>
2021     {
2022       static inline CORBA::Any* convert(const TypeCode *t,bool o)
2023         {
2024           CORBA::Any *any = new CORBA::Any();
2025           *any <<= CORBA::Any::from_boolean(o);
2026           return any;
2027         }
2028     };
2029     template <>
2030     struct convertFromYacsObjref<CORBAImpl,CORBA::Any*>
2031     {
2032       static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2033         {
2034           CORBA::Object_var obref;
2035
2036           if(t->isA(Runtime::_tc_file))
2037             {
2038               //It's an objref file. Convert it specially
2039               Salome_file_i* aSalome_file = new Salome_file_i();
2040               try
2041                 {
2042                   aSalome_file->setLocalFile(o.c_str());
2043                   obref = aSalome_file->_this();
2044                   aSalome_file->_remove_ref();
2045                 }
2046               catch (const SALOME::SALOME_Exception& e)
2047                 {
2048                   stringstream msg;
2049                   msg << e.details.text;
2050                   msg << " : " << __FILE__ << ":" << __LINE__;
2051                   throw YACS::ENGINE::ConversionException(msg.str());
2052                 }
2053             }
2054           else if(strncmp(t->id(),"python",6)==0 )
2055             {
2056               CORBA::Any *any = new CORBA::Any();
2057               Engines::fileBlock * buffer=new Engines::fileBlock();
2058               buffer->length(o.length());
2059               CORBA::Octet *buf=buffer->get_buffer();
2060               memcpy(buf,o.c_str(),o.length());
2061               *any <<= buffer;
2062               return any;
2063             }
2064           else if(strncmp(t->id(),"json",4)==0)
2065             {
2066               CORBA::Any *any = new CORBA::Any();
2067               *any <<= o.c_str();
2068               return any;
2069             }
2070           else
2071             {
2072               try
2073                 {
2074                   obref=getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
2075                 }
2076               catch(CORBA::Exception& ex)
2077                 {
2078                   throw ConversionException("Can't get reference to object");
2079                 }
2080               if( CORBA::is_nil(obref) )
2081                 {
2082                   throw ConversionException("Can't get reference to object");
2083                 }
2084             }
2085 #ifdef REFCNT
2086           DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2087 #endif
2088           CORBA::Any *any = new CORBA::Any();
2089           *any <<= obref;
2090 #ifdef REFCNT
2091           DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2092 #endif
2093           return any;
2094         }
2095     };
2096
2097     template <>
2098     struct convertFromYacsSequence<CORBAImpl,CORBA::Any*>
2099     {
2100       static inline CORBA::Any* convert(const TypeCode *t,std::vector<CORBA::Any*>& v)
2101         {
2102           CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2103           std::vector<CORBA::Any*>::const_iterator iter;
2104
2105           // Build an Any from vector v
2106           int isObjref=0;
2107           if(t->contentType()->kind() == Objref)
2108             isObjref=1;
2109
2110           CORBA::TypeCode_var tc=getCorbaTC(t);
2111
2112           DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2113           DynamicAny::DynSequence_var ds = DynamicAny::DynSequence::_narrow(dynany);
2114           ds->set_length(v.size());
2115
2116           for(iter=v.begin();iter!=v.end();iter++)
2117             {
2118               DynamicAny::DynAny_var temp=ds->current_component();
2119               CORBA::Any* a=*iter;
2120               //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2121               if(isObjref)
2122                 {
2123                   CORBA::Object_var zzobj ;
2124                   *a >>= CORBA::Any::to_object(zzobj) ;
2125                   temp->insert_reference(zzobj);
2126                 }
2127               else
2128                 temp->from_any(*a);
2129
2130               //delete intermediate any
2131               delete a;
2132               ds->next();
2133             }
2134
2135           CORBA::Any *any=ds->to_any();
2136           ds->destroy();
2137           return any;
2138         }
2139     };
2140     template <>
2141     struct convertFromYacsStruct<CORBAImpl,CORBA::Any*>
2142     {
2143       static inline CORBA::Any* convert(const TypeCode *t,std::map<std::string,CORBA::Any*>& m)
2144         {
2145           CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2146
2147           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2148           int nMember=tst->memberCount();
2149           DEBTRACE("nMember="<<nMember);
2150
2151           CORBA::TypeCode_var tc=getCorbaTC(t);
2152           DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2153           DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(dynany);
2154
2155           for(int i=0;i<nMember;i++)
2156             {
2157               DynamicAny::DynAny_var temp=ds->current_component();
2158               const char * name=tst->memberName(i);
2159               DEBTRACE("Member name="<<name);
2160               //do not test member presence : test has been done in ToYacs convertor
2161               CORBA::Any* a=m[name];
2162               //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2163               CORBA::TypeCode_var atc = tc->member_type(i);
2164               if(atc->kind()==CORBA::tk_objref)
2165                 {
2166                   //special treatment for objref
2167                   CORBA::Object_var zzobj ;
2168                   *a >>= CORBA::Any::to_object(zzobj) ;
2169                   temp->insert_reference(zzobj);
2170                 }
2171               else
2172                 {
2173                   temp->from_any(*a);
2174                 }
2175               //delete intermediate any
2176               delete a;
2177               ds->next();
2178             }
2179           CORBA::Any *any=ds->to_any();
2180           ds->destroy();
2181
2182           return any;
2183         }
2184     };
2185     /* End of FromYacs Convertor for CORBAImpl */
2186
2187     /* Some shortcuts for CORBA to CORBA conversion */
2188     template <>
2189     inline CORBA::Any* convertDouble<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2190     {
2191       CORBA::TypeCode_var tc = o->type();
2192       if (tc->equivalent(CORBA::_tc_double))
2193         {
2194           return o;
2195         }
2196       if (tc->equivalent(CORBA::_tc_long))
2197         {
2198           CORBA::Long d;
2199           *o >>= d;
2200           CORBA::Any *any = new CORBA::Any();
2201           *any <<= (CORBA::Double)d;
2202           return any;
2203         }
2204       stringstream msg;
2205       msg << "Not a double or long corba type " << tc->kind();
2206       msg << " : " << __FILE__ << ":" << __LINE__;
2207       throw YACS::ENGINE::ConversionException(msg.str());
2208     }
2209     template <>
2210     inline CORBA::Any* convertInt<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2211     {
2212       return o;
2213     }
2214     template <>
2215     inline CORBA::Any* convertString<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2216     {
2217       return o;
2218     }
2219     template <>
2220     inline CORBA::Any* convertBool<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2221     {
2222       return o;
2223     }
2224     template <>
2225     inline CORBA::Any* convertObjref<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2226     {
2227       return o;
2228     }
2229     template <>
2230     inline CORBA::Any* convertStruct<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2231     {
2232       return o;
2233     }
2234     /* End of shortcuts for CORBA to CORBA conversion */
2235
2236     //! ToYacs Convertor for CPPImpl
2237     /*!
2238      * This convertor converts Python object to YACS<TOUT> types
2239      * Partial specialization for Python implementation with type PyObject* (PYTHONImpl)
2240      */
2241     template <ImplType IMPLOUT, class TOUT>
2242     struct convertToYacsDouble<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2243     {
2244       static inline double convert(const TypeCode *t,void* o,const TypeCode* intype)
2245         {
2246           if(intype->kind()==YACS::ENGINE::Double)
2247             {
2248               return *(double*)o;
2249             }
2250           else if(intype->kind()==YACS::ENGINE::Int)
2251             {
2252               return *(long*)o;
2253             }
2254           stringstream msg;
2255           msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2256           msg << " : " << __FILE__ << ":" << __LINE__;
2257           throw YACS::ENGINE::ConversionException(msg.str());
2258         }
2259     };
2260     template <ImplType IMPLOUT, class TOUT>
2261     struct convertToYacsInt<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2262     {
2263       static inline long convert(const TypeCode *t,void* o,const TypeCode* intype)
2264         {
2265           if(intype->kind()==YACS::ENGINE::Int)
2266             {
2267               return *(long*)o;
2268             }
2269           stringstream msg;
2270           msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2271           msg << " : " << __FILE__ << ":" << __LINE__;
2272           throw YACS::ENGINE::ConversionException(msg.str());
2273         }
2274     };
2275     /* End of ToYacs Convertor for CPPImpl */
2276
2277     //Python conversions
2278     std::string convertPyObjectXml(const TypeCode *t,PyObject *data)
2279       {
2280         return YacsConvertor<PYTHONImpl,PyObject*,void*,XMLImpl,std::string>(t,data,0);
2281       }
2282     YACS::ENGINE::Any* convertPyObjectNeutral(const TypeCode *t,PyObject *data)
2283       {
2284         return YacsConvertor<PYTHONImpl,PyObject*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2285       }
2286     CORBA::Any* convertPyObjectCorba(const TypeCode *t,PyObject *data)
2287       {
2288         return YacsConvertor<PYTHONImpl,PyObject*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2289       }
2290     PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *data)
2291       {
2292         return YacsConvertor<PYTHONImpl,PyObject*,void*,PYTHONImpl,PyObject*>(t,data,0);
2293       }
2294
2295     std::string convertPyObjectToString(PyObject* ob)
2296     {
2297       PyObject *s;
2298       PyGILState_STATE gstate = PyGILState_Ensure(); 
2299       // TODO: separate treatment for string (maybe with bad encoding?) and other types of PyObject ?
2300       // Do we need str() or repr() and what are the possible causes of failure of str() ?
2301       // not clear, needs more analysis.
2302       s=PyObject_Str(ob);
2303       if (s == NULL) // for instance string with bad encoding, non utf-8
2304       {
2305         s=PyObject_ASCII(ob); // escape non ASCII characters and like repr(), which is not the same as str()...
2306       }
2307       Py_ssize_t size;
2308       const char* characters =  PyUnicode_AsUTF8AndSize(s, &size);
2309       std::string ss( characters, size);
2310       Py_DECREF(s);
2311       PyGILState_Release(gstate);
2312       return ss;
2313     }
2314
2315     //XML conversions
2316     PyObject* convertXmlPyObject(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2317       {
2318         return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,PYTHONImpl,PyObject*>(t,doc,cur);
2319       }
2320     YACS::ENGINE::Any* convertXmlNeutral(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2321       {
2322         return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,NEUTRALImpl,YACS::ENGINE::Any*>(t,doc,cur);
2323       }
2324     CORBA::Any* convertXmlCorba(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2325       {
2326         return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,CORBAImpl,CORBA::Any*>(t,doc,cur);
2327       }
2328     PyObject* convertXmlStrPyObject(const TypeCode *t,std::string data)
2329       {
2330         xmlDocPtr doc;
2331         xmlNodePtr cur;
2332         PyObject *ob=NULL;
2333         doc = xmlParseMemory(data.c_str(), strlen(data.c_str()));
2334         if (doc == NULL )
2335         {
2336           std::stringstream msg;
2337           msg << "Problem in conversion: XML Document not parsed successfully ";
2338           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2339           throw YACS::ENGINE::ConversionException(msg.str());
2340         }
2341         cur = xmlDocGetRootElement(doc);
2342         if (cur == NULL)
2343         {
2344           xmlFreeDoc(doc);
2345           std::stringstream msg;
2346           msg << "Problem in conversion: empty XML Document";
2347           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2348           throw YACS::ENGINE::ConversionException(msg.str());
2349         }
2350         while (cur != NULL)
2351         {
2352           if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
2353           {
2354             ob=convertXmlPyObject(t,doc,cur);
2355             break;
2356           }
2357           cur = cur->next;
2358         }
2359         xmlFreeDoc(doc);
2360         if(ob==NULL)
2361         {
2362           std::stringstream msg;
2363           msg << "Problem in conversion: incorrect XML value";
2364           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2365           throw YACS::ENGINE::ConversionException(msg.str());
2366         }
2367         return ob;
2368       }
2369     //NEUTRAL conversions
2370     PyObject* convertNeutralPyObject(const TypeCode *t,YACS::ENGINE::Any* data)
2371       {
2372         return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2373       }
2374     std::string convertNeutralXml(const TypeCode *t,YACS::ENGINE::Any* data)
2375       {
2376         return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,XMLImpl,std::string>(t,data,0);
2377       }
2378     CORBA::Any* convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any* data)
2379       {
2380         return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2381       }
2382     YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* data)
2383       {
2384         data->incrRef();
2385         return data;
2386       }
2387
2388     //CORBA conversions
2389     PyObject* convertCorbaPyObject(const TypeCode *t,CORBA::Any* data)
2390       {
2391         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2392       }
2393     std::string convertCorbaXml(const TypeCode *t,CORBA::Any* data)
2394       {
2395         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,XMLImpl,std::string>(t,data,0);
2396       }
2397     YACS::ENGINE::Any* convertCorbaNeutral(const TypeCode *t,CORBA::Any* data)
2398       {
2399         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2400       }
2401     CORBA::Any *convertCorbaCorba(const TypeCode *t,CORBA::Any *data)
2402       {
2403         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2404       }
2405
2406     //! Basic template checker from type TIN 
2407     /*!
2408      * This checker does nothing : throws exception
2409      * It must be partially specialize for a specific type (TIN)
2410      */
2411     template <ImplType IMPLIN,class TIN,class TIN2>
2412     static inline bool checkDouble(const TypeCode *t,TIN o,TIN2 aux)
2413         {
2414           stringstream msg;
2415           msg << "Check not implemented for Implementation: " << IMPLIN ;
2416           msg << " : " << __FILE__ << ":" << __LINE__;
2417           throw YACS::ENGINE::ConversionException(msg.str());
2418         }
2419     template <ImplType IMPLIN,class TIN,class TIN2>
2420     static inline bool checkInt(const TypeCode *t,TIN o,TIN2 aux)
2421         {
2422           stringstream msg;
2423           msg << "Check not implemented for Implementation: " << IMPLIN ;
2424           msg << " : " << __FILE__ << ":" << __LINE__;
2425           throw YACS::ENGINE::ConversionException(msg.str());
2426         }
2427     template <ImplType IMPLIN,class TIN,class TIN2>
2428     static inline bool checkBool(const TypeCode *t,TIN o,TIN2 aux)
2429         {
2430           stringstream msg;
2431           msg << "Check not implemented for Implementation: " << IMPLIN ;
2432           msg << " : " << __FILE__ << ":" << __LINE__;
2433           throw YACS::ENGINE::ConversionException(msg.str());
2434         }
2435     template <ImplType IMPLIN,class TIN,class TIN2>
2436     static inline bool checkString(const TypeCode *t,TIN o,TIN2 aux)
2437         {
2438           stringstream msg;
2439           msg << "Check not implemented for Implementation: " << IMPLIN ;
2440           msg << " : " << __FILE__ << ":" << __LINE__;
2441           throw YACS::ENGINE::ConversionException(msg.str());
2442         }
2443     template <ImplType IMPLIN,class TIN,class TIN2>
2444     static inline bool checkObjref(const TypeCode *t,TIN o,TIN2 aux)
2445         {
2446           stringstream msg;
2447           msg << "Check not implemented for Implementation: " << IMPLIN ;
2448           msg << " : " << __FILE__ << ":" << __LINE__;
2449           throw YACS::ENGINE::ConversionException(msg.str());
2450         }
2451     template <ImplType IMPLIN,class TIN,class TIN2>
2452     static inline bool checkSequence(const TypeCode *t,TIN o,TIN2 aux)
2453         {
2454           stringstream msg;
2455           msg << "Check not implemented for Implementation: " << IMPLIN ;
2456           msg << " : " << __FILE__ << ":" << __LINE__;
2457           throw YACS::ENGINE::ConversionException(msg.str());
2458         }
2459     template <ImplType IMPLIN,class TIN,class TIN2>
2460     static inline bool checkStruct(const TypeCode *t,TIN o,TIN2 aux)
2461         {
2462           stringstream msg;
2463           msg << "Check not implemented for Implementation: " << IMPLIN ;
2464           msg << " : " << __FILE__ << ":" << __LINE__;
2465           throw YACS::ENGINE::ConversionException(msg.str());
2466         }
2467     template <ImplType IMPLIN,class TIN,class TIN2>
2468     static inline bool checkArray(const TypeCode *t,TIN o,TIN2 aux)
2469         {
2470           stringstream msg;
2471           msg << "Check not implemented for Implementation: " << IMPLIN ;
2472           msg << " : " << __FILE__ << ":" << __LINE__;
2473           throw YACS::ENGINE::ConversionException(msg.str());
2474         }
2475
2476     template <ImplType IMPLIN,class TIN,class TIN2>
2477     inline bool YacsChecker(const TypeCode *t,TIN o,TIN2 aux)
2478       {
2479          int tk=t->kind();
2480          switch(t->kind())
2481            {
2482            case Double:
2483              return checkDouble<IMPLIN,TIN,TIN2>(t,o,aux);
2484            case Int:
2485              return checkInt<IMPLIN,TIN,TIN2>(t,o,aux);
2486            case String:
2487              return checkString<IMPLIN,TIN,TIN2>(t,o,aux);
2488            case Bool:
2489              return checkBool<IMPLIN,TIN,TIN2>(t,o,aux);
2490            case Objref:
2491              return checkObjref<IMPLIN,TIN,TIN2>(t,o,aux);
2492            case Sequence:
2493              return checkSequence<IMPLIN,TIN,TIN2>(t,o,aux);
2494            case Array:
2495              return checkArray<IMPLIN,TIN,TIN2>(t,o,aux);
2496            case Struct:
2497              return checkStruct<IMPLIN,TIN,TIN2>(t,o,aux);
2498            default:
2499              break;
2500            }
2501          stringstream msg;
2502          msg << "Check not implemented for kind= " << tk ;
2503          msg << " : " << __FILE__ << ":" << __LINE__;
2504          throw YACS::ENGINE::ConversionException(msg.str());
2505       }
2506     template<>
2507     inline bool checkDouble<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2508       {
2509         if (PyFloat_Check(o))
2510           return true;
2511         else if(PyLong_Check(o))
2512           return true;
2513         else
2514           {
2515             stringstream msg;
2516             msg << "Not a python double ";
2517             throw YACS::ENGINE::ConversionException(msg.str());
2518           }
2519       }
2520     template<>
2521     inline bool checkInt<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2522       {
2523           if (PyLong_Check(o))
2524             return true;
2525           else
2526             {
2527               stringstream msg;
2528               msg << "Not a python integer ";
2529               throw YACS::ENGINE::ConversionException(msg.str());
2530             }
2531       }
2532     template<>
2533     inline bool checkBool<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2534       {
2535           if (PyBool_Check(o))
2536               return true;
2537           else if(PyLong_Check(o))
2538               return true;
2539           else
2540             {
2541               stringstream msg;
2542               msg << "Not a python boolean " ;
2543               throw YACS::ENGINE::ConversionException(msg.str());
2544             }
2545
2546       }
2547     template<>
2548     inline bool checkString<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2549       {
2550           if (PyUnicode_Check(o))
2551             return true;
2552           else
2553             {
2554               stringstream msg;
2555               msg << "Not a python string " ;
2556               throw YACS::ENGINE::ConversionException(msg.str());
2557             }
2558       }
2559     template<>
2560     inline bool checkObjref<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2561       {
2562           if (PyUnicode_Check(o))
2563             return true;
2564           if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true)
2565             return true;
2566           else if(strncmp(t->id(),"json",4)==0) // The python object must be json pickable
2567             {
2568                // The python object should be json compliant (to improve)
2569                return true;
2570             }
2571           else
2572             {
2573               // The python object should be a CORBA obj (to improve)
2574                return true;
2575             }
2576       }
2577     template<>
2578     inline bool checkSequence<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2579       {
2580         if(!PySequence_Check(o))
2581           {
2582             stringstream msg;
2583             msg << "python object is not a sequence " ;
2584             throw YACS::ENGINE::ConversionException(msg.str());
2585           }
2586         int length=PySequence_Size(o);
2587         for(int i=0;i<length;i++)
2588           {
2589             PyObject *item=PySequence_ITEM(o,i);
2590             try
2591               {
2592                 YacsChecker<PYTHONImpl,PyObject*,void*>(t->contentType(),item,0);
2593               }
2594             catch(ConversionException& ex)
2595               {
2596                 stringstream msg;
2597                 msg << ex.what() << " for sequence element " << i;
2598                 throw YACS::ENGINE::ConversionException(msg.str(),false);
2599               }
2600             Py_DECREF(item);
2601           }
2602         return true;
2603       }
2604     template<>
2605     inline bool checkStruct<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2606       {
2607         PyObject *value;
2608         if(!PyDict_Check(o))
2609           {
2610             stringstream msg;
2611             msg << "python object is not a dict " ;
2612             throw YACS::ENGINE::ConversionException(msg.str());
2613           }
2614         YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2615         int nMember=tst->memberCount();
2616         for(int i=0;i<nMember;i++)
2617           {
2618             std::string name=tst->memberName(i);
2619             TypeCode* tm=tst->memberType(i);
2620             value=PyDict_GetItemString(o, name.c_str());
2621             if(value==NULL)
2622               {
2623                 stringstream msg;
2624                 msg << "member " << name << " not present " ;
2625                 throw YACS::ENGINE::ConversionException(msg.str());
2626               }
2627             try
2628               {
2629                 YacsChecker<PYTHONImpl,PyObject*,void*>(tm,value,0);
2630               }
2631             catch(ConversionException& ex)
2632               {
2633                 std::string s=" for struct member "+name;
2634                 throw YACS::ENGINE::ConversionException(ex.what()+s,false);
2635               }
2636           }
2637         return true;
2638       }
2639
2640     bool checkPyObject(const TypeCode *t,PyObject* ob)
2641       {
2642         return YacsChecker<PYTHONImpl,PyObject*,void*>(t,ob,0);
2643       }
2644   }
2645 }