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