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