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