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