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