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