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