1 // Copyright (C) 2006-2023 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #define private public
24 #define protected public
25 #include <omniORB4/CORBA.h>
26 #include <omniORB4/internal/typecode.h>
29 #include "TypeConversions.hxx"
30 #include "ConversionException.hxx"
31 #include "RuntimeSALOME.hxx"
32 #include "Salome_file_i.hxx"
33 #include "TypeCode.hxx"
35 #include "SALOME_GenericObj.hh"
45 int mkstemp(char *tmpl)
48 mktemp(tmpl); ret=open(tmpl,O_RDWR|O_BINARY|O_CREAT|O_EXCL|_O_SHORT_LIVED, _S_IREAD|_S_IWRITE);
54 #include "YacsTrace.hxx"
62 std::string getImplName(ImplType impl)
81 * Functions to return a CORBA TypeCode equivalent to a YACS TypeCode
84 typedef CORBA::TypeCode_ptr (*getCorbaTCFn)(const TypeCode *);
86 CORBA::TypeCode_ptr getCorbaTCNull(const TypeCode *t)
89 msg << "Conversion not implemented: kind= " << t->kind();
90 msg << " : " << __FILE__ << ":" << __LINE__;
91 throw YACS::ENGINE::ConversionException(msg.str());
94 CORBA::TypeCode_ptr getCorbaTCDouble(const TypeCode *t)
96 return CORBA::TypeCode::_duplicate(CORBA::_tc_double);
99 CORBA::TypeCode_ptr getCorbaTCInt(const TypeCode *t)
101 return CORBA::TypeCode::_duplicate(CORBA::_tc_long);
104 CORBA::TypeCode_ptr getCorbaTCString(const TypeCode *t)
106 return CORBA::TypeCode::_duplicate(CORBA::_tc_string);
109 CORBA::TypeCode_ptr getCorbaTCBool(const TypeCode *t)
111 return CORBA::TypeCode::_duplicate(CORBA::_tc_boolean);
114 CORBA::TypeCode_ptr getCorbaTCObjref(const TypeCode *t)
116 DEBTRACE( t->name() << " " << t->shortName() << " " << t->id());
117 CORBA::TypeCode_ptr tc;
118 if(strncmp(t->id(),"python",6)==0 )
119 tc= CORBA::TypeCode::_duplicate(Engines::_tc_fileBlock);
120 else if(strncmp(t->id(),"json",4)==0)
121 tc= CORBA::TypeCode::_duplicate(CORBA::_tc_string);
123 tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName());
125 DEBTRACE("refcount CORBA tc Objref: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
130 CORBA::TypeCode_ptr getCorbaTCSequence(const TypeCode *t)
132 CORBA::TypeCode_var content_type=getCorbaTC(t->contentType());
133 CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_sequence_tc(0,content_type);
135 DEBTRACE("refcount CORBA content_type: " << ((omni::TypeCode_base*)content_type.in())->pd_ref_count);
136 DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
141 CORBA::TypeCode_ptr getCorbaTCStruct(const TypeCode *t)
143 CORBA::StructMemberSeq mseq;
144 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
145 int nMember=tst->memberCount();
146 mseq.length(nMember);
147 for(int i=0;i<nMember;i++)
149 const char * name=tst->memberName(i);
150 TypeCode* tm=tst->memberType(i);
151 mseq[i].name=CORBA::string_dup(name);
152 mseq[i].type=getCorbaTC(tm);
154 CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_struct_tc(t->id(),t->shortName(),mseq);
156 DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
161 getCorbaTCFn getCorbaTCFns[]=
174 CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t)
177 return getCorbaTCFns[tk](t);
181 * End of Functions to return a CORBA TypeCode equivalent to a YACS TypeCode
185 * Section that defines functions to check adaptation from one implementation to another
186 * isAdaptable is template function that checks if TypeCode t1 from implementation IMPLIN
187 * can be converted to TypeCode t2 from implementation IMPLOUT
188 * IMPLIN is the implementation of an output port
189 * IMPLOUT is the implementation of an input port
190 * If the check is True, the input port can be adapted to the output port
193 template <ImplType IMPLIN,ImplType IMPLOUT> inline int isAdaptable(const TypeCode *t1,const TypeCode* t2);
195 template <ImplType IMPLIN,ImplType IMPLOUT>
196 struct isAdaptableDouble
198 static inline int apply(const TypeCode *t1,const TypeCode* t2)
200 if(t1->kind() == Double)return 1;
201 if(t1->kind() == Int)return 1;
205 template <ImplType IMPLIN,ImplType IMPLOUT>
206 struct isAdaptableInt
208 static inline int apply(const TypeCode *t1,const TypeCode* t2)
210 if(t1->kind() == Int)return 1;
214 template <ImplType IMPLIN,ImplType IMPLOUT>
215 struct isAdaptableString
217 static inline int apply(const TypeCode *t1,const TypeCode* t2)
219 if(t1->kind() == String)return 1;
223 template <ImplType IMPLIN,ImplType IMPLOUT>
224 struct isAdaptableBool
226 static inline int apply(const TypeCode *t1,const TypeCode* t2)
228 if(t1->kind() == Bool)return 1;
229 if(t1->kind() == Int)return 1;
233 template <ImplType IMPLIN,ImplType IMPLOUT>
234 struct isAdaptableObjref
236 static inline int apply(const TypeCode *t1,const TypeCode* t2)
238 if(t1->kind() == Objref)
240 //The inport type must be more general than outport type
241 if( t1->isA(t2->id()) )
244 else if(t1->kind() == Sequence)
246 const TypeCodeSeq *t1c(dynamic_cast<const TypeCodeSeq *>(t1));
249 const TypeCode *t1cc(t1c->contentType());
252 if(t1cc->kind() == Objref && std::string(t1cc->id())==std::string(t2->id()))
258 template <ImplType IMPLIN,ImplType IMPLOUT>
259 struct isAdaptableSequence
261 static inline int apply(const TypeCode *t1,const TypeCode* t2)
263 if(t1->kind() == Sequence)
265 if(isAdaptable<IMPLIN,IMPLOUT>(t1->contentType(),t2->contentType()))
273 template <ImplType IMPLIN,ImplType IMPLOUT>
274 struct isAdaptableArray
276 static inline int apply(const TypeCode *t1,const TypeCode* t2)
281 template <ImplType IMPLIN,ImplType IMPLOUT>
282 struct isAdaptableStruct
284 static inline int apply(const TypeCode *t1,const TypeCode* t2)
286 if(t1->kind() == Struct)
296 * Function to check adaptation from implementation 1 (IMPLIN,t1) to implementation 2 (IMPLOUT,t2)
297 * t1 is the IMPLIN output port type
298 * t2 is the IMPLOUT input port type
300 template <ImplType IMPLIN,ImplType IMPLOUT>
301 inline int isAdaptable(const TypeCode *t1,const TypeCode* t2)
306 return isAdaptableDouble<IMPLIN,IMPLOUT>::apply(t1,t2);
308 return isAdaptableInt<IMPLIN,IMPLOUT>::apply(t1,t2);
310 return isAdaptableString<IMPLIN,IMPLOUT>::apply(t1,t2);
312 return isAdaptableBool<IMPLIN,IMPLOUT>::apply(t1,t2);
314 return isAdaptableObjref<IMPLIN,IMPLOUT>::apply(t1,t2);
316 return isAdaptableSequence<IMPLIN,IMPLOUT>::apply(t1,t2);
318 return isAdaptableArray<IMPLIN,IMPLOUT>::apply(t1,t2);
320 return isAdaptableStruct<IMPLIN,IMPLOUT>::apply(t1,t2);
327 //xxx to Python adaptations
328 int isAdaptableCorbaPyObject(const TypeCode *t1,const TypeCode *t2)
330 return isAdaptable<PYTHONImpl,CORBAImpl>(t1,t2);
332 int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2)
334 return isAdaptable<PYTHONImpl,NEUTRALImpl>(t1,t2);
336 int isAdaptablePyObjectPyObject(const TypeCode *t1,const TypeCode *t2)
338 return isAdaptable<PYTHONImpl,PYTHONImpl>(t1,t2);
341 //xxx to Neutral adaptations
342 int isAdaptableCorbaNeutral(const TypeCode *t1,const TypeCode *t2)
344 return isAdaptable<NEUTRALImpl,CORBAImpl>(t1,t2);
346 int isAdaptablePyObjectNeutral(const TypeCode *t1,const TypeCode *t2)
348 return isAdaptable<NEUTRALImpl,PYTHONImpl>(t1,t2);
350 int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2)
352 return isAdaptable<NEUTRALImpl,XMLImpl>(t1,t2);
354 int isAdaptableNeutralNeutral(const TypeCode *t1, const TypeCode *t2)
356 return isAdaptableNeutralCorba(t1, t2);
359 //xxx to XML adaptations
360 int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2)
362 return isAdaptable<XMLImpl,NEUTRALImpl>(t1,t2);
365 //xxx to Corba adaptations
366 int isAdaptableNeutralCorba(const TypeCode *t1,const TypeCode *t2)
368 return isAdaptable<CORBAImpl,NEUTRALImpl>(t1,t2);
370 int isAdaptableXmlCorba(const TypeCode *t1,const TypeCode *t2)
372 return isAdaptable<CORBAImpl,XMLImpl>(t1,t2);
374 int isAdaptableCorbaCorba(const TypeCode *t1,const TypeCode *t2)
376 return isAdaptable<CORBAImpl,CORBAImpl>(t1,t2);
378 int isAdaptablePyObjectCorba(const TypeCode *t1,const TypeCode *t2)
380 return isAdaptable<CORBAImpl,PYTHONImpl>(t1,t2);
383 //! Basic template convertor from type TIN to Yacs<TOUT> type
385 * This convertor does nothing : throws exception
386 * It must be partially specialize for a specific type (TIN)
388 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
389 struct convertToYacsDouble
391 static inline double convert(const TypeCode *t,TIN o,TIN2 aux)
394 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
395 msg << " : " << __FILE__ << ":" << __LINE__;
396 throw YACS::ENGINE::ConversionException(msg.str());
399 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
400 struct convertToYacsInt
402 static inline long convert(const TypeCode *t,TIN o,TIN2 aux)
405 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
406 msg << " : " << __FILE__ << ":" << __LINE__;
407 throw YACS::ENGINE::ConversionException(msg.str());
410 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
411 struct convertToYacsString
413 static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux)
416 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
417 msg << " : " << __FILE__ << ":" << __LINE__;
418 throw YACS::ENGINE::ConversionException(msg.str());
421 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
422 struct convertToYacsBool
424 static inline bool convert(const TypeCode *t,TIN o,TIN2 aux)
427 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
428 msg << " : " << __FILE__ << ":" << __LINE__;
429 throw YACS::ENGINE::ConversionException(msg.str());
432 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
433 struct convertToYacsObjref
435 static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux,int protocol)
438 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
439 msg << " : " << __FILE__ << ":" << __LINE__;
440 throw YACS::ENGINE::ConversionException(msg.str());
443 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
444 struct convertToYacsSequence
446 static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector<TOUT>& v)
449 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
450 msg << " : " << __FILE__ << ":" << __LINE__;
451 throw YACS::ENGINE::ConversionException(msg.str());
454 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
455 struct convertToYacsArray
457 static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector<TOUT>& v)
460 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
461 msg << " : " << __FILE__ << ":" << __LINE__;
462 throw YACS::ENGINE::ConversionException(msg.str());
465 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
466 struct convertToYacsStruct
468 static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::map<std::string,TOUT>& v)
471 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
472 msg << " : " << __FILE__ << ":" << __LINE__;
473 throw YACS::ENGINE::ConversionException(msg.str());
477 //! Basic convertor from Yacs<TOUT> type to full TOUT type
481 template <ImplType IMPLOUT, class TOUT>
482 struct convertFromYacsDouble
484 static inline TOUT convert(const TypeCode *t,double o)
487 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
488 msg << " : " << __FILE__ << ":" << __LINE__;
489 throw YACS::ENGINE::ConversionException(msg.str());
492 template <ImplType IMPLOUT, class TOUT>
493 struct convertFromYacsInt
495 static inline TOUT convert(const TypeCode *t,long o)
498 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
499 msg << " : " << __FILE__ << ":" << __LINE__;
500 throw YACS::ENGINE::ConversionException(msg.str());
503 template <ImplType IMPLOUT, class TOUT>
504 struct convertFromYacsString
506 static inline TOUT convert(const TypeCode *t,std::string o)
509 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
510 msg << " : " << __FILE__ << ":" << __LINE__;
511 throw YACS::ENGINE::ConversionException(msg.str());
514 template <ImplType IMPLOUT, class TOUT>
515 struct convertFromYacsBool
517 static inline TOUT convert(const TypeCode *t,bool o)
520 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
521 msg << " : " << __FILE__ << ":" << __LINE__;
522 throw YACS::ENGINE::ConversionException(msg.str());
525 template <ImplType IMPLOUT, class TOUT>
526 struct convertFromYacsObjref
528 static inline TOUT convert(const TypeCode *t,std::string o)
531 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
532 msg << " : " << __FILE__ << ":" << __LINE__;
533 throw YACS::ENGINE::ConversionException(msg.str());
536 template <ImplType IMPLOUT, class TOUT>
537 struct convertFromYacsSequence
539 static inline TOUT convert(const TypeCode *t,std::vector<TOUT>& v)
542 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
543 msg << " : " << __FILE__ << ":" << __LINE__;
544 throw YACS::ENGINE::ConversionException(msg.str());
547 template <ImplType IMPLOUT, class TOUT>
548 struct convertFromYacsArray
550 static inline TOUT convert(const TypeCode *t,std::vector<TOUT>& v)
553 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
554 msg << " : " << __FILE__ << ":" << __LINE__;
555 throw YACS::ENGINE::ConversionException(msg.str());
558 template <ImplType IMPLOUT, class TOUT>
559 struct convertFromYacsStruct
561 static inline TOUT convert(const TypeCode *t,std::map<std::string,TOUT>& v)
564 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
565 msg << " : " << __FILE__ << ":" << __LINE__;
566 throw YACS::ENGINE::ConversionException(msg.str());
569 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
570 inline TOUT convertDouble(const TypeCode *t,TIN o,TIN2 aux)
572 double d=convertToYacsDouble<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
574 TOUT r=convertFromYacsDouble<IMPLOUT,TOUT>::convert(t,d);
577 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
578 inline TOUT convertInt(const TypeCode *t,TIN o,TIN2 aux)
580 long d=convertToYacsInt<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
582 TOUT r=convertFromYacsInt<IMPLOUT,TOUT>::convert(t,d);
585 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
586 inline TOUT convertString(const TypeCode *t,TIN o,TIN2 aux)
588 std::string d=convertToYacsString<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
590 TOUT r=convertFromYacsString<IMPLOUT,TOUT>::convert(t,d);
593 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
594 inline TOUT convertBool(const TypeCode *t,TIN o,TIN2 aux)
596 double d=convertToYacsBool<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
598 TOUT r=convertFromYacsBool<IMPLOUT,TOUT>::convert(t,d);
601 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
602 inline TOUT convertObjref(const TypeCode *t,TIN o,TIN2 aux)
606 protocol=0;//to avoid presence of \0 into XML generated file
607 if(IMPLOUT==NEUTRALImpl)
609 std::string d=convertToYacsObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,protocol);
611 TOUT r=convertFromYacsObjref<IMPLOUT,TOUT>::convert(t,d);
615 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
616 inline TOUT convertSequence(const TypeCode *t,TIN o,TIN2 aux)
619 convertToYacsSequence<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
620 TOUT r=convertFromYacsSequence<IMPLOUT,TOUT>::convert(t,v);
623 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
624 inline TOUT convertArray(const TypeCode *t,TIN o,TIN2 aux)
627 convertToYacsArray<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
628 TOUT r=convertFromYacsArray<IMPLOUT,TOUT>::convert(t,v);
631 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
632 inline TOUT convertStruct(const TypeCode *t,TIN o,TIN2 aux)
634 std::map<std::string,TOUT> v;
635 convertToYacsStruct<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
636 TOUT r=convertFromYacsStruct<IMPLOUT,TOUT>::convert(t,v);
640 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
641 inline TOUT YacsConvertor(const TypeCode *t,TIN o,TIN2 aux)
647 return convertDouble<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
649 return convertInt<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
651 return convertString<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
653 return convertBool<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
655 return convertObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
657 return convertSequence<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
659 return convertArray<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
661 return convertStruct<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
666 msg << "Conversion not implemented: kind= " << tk << " Implementation: " << IMPLOUT;
667 msg << " : " << __FILE__ << ":" << __LINE__;
668 throw YACS::ENGINE::ConversionException(msg.str());
671 //! ToYacs Convertor for PYTHONImpl
673 * This convertor converts Python object to YACS<TOUT> types
674 * Partial specialization for Python implementation with type PyObject* (PYTHONImpl)
676 template <ImplType IMPLOUT, class TOUT>
677 struct convertToYacsDouble<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
679 static inline double convert(const TypeCode *t,PyObject* o,void*)
682 if (PyFloat_Check(o))
683 x=PyFloat_AS_DOUBLE(o);
684 else if(PyLong_Check(o))
689 msg << "Not a python double. ";
691 msg << "kind=" << t->kind() ;
692 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
694 throw YACS::ENGINE::ConversionException(msg.str());
699 template <ImplType IMPLOUT, class TOUT>
700 struct convertToYacsInt<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
702 static inline long convert(const TypeCode *t,PyObject* o,void*)
710 msg << "Not a python integer. ";
712 msg << "kind=" << t->kind() ;
713 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
715 throw YACS::ENGINE::ConversionException(msg.str());
720 template <ImplType IMPLOUT, class TOUT>
721 struct convertToYacsString<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
723 static inline std::string convert(const TypeCode *t,PyObject* o,void*)
726 if (PyUnicode_Check(o))
729 const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
731 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
737 msg << "Not a python string. ";
739 msg << "kind=" << t->kind() ;
740 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
742 throw YACS::ENGINE::ConversionException(msg.str());
747 template <ImplType IMPLOUT, class TOUT>
748 struct convertToYacsBool<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
750 static inline bool convert(const TypeCode *t,PyObject* o,void*)
755 else if(PyLong_Check(o))
756 l=(PyLong_AsLong(o)!=0);
760 msg << "Not a python boolean. ";
762 msg << "kind=" << t->kind() ;
763 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
765 throw YACS::ENGINE::ConversionException(msg.str());
770 template <ImplType IMPLOUT, class TOUT>
771 struct convertToYacsObjref<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
773 static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol)
775 if (PyUnicode_Check(o) && strncmp(t->id(),"python",6)!=0)
777 // the objref is used by Python as a string (prefix:value) keep it as a string
780 const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
782 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
786 if(strncmp(t->id(),"python",6)==0)
788 // It's a native Python object pickle it
789 PyObject* mod=PyImport_ImportModule("pickle");
790 PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol);
791 DEBTRACE(PyObject_Repr(pickled) );
796 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
798 std::string mystr(PyBytes_AsString(pickled),PyBytes_Size(pickled));
802 else if(strncmp(t->id(),"json",4)==0)
804 // It's a Python object convert it to json
805 PyObject* mod=PyImport_ImportModule("simplejson");
809 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
811 PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"O",o);
816 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
818 std::string mystr=PyBytes_AsString(pickled);
824 // It should be a CORBA Object convert it to an IOR string
825 PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),(char *)"object_to_string",(char *)"O",o);
829 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
833 const char *ptr = PyUnicode_AsUTF8AndSize(pystring, &size);
835 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
836 mystr.assign(ptr, size);
842 template <ImplType IMPLOUT, class TOUT>
843 struct convertToYacsSequence<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
845 static inline void convert(const TypeCode *t,PyObject* o,void*,std::vector<TOUT>& v)
847 if(!PySequence_Check(o))
850 msg << "Problem in conversion: the python object is not a sequence " << std::endl;
852 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
854 throw YACS::ENGINE::ConversionException(msg.str());
856 int length=PySequence_Size(o);
857 DEBTRACE("length: " << length );
859 for(int i=0;i<length;i++)
861 PyObject *item=PySequence_ITEM(o,i);
863 std::cerr <<"item[" << i << "]=";
864 PyObject_Print(item,stderr,Py_PRINT_RAW);
865 std::cerr << std::endl;
867 DEBTRACE( "item refcnt: " << item->ob_refcnt );
870 TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(t->contentType(),item,0);
874 catch(ConversionException& ex)
877 msg << ex.what() << " for sequence element " << i;
878 throw YACS::ENGINE::ConversionException(msg.str(),false);
883 template <ImplType IMPLOUT, class TOUT>
884 struct convertToYacsStruct<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
886 static inline void convert(const TypeCode *t,PyObject* o,void*,std::map<std::string,TOUT>& m)
888 DEBTRACE( "o refcnt: " << o->ob_refcnt );
889 PyObject *key, *value;
890 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
891 int nMember=tst->memberCount();
892 DEBTRACE("nMember="<<nMember);
893 for(int i=0;i<nMember;i++)
895 std::string name=tst->memberName(i);
896 DEBTRACE("Member name="<<name);
897 TypeCode* tm=tst->memberType(i);
898 value=PyDict_GetItemString(o, name.c_str());
901 //member name not present
902 //TODO delete all allocated objects in m
904 PyObject_Print(o,stderr,Py_PRINT_RAW);
905 std::cerr << std::endl;
908 msg << "member " << name << " not present " ;
909 throw YACS::ENGINE::ConversionException(msg.str());
911 DEBTRACE( "value refcnt: " << value->ob_refcnt );
914 TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(tm,value,0);
917 catch(ConversionException& ex)
919 std::string s=" for struct member "+name;
920 throw YACS::ENGINE::ConversionException(ex.what()+s,false);
925 /* End of ToYacs Convertor for PYTHONImpl */
927 //! FromYacs Convertor for PYTHONImpl
929 * Convert YACS<PyObject*> intermediate types to PyObject* types (PYTHONImpl)
932 struct convertFromYacsDouble<PYTHONImpl,PyObject*>
934 static inline PyObject* convert(const TypeCode *t,double o)
936 PyObject *pyob=PyFloat_FromDouble(o);
941 struct convertFromYacsInt<PYTHONImpl,PyObject*>
943 static inline PyObject* convert(const TypeCode *t,long o)
945 PyObject *pyob=PyLong_FromLong(o);
950 struct convertFromYacsString<PYTHONImpl,PyObject*>
952 static inline PyObject* convert(const TypeCode *t,std::string& o)
954 return PyUnicode_FromString(o.c_str());
958 struct convertFromYacsBool<PYTHONImpl,PyObject*>
960 static inline PyObject* convert(const TypeCode *t,bool o)
962 return PyBool_FromLong ((long)o);
966 struct convertFromYacsObjref<PYTHONImpl,PyObject*>
968 static inline PyObject* convert(const TypeCode *t,std::string& o)
975 if(t->isA(Runtime::_tc_file))
977 //It's an objref file. Convert it specially
978 return PyUnicode_FromString(o.c_str());
980 if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0"
982 //It's a python pickled object, unpickled it
983 PyObject* mod=PyImport_ImportModule("pickle");
984 PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length());
985 DEBTRACE(PyObject_Repr(ob));
990 throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
994 if(strncmp(t->id(),"json",4)==0)
996 // It's a json object unpack it
997 PyObject* mod=PyImport_ImportModule("simplejson");
1001 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
1003 PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y",o.c_str());
1008 throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
1013 /* another way to convert IOR string to CORBA PyObject
1014 PyObject* ob= PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"string_to_object","s",o.c_str());
1015 DEBTRACE( "Objref python refcnt: " << ob->ob_refcnt );
1019 //Objref CORBA. prefix=IOR,corbaname,corbaloc
1020 CORBA::Object_var obref;
1023 obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1025 DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1028 catch(CORBA::Exception& ex)
1030 DEBTRACE( "Can't get reference to object." );
1031 throw ConversionException("Can't get reference to object");
1034 if(obref->_non_existent())
1036 throw ConversionException("non_existent object");
1039 if( CORBA::is_nil(obref) )
1041 DEBTRACE( "Can't get reference to object (or it was nil)." );
1042 throw ConversionException("Can't get reference to object");
1045 if(!obref->_is_a(t->id()))
1048 msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1049 msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1050 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1051 throw YACS::ENGINE::ConversionException(msg.str());
1054 DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1057 std::cerr << "_PD_repoId: " << obref->_PD_repoId << std::endl;
1058 std::cerr << "_mostDerivedRepoId: " << obref->_PR_getobj()->_mostDerivedRepoId() << std::endl;
1061 //hold_lock is true: caller is supposed to hold the GIL.
1062 //omniorb will not take the GIL
1063 PyObject* ob= getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(obref, 1);
1066 PyObject_Print(ob,stderr,Py_PRINT_RAW);
1067 std::cerr << std::endl;
1068 std::cerr << "obref is a generic: " << obref->_is_a("IDL:SALOME/GenericObj:1.0") << std::endl;
1069 PyObject_Print(getSALOMERuntime()->get_omnipy(),stderr,Py_PRINT_RAW);
1070 std::cerr << std::endl;
1073 //ob is a CORBA::Object. Try to convert it to more specific type SALOME/GenericObj
1074 if(obref->_is_a("IDL:SALOME/GenericObj:1.0"))
1076 PyObject *result = PyObject_CallMethod(getSALOMERuntime()->get_omnipy(), (char *)"narrow", (char *)"Osi",ob,"IDL:SALOME/GenericObj:1.0",1);
1078 PyErr_Clear();//Exception during narrow. Keep ob
1079 else if(result==Py_None)
1080 Py_DECREF(result); //Can't narrow. Keep ob
1083 //Can narrow. Keep result
1085 PyObject_Print(result,stderr,Py_PRINT_RAW);
1086 std::cerr << std::endl;
1094 DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1101 struct convertFromYacsSequence<PYTHONImpl,PyObject*>
1103 static inline PyObject* convert(const TypeCode *t,std::vector<PyObject*>& v)
1105 std::vector<PyObject*>::const_iterator iter;
1106 PyObject *pyob = PyList_New(v.size());
1108 for(iter=v.begin();iter!=v.end();iter++)
1110 PyObject* item=*iter;
1111 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1112 PyList_SetItem(pyob,i,item);
1113 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1120 struct convertFromYacsStruct<PYTHONImpl,PyObject*>
1122 static inline PyObject* convert(const TypeCode *t,std::map<std::string,PyObject*>& m)
1124 PyObject *pyob = PyDict_New();
1125 std::map<std::string, PyObject*>::const_iterator pt;
1126 for(pt=m.begin();pt!=m.end();pt++)
1128 std::string name=(*pt).first;
1129 PyObject* item=(*pt).second;
1130 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1131 PyDict_SetItemString(pyob,name.c_str(),item);
1133 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1135 DEBTRACE( "pyob refcnt: " << pyob->ob_refcnt );
1139 /* End of FromYacs Convertor for PYTHONImpl */
1141 //! ToYacs Convertor for XMLImpl
1143 * Partial specialization for XML implementation (XMLImpl)
1144 * This convertor converts xml object to YACS<TOUT> types
1146 template <ImplType IMPLOUT, class TOUT>
1147 struct convertToYacsDouble<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1149 static inline double convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1152 cur = cur->xmlChildrenNode;
1155 if ((!xmlStrcmp(cur->name, (const xmlChar *)"double")))
1157 //wait a double, got a double
1159 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1162 DEBTRACE( "convertToYacsDouble " << (const char *)s );
1163 d=Cstr2d((const char *)s);
1168 DEBTRACE("############### workaround to improve...");
1172 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1174 //wait a double, got an int
1176 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1179 DEBTRACE( "convertToYacsDouble " << (const char *)s );
1180 d=Cstr2d((const char *)s);
1185 DEBTRACE("############### workaround to improve...");
1192 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1193 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1194 throw YACS::ENGINE::ConversionException(msg.str());
1197 template <ImplType IMPLOUT, class TOUT>
1198 struct convertToYacsInt<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1200 static inline long convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1203 cur = cur->xmlChildrenNode;
1206 if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1209 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1212 DEBTRACE( "convertToYacsInt " << (const char *)s );
1213 d=atol((const char *)s);
1218 DEBTRACE("############### workaround to improve...");
1225 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1226 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1227 throw YACS::ENGINE::ConversionException(msg.str());
1230 template <ImplType IMPLOUT, class TOUT>
1231 struct convertToYacsString<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1233 static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1235 cur = cur->xmlChildrenNode;
1238 if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))
1240 //wait a string, got a string
1242 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1244 DEBTRACE( "convertToYacsString " << (const char *)s );
1245 std::string mystr=std::string((const char *)s);
1252 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1253 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1254 throw YACS::ENGINE::ConversionException(msg.str());
1257 template <ImplType IMPLOUT, class TOUT>
1258 struct convertToYacsBool<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1260 static inline bool convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1262 cur = cur->xmlChildrenNode;
1265 if ((!xmlStrcmp(cur->name, (const xmlChar *)"boolean")))
1267 //wait a boolean, got a boolean
1269 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1273 DEBTRACE( "convertToYacsBool " << (const char *)s );
1274 ob=atoi((const char*)s)!=0;
1279 DEBTRACE("############### workaround to improve...");
1286 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1287 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1288 throw YACS::ENGINE::ConversionException(msg.str());
1291 template <ImplType IMPLOUT, class TOUT>
1292 struct convertToYacsObjref<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1294 static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,int protocol)
1296 cur = cur->xmlChildrenNode;
1299 if ((!xmlStrcmp(cur->name, (const xmlChar *)"objref")))
1301 //we wait a objref, we have got a objref
1303 std::string mystr = "";
1304 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1307 DEBTRACE( "convertToYacsObjref " << (const char *)s );
1308 mystr = (const char *)s;
1313 DEBTRACE("############### workaround to improve...");
1315 if(strncmp(t->id(),"python",6)==0 )
1316 return FromBase64Safe(mystr);
1320 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))// <- here case where pyobj value has been stored in XML. pyobj has kind==ObjRef. And the stored format is String ! EDF11027
1322 //wait a string, got a string
1324 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1326 DEBTRACE( "convertToYacsString " << (const char *)s );
1327 std::string mystr=std::string((const char *)s);
1334 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1335 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1336 throw YACS::ENGINE::ConversionException(msg.str());
1339 template <ImplType IMPLOUT, class TOUT>
1340 struct convertToYacsSequence<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1342 static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::vector<TOUT>& v)
1344 cur = cur->xmlChildrenNode;
1347 if ((!xmlStrcmp(cur->name, (const xmlChar *)"array")))
1349 DEBTRACE( "parse sequence " );
1350 xmlNodePtr cur1=cur->xmlChildrenNode;
1351 while (cur1 != NULL)
1353 if ((!xmlStrcmp(cur1->name, (const xmlChar *)"data")))
1355 DEBTRACE( "parse data " );
1356 xmlNodePtr cur2=cur1->xmlChildrenNode;
1357 while (cur2 != NULL)
1359 //collect all values
1360 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1362 TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(t->contentType(),doc,cur2);
1366 } // end while value
1374 } // end while array
1377 template <ImplType IMPLOUT, class TOUT>
1378 struct convertToYacsStruct<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1380 static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::map<std::string,TOUT>& m)
1382 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1383 int nMember=tst->memberCount();
1384 DEBTRACE("nMember="<<nMember);
1385 std::map<std::string,TypeCode*> mtc;
1386 for(int i=0;i<nMember;i++)
1388 mtc[tst->memberName(i)]=tst->memberType(i);
1391 cur = cur->xmlChildrenNode;
1394 if ((!xmlStrcmp(cur->name, (const xmlChar *)"struct")))
1396 DEBTRACE( "parse struct " );
1397 xmlNodePtr cur1=cur->xmlChildrenNode;
1398 while (cur1 != NULL)
1400 if ((!xmlStrcmp(cur1->name, (const xmlChar *)"member")))
1402 DEBTRACE( "parse member " );
1403 xmlNodePtr cur2=cur1->xmlChildrenNode;
1404 while (cur2 != NULL)
1407 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"name")))
1410 s = xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
1411 std::string name= (char *)s;
1413 while (cur2 != NULL)
1415 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1417 TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(mtc[name],doc,cur2);
1427 } // end while member/value
1430 } // end while member
1434 } // end while struct
1437 /* End of ToYacs Convertor for XMLImpl */
1439 //! FromYacs Convertor for XMLImpl
1441 * Convert YACS<std::string> intermediate types to std::string types (XMLImpl)
1444 struct convertFromYacsDouble<XMLImpl,std::string>
1446 static inline std::string convert(const TypeCode *t,double o)
1449 msg << "<value><double>" << setprecision(16) << o << "</double></value>\n";
1454 struct convertFromYacsInt<XMLImpl,std::string>
1456 static inline std::string convert(const TypeCode *t,long o)
1459 msg << "<value><int>" << o << "</int></value>\n";
1464 struct convertFromYacsString<XMLImpl,std::string>
1466 static inline std::string convert(const TypeCode *t,std::string& o)
1468 std::string msg="<value><string>";
1469 return msg+o+"</string></value>\n";
1473 struct convertFromYacsBool<XMLImpl,std::string>
1475 static inline std::string convert(const TypeCode *t,bool o)
1478 msg << "<value><boolean>" << o << "</boolean></value>\n";
1483 struct convertFromYacsObjref<XMLImpl,std::string>
1485 static inline std::string convert(const TypeCode *t,std::string& o)
1487 if(strncmp(t->id(),"python",6)==0 )
1488 return "<value><objref><![CDATA[" + ToBase64(o) + "]]></objref></value>\n";
1489 else if(strncmp(t->id(),"json",4)==0)
1490 return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
1492 return "<value><objref>" + o + "</objref></value>\n";
1497 struct convertFromYacsSequence<XMLImpl,std::string>
1499 static inline std::string convert(const TypeCode *t,std::vector<std::string>& v)
1501 std::vector<std::string>::const_iterator iter;
1503 xmlob << "<value><array><data>\n";
1504 for(iter=v.begin();iter!=v.end();iter++)
1508 xmlob << "</data></array></value>\n";
1509 DEBTRACE("Sequence= " << xmlob);
1514 struct convertFromYacsStruct<XMLImpl,std::string>
1516 static inline std::string convert(const TypeCode *t,std::map<std::string,std::string>& m)
1518 std::string result="<value><struct>\n";
1519 std::map<std::string, std::string>::const_iterator pt;
1520 for(pt=m.begin();pt!=m.end();pt++)
1522 std::string name=(*pt).first;
1523 std::string item=(*pt).second;
1524 result=result+"<member>\n";
1525 result=result+"<name>"+name+"</name>\n";
1527 result=result+"</member>\n";
1529 result=result+"</struct></value>\n";
1534 /* End of FromYacs Convertor for XMLImpl */
1536 //! ToYacs Convertor for NEUTRALImpl
1538 * This convertor converts Neutral objects to intermediate YACS<TOUT> types
1539 * Template : Partial specialization for Neutral implementation with types YACS::ENGINE::Any*
1541 template <ImplType IMPLOUT, class TOUT>
1542 struct convertToYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1544 static inline double convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1546 if(o->getType()->kind()==Double)
1547 return o->getDoubleValue();
1548 else if(o->getType()->kind()==Int)
1549 return o->getIntValue();
1552 msg << "Problem in conversion: a double or int is expected " ;
1553 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1554 throw YACS::ENGINE::ConversionException(msg.str());
1557 template <ImplType IMPLOUT, class TOUT>
1558 struct convertToYacsInt<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1560 static inline long convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1562 if(o->getType()->kind()==Int)
1563 return o->getIntValue();
1565 msg << "Problem in conversion: a int is expected " ;
1566 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1567 throw YACS::ENGINE::ConversionException(msg.str());
1570 template <ImplType IMPLOUT, class TOUT>
1571 struct convertToYacsString<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1573 static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1575 if(o->getType()->kind()==String)
1576 return o->getStringValue();
1578 msg << "Problem in conversion: a string is expected " ;
1579 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1580 throw YACS::ENGINE::ConversionException(msg.str());
1583 template <ImplType IMPLOUT, class TOUT>
1584 struct convertToYacsBool<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1586 static inline bool convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1588 if(o->getType()->kind()==Bool)
1589 return o->getBoolValue();
1590 else if(o->getType()->kind()==Int)
1591 return o->getIntValue() != 0;
1593 msg << "Problem in conversion: a bool or int is expected " ;
1594 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1595 throw YACS::ENGINE::ConversionException(msg.str());
1598 template <ImplType IMPLOUT, class TOUT>
1599 struct convertToYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1601 static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,int protocol)
1603 if(o->getType()->kind()==String || o->getType()->kind()==Objref)
1604 return o->getStringValue();
1606 msg << "Problem in conversion: a objref(string) is expected " ;
1607 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1608 throw YACS::ENGINE::ConversionException(msg.str());
1611 template <ImplType IMPLOUT, class TOUT>
1612 struct convertToYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1614 static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::vector<TOUT>& v)
1616 SequenceAny* sdata= (SequenceAny*)o;
1617 int length=sdata->size();
1619 for(int i=0;i<length;i++)
1621 TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(t->contentType(),(*sdata)[i],0);
1626 template <ImplType IMPLOUT, class TOUT>
1627 struct convertToYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1629 static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::map<std::string,TOUT>& m)
1631 StructAny * sdata = dynamic_cast<StructAny *>(o);
1632 YASSERT(sdata != NULL);
1633 const TypeCodeStruct * tst = dynamic_cast<const TypeCodeStruct *>(t);
1634 YASSERT(tst != NULL);
1635 for (int i=0 ; i<tst->memberCount() ; i++)
1637 string name = tst->memberName(i);
1638 TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),(*sdata)[name.c_str()],0);
1643 /* End of ToYacs Convertor for NEUTRALImpl */
1645 //! FromYacs Convertor for NEUTRALImpl
1647 * Convert YACS<YACS::ENGINE::Any*> intermediate types to YACS::ENGINE::Any* types (NEUTRALImpl)
1650 struct convertFromYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*>
1652 static inline YACS::ENGINE::Any* convert(const TypeCode *t,double o)
1654 YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(o);
1659 struct convertFromYacsInt<NEUTRALImpl,YACS::ENGINE::Any*>
1661 static inline YACS::ENGINE::Any* convert(const TypeCode *t,long o)
1663 return YACS::ENGINE::AtomAny::New((int)o);
1667 struct convertFromYacsString<NEUTRALImpl,YACS::ENGINE::Any*>
1669 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1671 return YACS::ENGINE::AtomAny::New(o);
1675 struct convertFromYacsBool<NEUTRALImpl,YACS::ENGINE::Any*>
1677 static inline YACS::ENGINE::Any* convert(const TypeCode *t,bool o)
1679 return YACS::ENGINE::AtomAny::New(o);
1683 struct convertFromYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*>
1685 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1687 //Check if objref is a GenericObj and register it if it is the case (workaround for bad management of GenericObj)
1688 if(o=="" || (t->isA(Runtime::_tc_file)) || (strncmp(t->id(),"python",6)==0) || (strncmp(t->id(),"json",4)==0))
1689 return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1691 //Objref CORBA. prefix=IOR,corbaname,corbaloc
1692 CORBA::Object_var obref;
1695 obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1697 catch(CORBA::Exception& ex)
1699 throw ConversionException("Can't get reference to object");
1701 if(obref->_non_existent())
1702 throw ConversionException("non_existent object");
1703 if( CORBA::is_nil(obref) )
1704 throw ConversionException("Can't get reference to object");
1705 if(!obref->_is_a(t->id()))
1708 msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1709 msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1710 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1711 throw YACS::ENGINE::ConversionException(msg.str());
1714 SALOME::GenericObj_var gobj=SALOME::GenericObj::_narrow(obref);
1715 if(!CORBA::is_nil(gobj))
1717 DEBTRACE("It's a SALOME::GenericObj register it");
1721 DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
1723 return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1728 struct convertFromYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*>
1730 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::vector<YACS::ENGINE::Any*>& v)
1732 std::vector<YACS::ENGINE::Any*>::const_iterator iter;
1733 //Objref are managed as string within YACS::ENGINE::Any objs
1735 any=SequenceAny::New(t->contentType());
1736 for(iter=v.begin();iter!=v.end();iter++)
1738 any->pushBack(*iter);
1741 DEBTRACE( "refcnt: " << any->getRefCnt() );
1747 struct convertFromYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*>
1749 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::map<std::string,YACS::ENGINE::Any*>& m)
1751 StructAny * any = StructAny::New((TypeCodeStruct *)t);
1752 std::map<std::string,YACS::ENGINE::Any*>::const_iterator it;
1753 for (it=m.begin() ; it!=m.end() ; it++)
1755 any->setEltAtRank(it->first.c_str(), it->second);
1756 it->second->decrRef();
1761 /* End of FromYacs Convertor for NEUTRALImpl */
1763 //! ToYacs Convertor for CORBAImpl
1765 * This convertor converts Corba objects to intermediate YACS<TOUT> types
1766 * Template : Partial specialization for CORBA implementation with types CORBA::Any*
1768 template <ImplType IMPLOUT, class TOUT>
1769 struct convertToYacsDouble<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1771 static inline double convert(const TypeCode *t,CORBA::Any* o,void*)
1773 CORBA::TypeCode_var tc = o->type();
1774 if (tc->equivalent(CORBA::_tc_double))
1780 if (tc->equivalent(CORBA::_tc_long))
1787 msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1788 msg << " : " << __FILE__ << ":" << __LINE__;
1789 throw YACS::ENGINE::ConversionException(msg.str());
1792 template <ImplType IMPLOUT, class TOUT>
1793 struct convertToYacsInt<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1795 static inline long convert(const TypeCode *t,CORBA::Any* o,void*)
1801 msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1802 msg << " : " << __FILE__ << ":" << __LINE__;
1803 throw YACS::ENGINE::ConversionException(msg.str());
1806 template <ImplType IMPLOUT, class TOUT>
1807 struct convertToYacsString<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1809 static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*)
1815 msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1816 msg << " : " << __FILE__ << ":" << __LINE__;
1817 throw YACS::ENGINE::ConversionException(msg.str());
1820 template <ImplType IMPLOUT, class TOUT>
1821 struct convertToYacsBool<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1823 static inline bool convert(const TypeCode *t,CORBA::Any* o,void*)
1826 if(*o >>= CORBA::Any::to_boolean(b))
1829 msg << "Problem in Corba to TOUT conversion: kind= " << t->kind() ;
1830 msg << " : " << __FILE__ << ":" << __LINE__;
1831 throw YACS::ENGINE::ConversionException(msg.str());
1834 template <ImplType IMPLOUT, class TOUT>
1835 struct convertToYacsObjref<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1837 static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*,int protocol)
1839 char file[]="/tmp/XXXXXX";
1840 if(t->isA(Runtime::_tc_file))
1842 Engines::Salome_file_ptr sf;
1844 Salome_file_i* f=new Salome_file_i();
1846 f->setDistributedFile(file);
1852 else if(strncmp(t->id(),"python",6)==0)
1855 Engines::fileBlock * buffer;
1858 s=(const char*)buffer->get_buffer();
1862 std::string mystr(s,buffer->length());
1866 PyGILState_STATE gstate = PyGILState_Ensure();
1867 PyObject* mod=PyImport_ImportModule("pickle");
1868 PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",s,buffer->length());
1869 PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",ob,protocol);
1870 DEBTRACE(PyObject_Repr(pickled));
1871 std::string mystr=PyBytes_AsString(pickled);
1875 PyGILState_Release(gstate);
1880 msg << "Problem in CORBA (protocol python) to TOUT conversion: kind= " << t->kind() ;
1881 msg << " : " << __FILE__ << ":" << __LINE__;
1882 throw YACS::ENGINE::ConversionException(msg.str());
1884 else if(strncmp(t->id(),"json",4)==0)
1892 msg << "Problem in CORBA (protocol json) to TOUT conversion: kind= " << t->kind() ;
1893 msg << " : " << __FILE__ << ":" << __LINE__;
1894 throw YACS::ENGINE::ConversionException(msg.str());
1898 CORBA::Object_var ObjRef ;
1899 *o >>= CORBA::Any::to_object(ObjRef) ;
1900 CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef);
1901 return (char *)objref;
1905 template <ImplType IMPLOUT, class TOUT>
1906 struct convertToYacsSequence<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1908 static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::vector<TOUT>& v)
1910 CORBA::TypeCode_var tc=o->type();
1911 if (tc->kind() != CORBA::tk_sequence)
1914 msg << "Not a sequence corba type " << tc->kind();
1915 msg << " : " << __FILE__ << ":" << __LINE__;
1916 throw YACS::ENGINE::ConversionException(msg.str());
1918 DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1919 DynamicAny::DynSequence_ptr ds=DynamicAny::DynSequence::_narrow(dynany);
1920 CORBA::release(dynany);
1921 DynamicAny::AnySeq_var as=ds->get_elements();
1922 int len=as->length();
1924 for(int i=0;i<len;i++)
1927 DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1929 TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(t->contentType(),&as[i],0);
1934 for(int i=0;i<len;i++)
1937 DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1942 template <ImplType IMPLOUT, class TOUT>
1943 struct convertToYacsStruct<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1945 static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::map<std::string,TOUT>& m)
1947 CORBA::TypeCode_var tc=o->type();
1948 DEBTRACE(tc->kind());
1949 if (tc->kind() != CORBA::tk_struct)
1952 msg << "Not a struct corba type " << tc->kind();
1953 msg << " : " << __FILE__ << ":" << __LINE__;
1954 throw YACS::ENGINE::ConversionException(msg.str());
1956 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1957 DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1958 DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(dynany);
1959 CORBA::release(dynany);
1960 DynamicAny::NameValuePairSeq_var as=ds->get_members();
1961 int len=as->length();
1962 for(int i=0;i<len;i++)
1964 std::string name=as[i].id.in();
1966 CORBA::Any value=as[i].value;
1968 DEBTRACE("refcount CORBA value: " << ((omni::TypeCode_base*)value.pd_tc.in())->pd_ref_count);
1970 TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),&value,0);
1977 /* End of ToYacs Convertor for CORBAImpl */
1979 //! FromYacs Convertor for CORBAImpl
1981 * Convert YACS<CORBA::Any*> intermediate types to CORBA::Any* types (CORBAImpl)
1984 struct convertFromYacsDouble<CORBAImpl,CORBA::Any*>
1986 static inline CORBA::Any* convert(const TypeCode *t,double o)
1988 CORBA::Any *any = new CORBA::Any();
1989 *any <<= (CORBA::Double)o;
1994 struct convertFromYacsInt<CORBAImpl,CORBA::Any*>
1996 static inline CORBA::Any* convert(const TypeCode *t,long o)
1998 CORBA::Any *any = new CORBA::Any();
1999 *any <<= (CORBA::Long)o;
2004 struct convertFromYacsString<CORBAImpl,CORBA::Any*>
2006 static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2008 CORBA::Any *any = new CORBA::Any();
2014 struct convertFromYacsBool<CORBAImpl,CORBA::Any*>
2016 static inline CORBA::Any* convert(const TypeCode *t,bool o)
2018 CORBA::Any *any = new CORBA::Any();
2019 *any <<= CORBA::Any::from_boolean(o);
2024 struct convertFromYacsObjref<CORBAImpl,CORBA::Any*>
2026 static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2028 CORBA::Object_var obref;
2030 if(t->isA(Runtime::_tc_file))
2032 //It's an objref file. Convert it specially
2033 Salome_file_i* aSalome_file = new Salome_file_i();
2036 aSalome_file->setLocalFile(o.c_str());
2037 obref = aSalome_file->_this();
2038 aSalome_file->_remove_ref();
2040 catch (const SALOME::SALOME_Exception& e)
2043 msg << e.details.text;
2044 msg << " : " << __FILE__ << ":" << __LINE__;
2045 throw YACS::ENGINE::ConversionException(msg.str());
2048 else if(strncmp(t->id(),"python",6)==0 )
2050 CORBA::Any *any = new CORBA::Any();
2051 Engines::fileBlock * buffer=new Engines::fileBlock();
2052 buffer->length(o.length());
2053 CORBA::Octet *buf=buffer->get_buffer();
2054 memcpy(buf,o.c_str(),o.length());
2058 else if(strncmp(t->id(),"json",4)==0)
2060 CORBA::Any *any = new CORBA::Any();
2068 obref=getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
2070 catch(CORBA::Exception& ex)
2072 throw ConversionException("Can't get reference to object");
2074 if( CORBA::is_nil(obref) )
2076 throw ConversionException("Can't get reference to object");
2080 DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2082 CORBA::Any *any = new CORBA::Any();
2085 DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2092 struct convertFromYacsSequence<CORBAImpl,CORBA::Any*>
2094 static inline CORBA::Any* convert(const TypeCode *t,std::vector<CORBA::Any*>& v)
2096 CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2097 std::vector<CORBA::Any*>::const_iterator iter;
2099 // Build an Any from vector v
2101 if(t->contentType()->kind() == Objref)
2104 CORBA::TypeCode_var tc=getCorbaTC(t);
2106 DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2107 DynamicAny::DynSequence_var ds = DynamicAny::DynSequence::_narrow(dynany);
2108 ds->set_length(v.size());
2110 for(iter=v.begin();iter!=v.end();iter++)
2112 DynamicAny::DynAny_var temp=ds->current_component();
2113 CORBA::Any* a=*iter;
2114 //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2117 CORBA::Object_var zzobj ;
2118 *a >>= CORBA::Any::to_object(zzobj) ;
2119 temp->insert_reference(zzobj);
2124 //delete intermediate any
2129 CORBA::Any *any=ds->to_any();
2135 struct convertFromYacsStruct<CORBAImpl,CORBA::Any*>
2137 static inline CORBA::Any* convert(const TypeCode *t,std::map<std::string,CORBA::Any*>& m)
2139 CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2141 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2142 int nMember=tst->memberCount();
2143 DEBTRACE("nMember="<<nMember);
2145 CORBA::TypeCode_var tc=getCorbaTC(t);
2146 DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2147 DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(dynany);
2149 for(int i=0;i<nMember;i++)
2151 DynamicAny::DynAny_var temp=ds->current_component();
2152 const char * name=tst->memberName(i);
2153 DEBTRACE("Member name="<<name);
2154 //do not test member presence : test has been done in ToYacs convertor
2155 CORBA::Any* a=m[name];
2156 //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2157 CORBA::TypeCode_var atc = tc->member_type(i);
2158 if(atc->kind()==CORBA::tk_objref)
2160 //special treatment for objref
2161 CORBA::Object_var zzobj ;
2162 *a >>= CORBA::Any::to_object(zzobj) ;
2163 temp->insert_reference(zzobj);
2169 //delete intermediate any
2173 CORBA::Any *any=ds->to_any();
2179 /* End of FromYacs Convertor for CORBAImpl */
2181 /* Some shortcuts for CORBA to CORBA conversion */
2183 inline CORBA::Any* convertDouble<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2185 CORBA::TypeCode_var tc = o->type();
2186 if (tc->equivalent(CORBA::_tc_double))
2190 if (tc->equivalent(CORBA::_tc_long))
2194 CORBA::Any *any = new CORBA::Any();
2195 *any <<= (CORBA::Double)d;
2199 msg << "Not a double or long corba type " << tc->kind();
2200 msg << " : " << __FILE__ << ":" << __LINE__;
2201 throw YACS::ENGINE::ConversionException(msg.str());
2204 inline CORBA::Any* convertInt<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2209 inline CORBA::Any* convertString<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2214 inline CORBA::Any* convertBool<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2219 inline CORBA::Any* convertObjref<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2224 inline CORBA::Any* convertStruct<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2228 /* End of shortcuts for CORBA to CORBA conversion */
2230 //! ToYacs Convertor for CPPImpl
2232 * This convertor converts Python object to YACS<TOUT> types
2233 * Partial specialization for Python implementation with type PyObject* (PYTHONImpl)
2235 template <ImplType IMPLOUT, class TOUT>
2236 struct convertToYacsDouble<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2238 static inline double convert(const TypeCode *t,void* o,const TypeCode* intype)
2240 if(intype->kind()==YACS::ENGINE::Double)
2244 else if(intype->kind()==YACS::ENGINE::Int)
2249 msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2250 msg << " : " << __FILE__ << ":" << __LINE__;
2251 throw YACS::ENGINE::ConversionException(msg.str());
2254 template <ImplType IMPLOUT, class TOUT>
2255 struct convertToYacsInt<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2257 static inline long convert(const TypeCode *t,void* o,const TypeCode* intype)
2259 if(intype->kind()==YACS::ENGINE::Int)
2264 msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2265 msg << " : " << __FILE__ << ":" << __LINE__;
2266 throw YACS::ENGINE::ConversionException(msg.str());
2269 /* End of ToYacs Convertor for CPPImpl */
2271 //Python conversions
2272 std::string convertPyObjectXml(const TypeCode *t,PyObject *data)
2274 return YacsConvertor<PYTHONImpl,PyObject*,void*,XMLImpl,std::string>(t,data,0);
2276 YACS::ENGINE::Any* convertPyObjectNeutral(const TypeCode *t,PyObject *data)
2278 return YacsConvertor<PYTHONImpl,PyObject*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2280 CORBA::Any* convertPyObjectCorba(const TypeCode *t,PyObject *data)
2282 return YacsConvertor<PYTHONImpl,PyObject*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2284 PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *data)
2286 return YacsConvertor<PYTHONImpl,PyObject*,void*,PYTHONImpl,PyObject*>(t,data,0);
2289 std::string convertPyObjectToString(PyObject* ob)
2292 PyGILState_STATE gstate = PyGILState_Ensure();
2293 // TODO: separate treatment for string (maybe with bad encoding?) and other types of PyObject ?
2294 // Do we need str() or repr() and what are the possible causes of failure of str() ?
2295 // not clear, needs more analysis.
2297 if (s == NULL) // for instance string with bad encoding, non utf-8
2299 s=PyObject_ASCII(ob); // escape non ASCII characters and like repr(), which is not the same as str()...
2302 const char* characters = PyUnicode_AsUTF8AndSize(s, &size);
2303 std::string ss( characters, size);
2305 PyGILState_Release(gstate);
2310 PyObject* convertXmlPyObject(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2312 return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,PYTHONImpl,PyObject*>(t,doc,cur);
2314 YACS::ENGINE::Any* convertXmlNeutral(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2316 return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,NEUTRALImpl,YACS::ENGINE::Any*>(t,doc,cur);
2318 CORBA::Any* convertXmlCorba(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2320 return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,CORBAImpl,CORBA::Any*>(t,doc,cur);
2322 PyObject* convertXmlStrPyObject(const TypeCode *t,std::string data)
2327 doc = xmlParseMemory(data.c_str(), strlen(data.c_str()));
2330 std::stringstream msg;
2331 msg << "Problem in conversion: XML Document not parsed successfully ";
2332 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2333 throw YACS::ENGINE::ConversionException(msg.str());
2335 cur = xmlDocGetRootElement(doc);
2339 std::stringstream msg;
2340 msg << "Problem in conversion: empty XML Document";
2341 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2342 throw YACS::ENGINE::ConversionException(msg.str());
2346 if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
2348 ob=convertXmlPyObject(t,doc,cur);
2356 std::stringstream msg;
2357 msg << "Problem in conversion: incorrect XML value";
2358 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2359 throw YACS::ENGINE::ConversionException(msg.str());
2363 //NEUTRAL conversions
2364 PyObject* convertNeutralPyObject(const TypeCode *t,YACS::ENGINE::Any* data)
2366 return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2368 std::string convertNeutralXml(const TypeCode *t,YACS::ENGINE::Any* data)
2370 return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,XMLImpl,std::string>(t,data,0);
2372 CORBA::Any* convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any* data)
2374 return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2376 YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* data)
2383 PyObject* convertCorbaPyObject(const TypeCode *t,CORBA::Any* data)
2385 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2387 std::string convertCorbaXml(const TypeCode *t,CORBA::Any* data)
2389 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,XMLImpl,std::string>(t,data,0);
2391 YACS::ENGINE::Any* convertCorbaNeutral(const TypeCode *t,CORBA::Any* data)
2393 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2395 CORBA::Any *convertCorbaCorba(const TypeCode *t,CORBA::Any *data)
2397 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2400 //! Basic template checker from type TIN
2402 * This checker does nothing : throws exception
2403 * It must be partially specialize for a specific type (TIN)
2405 template <ImplType IMPLIN,class TIN,class TIN2>
2406 static inline bool checkDouble(const TypeCode *t,TIN o,TIN2 aux)
2409 msg << "Check not implemented for Implementation: " << IMPLIN ;
2410 msg << " : " << __FILE__ << ":" << __LINE__;
2411 throw YACS::ENGINE::ConversionException(msg.str());
2413 template <ImplType IMPLIN,class TIN,class TIN2>
2414 static inline bool checkInt(const TypeCode *t,TIN o,TIN2 aux)
2417 msg << "Check not implemented for Implementation: " << IMPLIN ;
2418 msg << " : " << __FILE__ << ":" << __LINE__;
2419 throw YACS::ENGINE::ConversionException(msg.str());
2421 template <ImplType IMPLIN,class TIN,class TIN2>
2422 static inline bool checkBool(const TypeCode *t,TIN o,TIN2 aux)
2425 msg << "Check not implemented for Implementation: " << IMPLIN ;
2426 msg << " : " << __FILE__ << ":" << __LINE__;
2427 throw YACS::ENGINE::ConversionException(msg.str());
2429 template <ImplType IMPLIN,class TIN,class TIN2>
2430 static inline bool checkString(const TypeCode *t,TIN o,TIN2 aux)
2433 msg << "Check not implemented for Implementation: " << IMPLIN ;
2434 msg << " : " << __FILE__ << ":" << __LINE__;
2435 throw YACS::ENGINE::ConversionException(msg.str());
2437 template <ImplType IMPLIN,class TIN,class TIN2>
2438 static inline bool checkObjref(const TypeCode *t,TIN o,TIN2 aux)
2441 msg << "Check not implemented for Implementation: " << IMPLIN ;
2442 msg << " : " << __FILE__ << ":" << __LINE__;
2443 throw YACS::ENGINE::ConversionException(msg.str());
2445 template <ImplType IMPLIN,class TIN,class TIN2>
2446 static inline bool checkSequence(const TypeCode *t,TIN o,TIN2 aux)
2449 msg << "Check not implemented for Implementation: " << IMPLIN ;
2450 msg << " : " << __FILE__ << ":" << __LINE__;
2451 throw YACS::ENGINE::ConversionException(msg.str());
2453 template <ImplType IMPLIN,class TIN,class TIN2>
2454 static inline bool checkStruct(const TypeCode *t,TIN o,TIN2 aux)
2457 msg << "Check not implemented for Implementation: " << IMPLIN ;
2458 msg << " : " << __FILE__ << ":" << __LINE__;
2459 throw YACS::ENGINE::ConversionException(msg.str());
2461 template <ImplType IMPLIN,class TIN,class TIN2>
2462 static inline bool checkArray(const TypeCode *t,TIN o,TIN2 aux)
2465 msg << "Check not implemented for Implementation: " << IMPLIN ;
2466 msg << " : " << __FILE__ << ":" << __LINE__;
2467 throw YACS::ENGINE::ConversionException(msg.str());
2470 template <ImplType IMPLIN,class TIN,class TIN2>
2471 inline bool YacsChecker(const TypeCode *t,TIN o,TIN2 aux)
2477 return checkDouble<IMPLIN,TIN,TIN2>(t,o,aux);
2479 return checkInt<IMPLIN,TIN,TIN2>(t,o,aux);
2481 return checkString<IMPLIN,TIN,TIN2>(t,o,aux);
2483 return checkBool<IMPLIN,TIN,TIN2>(t,o,aux);
2485 return checkObjref<IMPLIN,TIN,TIN2>(t,o,aux);
2487 return checkSequence<IMPLIN,TIN,TIN2>(t,o,aux);
2489 return checkArray<IMPLIN,TIN,TIN2>(t,o,aux);
2491 return checkStruct<IMPLIN,TIN,TIN2>(t,o,aux);
2496 msg << "Check not implemented for kind= " << tk ;
2497 msg << " : " << __FILE__ << ":" << __LINE__;
2498 throw YACS::ENGINE::ConversionException(msg.str());
2501 inline bool checkDouble<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2503 if (PyFloat_Check(o))
2505 else if(PyLong_Check(o))
2510 msg << "Not a python double ";
2511 throw YACS::ENGINE::ConversionException(msg.str());
2515 inline bool checkInt<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2517 if (PyLong_Check(o))
2522 msg << "Not a python integer ";
2523 throw YACS::ENGINE::ConversionException(msg.str());
2527 inline bool checkBool<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2529 if (PyBool_Check(o))
2531 else if(PyLong_Check(o))
2536 msg << "Not a python boolean " ;
2537 throw YACS::ENGINE::ConversionException(msg.str());
2542 inline bool checkString<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2544 if (PyUnicode_Check(o))
2549 msg << "Not a python string " ;
2550 throw YACS::ENGINE::ConversionException(msg.str());
2554 inline bool checkObjref<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2556 if (PyUnicode_Check(o))
2558 if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true)
2560 else if(strncmp(t->id(),"json",4)==0) // The python object must be json pickable
2562 // The python object should be json compliant (to improve)
2567 // The python object should be a CORBA obj (to improve)
2572 inline bool checkSequence<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2574 if(!PySequence_Check(o))
2577 msg << "python object is not a sequence " ;
2578 throw YACS::ENGINE::ConversionException(msg.str());
2580 int length=PySequence_Size(o);
2581 for(int i=0;i<length;i++)
2583 PyObject *item=PySequence_ITEM(o,i);
2586 YacsChecker<PYTHONImpl,PyObject*,void*>(t->contentType(),item,0);
2588 catch(ConversionException& ex)
2591 msg << ex.what() << " for sequence element " << i;
2592 throw YACS::ENGINE::ConversionException(msg.str(),false);
2599 inline bool checkStruct<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2602 if(!PyDict_Check(o))
2605 msg << "python object is not a dict " ;
2606 throw YACS::ENGINE::ConversionException(msg.str());
2608 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2609 int nMember=tst->memberCount();
2610 for(int i=0;i<nMember;i++)
2612 std::string name=tst->memberName(i);
2613 TypeCode* tm=tst->memberType(i);
2614 value=PyDict_GetItemString(o, name.c_str());
2618 msg << "member " << name << " not present " ;
2619 throw YACS::ENGINE::ConversionException(msg.str());
2623 YacsChecker<PYTHONImpl,PyObject*,void*>(tm,value,0);
2625 catch(ConversionException& ex)
2627 std::string s=" for struct member "+name;
2628 throw YACS::ENGINE::ConversionException(ex.what()+s,false);
2634 bool checkPyObject(const TypeCode *t,PyObject* ob)
2636 return YacsChecker<PYTHONImpl,PyObject*,void*>(t,ob,0);