1 // Copyright (C) 2006-2020 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 void printbin(const std::string& bin)
65 for(int i=0;i<bin.length();i++)
68 if (c < ' ' || c >= 0x7f)
70 fprintf(stderr,"\\x%02x",c & 0xff);
73 fprintf(stderr,"%c",c);
78 std::string getImplName(ImplType impl)
97 * Functions to return a CORBA TypeCode equivalent to a YACS TypeCode
100 typedef CORBA::TypeCode_ptr (*getCorbaTCFn)(const TypeCode *);
102 CORBA::TypeCode_ptr getCorbaTCNull(const TypeCode *t)
105 msg << "Conversion not implemented: kind= " << t->kind();
106 msg << " : " << __FILE__ << ":" << __LINE__;
107 throw YACS::ENGINE::ConversionException(msg.str());
110 CORBA::TypeCode_ptr getCorbaTCDouble(const TypeCode *t)
112 return CORBA::TypeCode::_duplicate(CORBA::_tc_double);
115 CORBA::TypeCode_ptr getCorbaTCInt(const TypeCode *t)
117 return CORBA::TypeCode::_duplicate(CORBA::_tc_long);
120 CORBA::TypeCode_ptr getCorbaTCString(const TypeCode *t)
122 return CORBA::TypeCode::_duplicate(CORBA::_tc_string);
125 CORBA::TypeCode_ptr getCorbaTCBool(const TypeCode *t)
127 return CORBA::TypeCode::_duplicate(CORBA::_tc_boolean);
130 CORBA::TypeCode_ptr getCorbaTCObjref(const TypeCode *t)
132 DEBTRACE( t->name() << " " << t->shortName() << " " << t->id());
133 CORBA::TypeCode_ptr tc;
134 if(strncmp(t->id(),"python",6)==0 )
135 tc= CORBA::TypeCode::_duplicate(Engines::_tc_fileBlock);
136 else if(strncmp(t->id(),"json",4)==0)
137 tc= CORBA::TypeCode::_duplicate(CORBA::_tc_string);
139 tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName());
141 DEBTRACE("refcount CORBA tc Objref: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
146 CORBA::TypeCode_ptr getCorbaTCSequence(const TypeCode *t)
148 CORBA::TypeCode_var content_type=getCorbaTC(t->contentType());
149 CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_sequence_tc(0,content_type);
151 DEBTRACE("refcount CORBA content_type: " << ((omni::TypeCode_base*)content_type.in())->pd_ref_count);
152 DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
157 CORBA::TypeCode_ptr getCorbaTCStruct(const TypeCode *t)
159 CORBA::StructMemberSeq mseq;
160 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
161 int nMember=tst->memberCount();
162 mseq.length(nMember);
163 for(int i=0;i<nMember;i++)
165 const char * name=tst->memberName(i);
166 TypeCode* tm=tst->memberType(i);
167 mseq[i].name=CORBA::string_dup(name);
168 mseq[i].type=getCorbaTC(tm);
170 CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_struct_tc(t->id(),t->shortName(),mseq);
172 DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
177 getCorbaTCFn getCorbaTCFns[]=
190 CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t)
193 return getCorbaTCFns[tk](t);
197 * End of Functions to return a CORBA TypeCode equivalent to a YACS TypeCode
201 * Section that defines functions to check adaptation from one implementation to another
202 * isAdaptable is template function that checks if TypeCode t1 from implementation IMPLIN
203 * can be converted to TypeCode t2 from implementation IMPLOUT
204 * IMPLIN is the implementation of an output port
205 * IMPLOUT is the implementation of an input port
206 * If the check is True, the input port can be adapted to the output port
209 template <ImplType IMPLIN,ImplType IMPLOUT> inline int isAdaptable(const TypeCode *t1,const TypeCode* t2);
211 template <ImplType IMPLIN,ImplType IMPLOUT>
212 struct isAdaptableDouble
214 static inline int apply(const TypeCode *t1,const TypeCode* t2)
216 if(t1->kind() == Double)return 1;
217 if(t1->kind() == Int)return 1;
221 template <ImplType IMPLIN,ImplType IMPLOUT>
222 struct isAdaptableInt
224 static inline int apply(const TypeCode *t1,const TypeCode* t2)
226 if(t1->kind() == Int)return 1;
230 template <ImplType IMPLIN,ImplType IMPLOUT>
231 struct isAdaptableString
233 static inline int apply(const TypeCode *t1,const TypeCode* t2)
235 if(t1->kind() == String)return 1;
239 template <ImplType IMPLIN,ImplType IMPLOUT>
240 struct isAdaptableBool
242 static inline int apply(const TypeCode *t1,const TypeCode* t2)
244 if(t1->kind() == Bool)return 1;
245 if(t1->kind() == Int)return 1;
249 template <ImplType IMPLIN,ImplType IMPLOUT>
250 struct isAdaptableObjref
252 static inline int apply(const TypeCode *t1,const TypeCode* t2)
254 if(t1->kind() == Objref)
256 //The inport type must be more general than outport type
257 if( t1->isA(t2->id()) )
260 else if(t1->kind() == Sequence)
262 const TypeCodeSeq *t1c(dynamic_cast<const TypeCodeSeq *>(t1));
265 const TypeCode *t1cc(t1c->contentType());
268 if(t1cc->kind() == Objref && std::string(t1cc->id())==std::string(t2->id()))
274 template <ImplType IMPLIN,ImplType IMPLOUT>
275 struct isAdaptableSequence
277 static inline int apply(const TypeCode *t1,const TypeCode* t2)
279 if(t1->kind() == Sequence)
281 if(isAdaptable<IMPLIN,IMPLOUT>(t1->contentType(),t2->contentType()))
289 template <ImplType IMPLIN,ImplType IMPLOUT>
290 struct isAdaptableArray
292 static inline int apply(const TypeCode *t1,const TypeCode* t2)
297 template <ImplType IMPLIN,ImplType IMPLOUT>
298 struct isAdaptableStruct
300 static inline int apply(const TypeCode *t1,const TypeCode* t2)
302 if(t1->kind() == Struct)
312 * Function to check adaptation from implementation 1 (IMPLIN,t1) to implementation 2 (IMPLOUT,t2)
313 * t1 is the IMPLIN output port type
314 * t2 is the IMPLOUT input port type
316 template <ImplType IMPLIN,ImplType IMPLOUT>
317 inline int isAdaptable(const TypeCode *t1,const TypeCode* t2)
322 return isAdaptableDouble<IMPLIN,IMPLOUT>::apply(t1,t2);
324 return isAdaptableInt<IMPLIN,IMPLOUT>::apply(t1,t2);
326 return isAdaptableString<IMPLIN,IMPLOUT>::apply(t1,t2);
328 return isAdaptableBool<IMPLIN,IMPLOUT>::apply(t1,t2);
330 return isAdaptableObjref<IMPLIN,IMPLOUT>::apply(t1,t2);
332 return isAdaptableSequence<IMPLIN,IMPLOUT>::apply(t1,t2);
334 return isAdaptableArray<IMPLIN,IMPLOUT>::apply(t1,t2);
336 return isAdaptableStruct<IMPLIN,IMPLOUT>::apply(t1,t2);
343 //xxx to Python adaptations
344 int isAdaptableCorbaPyObject(const TypeCode *t1,const TypeCode *t2)
346 return isAdaptable<PYTHONImpl,CORBAImpl>(t1,t2);
348 int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2)
350 return isAdaptable<PYTHONImpl,NEUTRALImpl>(t1,t2);
352 int isAdaptablePyObjectPyObject(const TypeCode *t1,const TypeCode *t2)
354 return isAdaptable<PYTHONImpl,PYTHONImpl>(t1,t2);
357 //xxx to Neutral adaptations
358 int isAdaptableCorbaNeutral(const TypeCode *t1,const TypeCode *t2)
360 return isAdaptable<NEUTRALImpl,CORBAImpl>(t1,t2);
362 int isAdaptablePyObjectNeutral(const TypeCode *t1,const TypeCode *t2)
364 return isAdaptable<NEUTRALImpl,PYTHONImpl>(t1,t2);
366 int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2)
368 return isAdaptable<NEUTRALImpl,XMLImpl>(t1,t2);
370 int isAdaptableNeutralNeutral(const TypeCode *t1, const TypeCode *t2)
372 return isAdaptableNeutralCorba(t1, t2);
375 //xxx to XML adaptations
376 int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2)
378 return isAdaptable<XMLImpl,NEUTRALImpl>(t1,t2);
381 //xxx to Corba adaptations
382 int isAdaptableNeutralCorba(const TypeCode *t1,const TypeCode *t2)
384 return isAdaptable<CORBAImpl,NEUTRALImpl>(t1,t2);
386 int isAdaptableXmlCorba(const TypeCode *t1,const TypeCode *t2)
388 return isAdaptable<CORBAImpl,XMLImpl>(t1,t2);
390 int isAdaptableCorbaCorba(const TypeCode *t1,const TypeCode *t2)
392 return isAdaptable<CORBAImpl,CORBAImpl>(t1,t2);
394 int isAdaptablePyObjectCorba(const TypeCode *t1,const TypeCode *t2)
396 return isAdaptable<CORBAImpl,PYTHONImpl>(t1,t2);
399 //! Basic template convertor from type TIN to Yacs<TOUT> type
401 * This convertor does nothing : throws exception
402 * It must be partially specialize for a specific type (TIN)
404 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
405 struct convertToYacsDouble
407 static inline double convert(const TypeCode *t,TIN o,TIN2 aux)
410 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
411 msg << " : " << __FILE__ << ":" << __LINE__;
412 throw YACS::ENGINE::ConversionException(msg.str());
415 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
416 struct convertToYacsInt
418 static inline long convert(const TypeCode *t,TIN o,TIN2 aux)
421 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
422 msg << " : " << __FILE__ << ":" << __LINE__;
423 throw YACS::ENGINE::ConversionException(msg.str());
426 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
427 struct convertToYacsString
429 static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux)
432 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
433 msg << " : " << __FILE__ << ":" << __LINE__;
434 throw YACS::ENGINE::ConversionException(msg.str());
437 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
438 struct convertToYacsBool
440 static inline bool convert(const TypeCode *t,TIN o,TIN2 aux)
443 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
444 msg << " : " << __FILE__ << ":" << __LINE__;
445 throw YACS::ENGINE::ConversionException(msg.str());
448 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
449 struct convertToYacsObjref
451 static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux,int protocol)
454 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
455 msg << " : " << __FILE__ << ":" << __LINE__;
456 throw YACS::ENGINE::ConversionException(msg.str());
459 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
460 struct convertToYacsSequence
462 static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector<TOUT>& v)
465 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
466 msg << " : " << __FILE__ << ":" << __LINE__;
467 throw YACS::ENGINE::ConversionException(msg.str());
470 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
471 struct convertToYacsArray
473 static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector<TOUT>& v)
476 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
477 msg << " : " << __FILE__ << ":" << __LINE__;
478 throw YACS::ENGINE::ConversionException(msg.str());
481 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
482 struct convertToYacsStruct
484 static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::map<std::string,TOUT>& v)
487 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
488 msg << " : " << __FILE__ << ":" << __LINE__;
489 throw YACS::ENGINE::ConversionException(msg.str());
493 //! Basic convertor from Yacs<TOUT> type to full TOUT type
497 template <ImplType IMPLOUT, class TOUT>
498 struct convertFromYacsDouble
500 static inline TOUT convert(const TypeCode *t,double o)
503 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
504 msg << " : " << __FILE__ << ":" << __LINE__;
505 throw YACS::ENGINE::ConversionException(msg.str());
508 template <ImplType IMPLOUT, class TOUT>
509 struct convertFromYacsInt
511 static inline TOUT convert(const TypeCode *t,long o)
514 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
515 msg << " : " << __FILE__ << ":" << __LINE__;
516 throw YACS::ENGINE::ConversionException(msg.str());
519 template <ImplType IMPLOUT, class TOUT>
520 struct convertFromYacsString
522 static inline TOUT convert(const TypeCode *t,std::string o)
525 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
526 msg << " : " << __FILE__ << ":" << __LINE__;
527 throw YACS::ENGINE::ConversionException(msg.str());
530 template <ImplType IMPLOUT, class TOUT>
531 struct convertFromYacsBool
533 static inline TOUT convert(const TypeCode *t,bool o)
536 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
537 msg << " : " << __FILE__ << ":" << __LINE__;
538 throw YACS::ENGINE::ConversionException(msg.str());
541 template <ImplType IMPLOUT, class TOUT>
542 struct convertFromYacsObjref
544 static inline TOUT convert(const TypeCode *t,std::string o)
547 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
548 msg << " : " << __FILE__ << ":" << __LINE__;
549 throw YACS::ENGINE::ConversionException(msg.str());
552 template <ImplType IMPLOUT, class TOUT>
553 struct convertFromYacsSequence
555 static inline TOUT convert(const TypeCode *t,std::vector<TOUT>& v)
558 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
559 msg << " : " << __FILE__ << ":" << __LINE__;
560 throw YACS::ENGINE::ConversionException(msg.str());
563 template <ImplType IMPLOUT, class TOUT>
564 struct convertFromYacsArray
566 static inline TOUT convert(const TypeCode *t,std::vector<TOUT>& v)
569 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
570 msg << " : " << __FILE__ << ":" << __LINE__;
571 throw YACS::ENGINE::ConversionException(msg.str());
574 template <ImplType IMPLOUT, class TOUT>
575 struct convertFromYacsStruct
577 static inline TOUT convert(const TypeCode *t,std::map<std::string,TOUT>& v)
580 msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT;
581 msg << " : " << __FILE__ << ":" << __LINE__;
582 throw YACS::ENGINE::ConversionException(msg.str());
585 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
586 inline TOUT convertDouble(const TypeCode *t,TIN o,TIN2 aux)
588 double d=convertToYacsDouble<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
590 TOUT r=convertFromYacsDouble<IMPLOUT,TOUT>::convert(t,d);
593 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
594 inline TOUT convertInt(const TypeCode *t,TIN o,TIN2 aux)
596 long d=convertToYacsInt<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
598 TOUT r=convertFromYacsInt<IMPLOUT,TOUT>::convert(t,d);
601 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
602 inline TOUT convertString(const TypeCode *t,TIN o,TIN2 aux)
604 std::string d=convertToYacsString<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
606 TOUT r=convertFromYacsString<IMPLOUT,TOUT>::convert(t,d);
609 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
610 inline TOUT convertBool(const TypeCode *t,TIN o,TIN2 aux)
612 double d=convertToYacsBool<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
614 TOUT r=convertFromYacsBool<IMPLOUT,TOUT>::convert(t,d);
617 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
618 inline TOUT convertObjref(const TypeCode *t,TIN o,TIN2 aux)
622 protocol=0;//to avoid presence of \0 into XML generated file
623 if(IMPLOUT==NEUTRALImpl)
625 std::string d=convertToYacsObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,protocol);
627 TOUT r=convertFromYacsObjref<IMPLOUT,TOUT>::convert(t,d);
631 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
632 inline TOUT convertSequence(const TypeCode *t,TIN o,TIN2 aux)
635 convertToYacsSequence<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
636 TOUT r=convertFromYacsSequence<IMPLOUT,TOUT>::convert(t,v);
639 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
640 inline TOUT convertArray(const TypeCode *t,TIN o,TIN2 aux)
643 convertToYacsArray<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
644 TOUT r=convertFromYacsArray<IMPLOUT,TOUT>::convert(t,v);
647 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
648 inline TOUT convertStruct(const TypeCode *t,TIN o,TIN2 aux)
650 std::map<std::string,TOUT> v;
651 convertToYacsStruct<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,v);
652 TOUT r=convertFromYacsStruct<IMPLOUT,TOUT>::convert(t,v);
656 template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
657 inline TOUT YacsConvertor(const TypeCode *t,TIN o,TIN2 aux)
663 return convertDouble<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
665 return convertInt<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
667 return convertString<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
669 return convertBool<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
671 return convertObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
673 return convertSequence<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
675 return convertArray<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
677 return convertStruct<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>(t,o,aux);
682 msg << "Conversion not implemented: kind= " << tk << " Implementation: " << IMPLOUT;
683 msg << " : " << __FILE__ << ":" << __LINE__;
684 throw YACS::ENGINE::ConversionException(msg.str());
687 //! ToYacs Convertor for PYTHONImpl
689 * This convertor converts Python object to YACS<TOUT> types
690 * Partial specialization for Python implementation with type PyObject* (PYTHONImpl)
692 template <ImplType IMPLOUT, class TOUT>
693 struct convertToYacsDouble<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
695 static inline double convert(const TypeCode *t,PyObject* o,void*)
698 if (PyFloat_Check(o))
699 x=PyFloat_AS_DOUBLE(o);
700 else if(PyLong_Check(o))
705 msg << "Not a python double. ";
707 msg << "kind=" << t->kind() ;
708 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
710 throw YACS::ENGINE::ConversionException(msg.str());
715 template <ImplType IMPLOUT, class TOUT>
716 struct convertToYacsInt<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
718 static inline long convert(const TypeCode *t,PyObject* o,void*)
726 msg << "Not a python integer. ";
728 msg << "kind=" << t->kind() ;
729 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
731 throw YACS::ENGINE::ConversionException(msg.str());
736 template <ImplType IMPLOUT, class TOUT>
737 struct convertToYacsString<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
739 static inline std::string convert(const TypeCode *t,PyObject* o,void*)
742 if (PyUnicode_Check(o))
745 const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
747 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
753 msg << "Not a python string. ";
755 msg << "kind=" << t->kind() ;
756 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
758 throw YACS::ENGINE::ConversionException(msg.str());
763 template <ImplType IMPLOUT, class TOUT>
764 struct convertToYacsBool<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
766 static inline bool convert(const TypeCode *t,PyObject* o,void*)
771 else if(PyLong_Check(o))
772 l=(PyLong_AsLong(o)!=0);
776 msg << "Not a python boolean. ";
778 msg << "kind=" << t->kind() ;
779 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
781 throw YACS::ENGINE::ConversionException(msg.str());
786 template <ImplType IMPLOUT, class TOUT>
787 struct convertToYacsObjref<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
789 static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol)
791 if (PyUnicode_Check(o) && strncmp(t->id(),"python",6)!=0)
793 // the objref is used by Python as a string (prefix:value) keep it as a string
796 const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
798 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
802 if(strncmp(t->id(),"python",6)==0)
804 // It's a native Python object pickle it
805 PyObject* mod=PyImport_ImportModule("pickle");
806 PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol);
807 DEBTRACE(PyObject_Repr(pickled) );
812 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
814 std::string mystr(PyBytes_AsString(pickled),PyBytes_Size(pickled));
818 else if(strncmp(t->id(),"json",4)==0)
820 // It's a Python object convert it to json
821 PyObject* mod=PyImport_ImportModule("simplejson");
825 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
827 PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"O",o);
832 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
834 std::string mystr=PyBytes_AsString(pickled);
840 // It should be a CORBA Object convert it to an IOR string
841 PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),(char *)"object_to_string",(char *)"O",o);
845 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
849 const char *ptr = PyUnicode_AsUTF8AndSize(pystring, &size);
851 throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
852 mystr.assign(ptr, size);
858 template <ImplType IMPLOUT, class TOUT>
859 struct convertToYacsSequence<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
861 static inline void convert(const TypeCode *t,PyObject* o,void*,std::vector<TOUT>& v)
863 if(!PySequence_Check(o))
866 msg << "Problem in conversion: the python object is not a sequence " << std::endl;
868 msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
870 throw YACS::ENGINE::ConversionException(msg.str());
872 int length=PySequence_Size(o);
873 DEBTRACE("length: " << length );
875 for(int i=0;i<length;i++)
877 PyObject *item=PySequence_ITEM(o,i);
879 std::cerr <<"item[" << i << "]=";
880 PyObject_Print(item,stderr,Py_PRINT_RAW);
881 std::cerr << std::endl;
883 DEBTRACE( "item refcnt: " << item->ob_refcnt );
886 TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(t->contentType(),item,0);
890 catch(ConversionException& ex)
893 msg << ex.what() << " for sequence element " << i;
894 throw YACS::ENGINE::ConversionException(msg.str(),false);
899 template <ImplType IMPLOUT, class TOUT>
900 struct convertToYacsStruct<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
902 static inline void convert(const TypeCode *t,PyObject* o,void*,std::map<std::string,TOUT>& m)
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++)
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());
917 //member name not present
918 //TODO delete all allocated objects in m
920 PyObject_Print(o,stderr,Py_PRINT_RAW);
921 std::cerr << std::endl;
924 msg << "member " << name << " not present " ;
925 throw YACS::ENGINE::ConversionException(msg.str());
927 DEBTRACE( "value refcnt: " << value->ob_refcnt );
930 TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(tm,value,0);
933 catch(ConversionException& ex)
935 std::string s=" for struct member "+name;
936 throw YACS::ENGINE::ConversionException(ex.what()+s,false);
941 /* End of ToYacs Convertor for PYTHONImpl */
943 //! FromYacs Convertor for PYTHONImpl
945 * Convert YACS<PyObject*> intermediate types to PyObject* types (PYTHONImpl)
948 struct convertFromYacsDouble<PYTHONImpl,PyObject*>
950 static inline PyObject* convert(const TypeCode *t,double o)
952 PyObject *pyob=PyFloat_FromDouble(o);
957 struct convertFromYacsInt<PYTHONImpl,PyObject*>
959 static inline PyObject* convert(const TypeCode *t,long o)
961 PyObject *pyob=PyLong_FromLong(o);
966 struct convertFromYacsString<PYTHONImpl,PyObject*>
968 static inline PyObject* convert(const TypeCode *t,std::string& o)
970 return PyUnicode_FromString(o.c_str());
974 struct convertFromYacsBool<PYTHONImpl,PyObject*>
976 static inline PyObject* convert(const TypeCode *t,bool o)
978 return PyBool_FromLong ((long)o);
982 struct convertFromYacsObjref<PYTHONImpl,PyObject*>
984 static inline PyObject* convert(const TypeCode *t,std::string& o)
991 if(t->isA(Runtime::_tc_file))
993 //It's an objref file. Convert it specially
994 return PyUnicode_FromString(o.c_str());
996 if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0"
998 //It's a python pickled object, unpickled it
999 PyObject* mod=PyImport_ImportModule("pickle");
1000 PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length());
1001 DEBTRACE(PyObject_Repr(ob));
1006 throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
1010 if(strncmp(t->id(),"json",4)==0)
1012 // It's a json object unpack it
1013 PyObject* mod=PyImport_ImportModule("simplejson");
1017 throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
1019 PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y",o.c_str());
1024 throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
1029 /* another way to convert IOR string to CORBA PyObject
1030 PyObject* ob= PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"string_to_object","s",o.c_str());
1031 DEBTRACE( "Objref python refcnt: " << ob->ob_refcnt );
1035 //Objref CORBA. prefix=IOR,corbaname,corbaloc
1036 CORBA::Object_var obref;
1039 obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1041 DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1044 catch(CORBA::Exception& ex)
1046 DEBTRACE( "Can't get reference to object." );
1047 throw ConversionException("Can't get reference to object");
1050 if(obref->_non_existent())
1052 throw ConversionException("non_existent object");
1055 if( CORBA::is_nil(obref) )
1057 DEBTRACE( "Can't get reference to object (or it was nil)." );
1058 throw ConversionException("Can't get reference to object");
1061 if(!obref->_is_a(t->id()))
1064 msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1065 msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1066 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1067 throw YACS::ENGINE::ConversionException(msg.str());
1070 DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1073 std::cerr << "_PD_repoId: " << obref->_PD_repoId << std::endl;
1074 std::cerr << "_mostDerivedRepoId: " << obref->_PR_getobj()->_mostDerivedRepoId() << std::endl;
1077 //hold_lock is true: caller is supposed to hold the GIL.
1078 //omniorb will not take the GIL
1079 PyObject* ob= getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(obref, 1);
1082 PyObject_Print(ob,stderr,Py_PRINT_RAW);
1083 std::cerr << std::endl;
1084 std::cerr << "obref is a generic: " << obref->_is_a("IDL:SALOME/GenericObj:1.0") << std::endl;
1085 PyObject_Print(getSALOMERuntime()->get_omnipy(),stderr,Py_PRINT_RAW);
1086 std::cerr << std::endl;
1089 //ob is a CORBA::Object. Try to convert it to more specific type SALOME/GenericObj
1090 if(obref->_is_a("IDL:SALOME/GenericObj:1.0"))
1092 PyObject *result = PyObject_CallMethod(getSALOMERuntime()->get_omnipy(), (char *)"narrow", (char *)"Osi",ob,"IDL:SALOME/GenericObj:1.0",1);
1094 PyErr_Clear();//Exception during narrow. Keep ob
1095 else if(result==Py_None)
1096 Py_DECREF(result); //Can't narrow. Keep ob
1099 //Can narrow. Keep result
1101 PyObject_Print(result,stderr,Py_PRINT_RAW);
1102 std::cerr << std::endl;
1110 DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
1117 struct convertFromYacsSequence<PYTHONImpl,PyObject*>
1119 static inline PyObject* convert(const TypeCode *t,std::vector<PyObject*>& v)
1121 std::vector<PyObject*>::const_iterator iter;
1122 PyObject *pyob = PyList_New(v.size());
1124 for(iter=v.begin();iter!=v.end();iter++)
1126 PyObject* item=*iter;
1127 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1128 PyList_SetItem(pyob,i,item);
1129 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1136 struct convertFromYacsStruct<PYTHONImpl,PyObject*>
1138 static inline PyObject* convert(const TypeCode *t,std::map<std::string,PyObject*>& m)
1140 PyObject *pyob = PyDict_New();
1141 std::map<std::string, PyObject*>::const_iterator pt;
1142 for(pt=m.begin();pt!=m.end();pt++)
1144 std::string name=(*pt).first;
1145 PyObject* item=(*pt).second;
1146 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1147 PyDict_SetItemString(pyob,name.c_str(),item);
1149 DEBTRACE( "item refcnt: " << item->ob_refcnt );
1151 DEBTRACE( "pyob refcnt: " << pyob->ob_refcnt );
1155 /* End of FromYacs Convertor for PYTHONImpl */
1157 //! ToYacs Convertor for XMLImpl
1159 * Partial specialization for XML implementation (XMLImpl)
1160 * This convertor converts xml object to YACS<TOUT> types
1162 template <ImplType IMPLOUT, class TOUT>
1163 struct convertToYacsDouble<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1165 static inline double convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1168 cur = cur->xmlChildrenNode;
1171 if ((!xmlStrcmp(cur->name, (const xmlChar *)"double")))
1173 //wait a double, got a double
1175 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1178 DEBTRACE( "convertToYacsDouble " << (const char *)s );
1179 d=Cstr2d((const char *)s);
1184 DEBTRACE("############### workaround to improve...");
1188 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1190 //wait a double, got an int
1192 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1195 DEBTRACE( "convertToYacsDouble " << (const char *)s );
1196 d=Cstr2d((const char *)s);
1201 DEBTRACE("############### workaround to improve...");
1208 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1209 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1210 throw YACS::ENGINE::ConversionException(msg.str());
1213 template <ImplType IMPLOUT, class TOUT>
1214 struct convertToYacsInt<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1216 static inline long convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1219 cur = cur->xmlChildrenNode;
1222 if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
1225 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1228 DEBTRACE( "convertToYacsInt " << (const char *)s );
1229 d=atol((const char *)s);
1234 DEBTRACE("############### workaround to improve...");
1241 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1242 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1243 throw YACS::ENGINE::ConversionException(msg.str());
1246 template <ImplType IMPLOUT, class TOUT>
1247 struct convertToYacsString<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1249 static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1251 cur = cur->xmlChildrenNode;
1254 if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))
1256 //wait a string, got a string
1258 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1260 DEBTRACE( "convertToYacsString " << (const char *)s );
1261 std::string mystr=std::string((const char *)s);
1268 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1269 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1270 throw YACS::ENGINE::ConversionException(msg.str());
1273 template <ImplType IMPLOUT, class TOUT>
1274 struct convertToYacsBool<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1276 static inline bool convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
1278 cur = cur->xmlChildrenNode;
1281 if ((!xmlStrcmp(cur->name, (const xmlChar *)"boolean")))
1283 //wait a boolean, got a boolean
1285 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1289 DEBTRACE( "convertToYacsBool " << (const char *)s );
1290 ob=atoi((const char*)s)!=0;
1295 DEBTRACE("############### workaround to improve...");
1302 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1303 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1304 throw YACS::ENGINE::ConversionException(msg.str());
1307 template <ImplType IMPLOUT, class TOUT>
1308 struct convertToYacsObjref<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1310 static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,int protocol)
1312 cur = cur->xmlChildrenNode;
1315 if ((!xmlStrcmp(cur->name, (const xmlChar *)"objref")))
1317 //we wait a objref, we have got a objref
1319 std::string mystr = "";
1320 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1323 DEBTRACE( "convertToYacsObjref " << (const char *)s );
1324 mystr = (const char *)s;
1329 DEBTRACE("############### workaround to improve...");
1331 if(strncmp(t->id(),"python",6)==0 )
1332 return FromBase64Safe(mystr);
1336 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
1338 //wait a string, got a string
1340 s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
1342 DEBTRACE( "convertToYacsString " << (const char *)s );
1343 std::string mystr=std::string((const char *)s);
1350 msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ;
1351 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1352 throw YACS::ENGINE::ConversionException(msg.str());
1355 template <ImplType IMPLOUT, class TOUT>
1356 struct convertToYacsSequence<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1358 static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::vector<TOUT>& v)
1360 cur = cur->xmlChildrenNode;
1363 if ((!xmlStrcmp(cur->name, (const xmlChar *)"array")))
1365 DEBTRACE( "parse sequence " );
1366 xmlNodePtr cur1=cur->xmlChildrenNode;
1367 while (cur1 != NULL)
1369 if ((!xmlStrcmp(cur1->name, (const xmlChar *)"data")))
1371 DEBTRACE( "parse data " );
1372 xmlNodePtr cur2=cur1->xmlChildrenNode;
1373 while (cur2 != NULL)
1375 //collect all values
1376 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1378 TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(t->contentType(),doc,cur2);
1382 } // end while value
1390 } // end while array
1393 template <ImplType IMPLOUT, class TOUT>
1394 struct convertToYacsStruct<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
1396 static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::map<std::string,TOUT>& m)
1398 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1399 int nMember=tst->memberCount();
1400 DEBTRACE("nMember="<<nMember);
1401 std::map<std::string,TypeCode*> mtc;
1402 for(int i=0;i<nMember;i++)
1404 mtc[tst->memberName(i)]=tst->memberType(i);
1407 cur = cur->xmlChildrenNode;
1410 if ((!xmlStrcmp(cur->name, (const xmlChar *)"struct")))
1412 DEBTRACE( "parse struct " );
1413 xmlNodePtr cur1=cur->xmlChildrenNode;
1414 while (cur1 != NULL)
1416 if ((!xmlStrcmp(cur1->name, (const xmlChar *)"member")))
1418 DEBTRACE( "parse member " );
1419 xmlNodePtr cur2=cur1->xmlChildrenNode;
1420 while (cur2 != NULL)
1423 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"name")))
1426 s = xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
1427 std::string name= (char *)s;
1429 while (cur2 != NULL)
1431 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value")))
1433 TOUT ro=YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>(mtc[name],doc,cur2);
1443 } // end while member/value
1446 } // end while member
1450 } // end while struct
1453 /* End of ToYacs Convertor for XMLImpl */
1455 //! FromYacs Convertor for XMLImpl
1457 * Convert YACS<std::string> intermediate types to std::string types (XMLImpl)
1460 struct convertFromYacsDouble<XMLImpl,std::string>
1462 static inline std::string convert(const TypeCode *t,double o)
1465 msg << "<value><double>" << setprecision(16) << o << "</double></value>\n";
1470 struct convertFromYacsInt<XMLImpl,std::string>
1472 static inline std::string convert(const TypeCode *t,long o)
1475 msg << "<value><int>" << o << "</int></value>\n";
1480 struct convertFromYacsString<XMLImpl,std::string>
1482 static inline std::string convert(const TypeCode *t,std::string& o)
1484 std::string msg="<value><string>";
1485 return msg+o+"</string></value>\n";
1489 struct convertFromYacsBool<XMLImpl,std::string>
1491 static inline std::string convert(const TypeCode *t,bool o)
1494 msg << "<value><boolean>" << o << "</boolean></value>\n";
1499 struct convertFromYacsObjref<XMLImpl,std::string>
1501 static inline std::string convert(const TypeCode *t,std::string& o)
1503 if(strncmp(t->id(),"python",6)==0 )
1504 return "<value><objref><![CDATA[" + ToBase64(o) + "]]></objref></value>\n";
1505 else if(strncmp(t->id(),"json",4)==0)
1506 return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
1508 return "<value><objref>" + o + "</objref></value>\n";
1513 struct convertFromYacsSequence<XMLImpl,std::string>
1515 static inline std::string convert(const TypeCode *t,std::vector<std::string>& v)
1517 std::vector<std::string>::const_iterator iter;
1519 xmlob << "<value><array><data>\n";
1520 for(iter=v.begin();iter!=v.end();iter++)
1524 xmlob << "</data></array></value>\n";
1525 DEBTRACE("Sequence= " << xmlob);
1530 struct convertFromYacsStruct<XMLImpl,std::string>
1532 static inline std::string convert(const TypeCode *t,std::map<std::string,std::string>& m)
1534 std::string result="<value><struct>\n";
1535 std::map<std::string, std::string>::const_iterator pt;
1536 for(pt=m.begin();pt!=m.end();pt++)
1538 std::string name=(*pt).first;
1539 std::string item=(*pt).second;
1540 result=result+"<member>\n";
1541 result=result+"<name>"+name+"</name>\n";
1543 result=result+"</member>\n";
1545 result=result+"</struct></value>\n";
1550 /* End of FromYacs Convertor for XMLImpl */
1552 //! ToYacs Convertor for NEUTRALImpl
1554 * This convertor converts Neutral objects to intermediate YACS<TOUT> types
1555 * Template : Partial specialization for Neutral implementation with types YACS::ENGINE::Any*
1557 template <ImplType IMPLOUT, class TOUT>
1558 struct convertToYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1560 static inline double convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1562 if(o->getType()->kind()==Double)
1563 return o->getDoubleValue();
1564 else if(o->getType()->kind()==Int)
1565 return o->getIntValue();
1568 msg << "Problem in conversion: a double or int is expected " ;
1569 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1570 throw YACS::ENGINE::ConversionException(msg.str());
1573 template <ImplType IMPLOUT, class TOUT>
1574 struct convertToYacsInt<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1576 static inline long convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1578 if(o->getType()->kind()==Int)
1579 return o->getIntValue();
1581 msg << "Problem in conversion: a int is expected " ;
1582 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1583 throw YACS::ENGINE::ConversionException(msg.str());
1586 template <ImplType IMPLOUT, class TOUT>
1587 struct convertToYacsString<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1589 static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1591 if(o->getType()->kind()==String)
1592 return o->getStringValue();
1594 msg << "Problem in conversion: a string is expected " ;
1595 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1596 throw YACS::ENGINE::ConversionException(msg.str());
1599 template <ImplType IMPLOUT, class TOUT>
1600 struct convertToYacsBool<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1602 static inline bool convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
1604 if(o->getType()->kind()==Bool)
1605 return o->getBoolValue();
1606 else if(o->getType()->kind()==Int)
1607 return o->getIntValue() != 0;
1609 msg << "Problem in conversion: a bool or int is expected " ;
1610 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1611 throw YACS::ENGINE::ConversionException(msg.str());
1614 template <ImplType IMPLOUT, class TOUT>
1615 struct convertToYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1617 static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,int protocol)
1619 if(o->getType()->kind()==String || o->getType()->kind()==Objref)
1620 return o->getStringValue();
1622 msg << "Problem in conversion: a objref(string) is expected " ;
1623 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1624 throw YACS::ENGINE::ConversionException(msg.str());
1627 template <ImplType IMPLOUT, class TOUT>
1628 struct convertToYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1630 static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::vector<TOUT>& v)
1632 SequenceAny* sdata= (SequenceAny*)o;
1633 int length=sdata->size();
1635 for(int i=0;i<length;i++)
1637 TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(t->contentType(),(*sdata)[i],0);
1642 template <ImplType IMPLOUT, class TOUT>
1643 struct convertToYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
1645 static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::map<std::string,TOUT>& m)
1647 StructAny * sdata = dynamic_cast<StructAny *>(o);
1648 YASSERT(sdata != NULL);
1649 const TypeCodeStruct * tst = dynamic_cast<const TypeCodeStruct *>(t);
1650 YASSERT(tst != NULL);
1651 for (int i=0 ; i<tst->memberCount() ; i++)
1653 string name = tst->memberName(i);
1654 TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),(*sdata)[name.c_str()],0);
1659 /* End of ToYacs Convertor for NEUTRALImpl */
1661 //! FromYacs Convertor for NEUTRALImpl
1663 * Convert YACS<YACS::ENGINE::Any*> intermediate types to YACS::ENGINE::Any* types (NEUTRALImpl)
1666 struct convertFromYacsDouble<NEUTRALImpl,YACS::ENGINE::Any*>
1668 static inline YACS::ENGINE::Any* convert(const TypeCode *t,double o)
1670 YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(o);
1675 struct convertFromYacsInt<NEUTRALImpl,YACS::ENGINE::Any*>
1677 static inline YACS::ENGINE::Any* convert(const TypeCode *t,long o)
1679 return YACS::ENGINE::AtomAny::New((int)o);
1683 struct convertFromYacsString<NEUTRALImpl,YACS::ENGINE::Any*>
1685 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1687 return YACS::ENGINE::AtomAny::New(o);
1691 struct convertFromYacsBool<NEUTRALImpl,YACS::ENGINE::Any*>
1693 static inline YACS::ENGINE::Any* convert(const TypeCode *t,bool o)
1695 return YACS::ENGINE::AtomAny::New(o);
1699 struct convertFromYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*>
1701 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
1703 //Check if objref is a GenericObj and register it if it is the case (workaround for bad management of GenericObj)
1704 if(o=="" || (t->isA(Runtime::_tc_file)) || (strncmp(t->id(),"python",6)==0) || (strncmp(t->id(),"json",4)==0))
1705 return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1707 //Objref CORBA. prefix=IOR,corbaname,corbaloc
1708 CORBA::Object_var obref;
1711 obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
1713 catch(CORBA::Exception& ex)
1715 throw ConversionException("Can't get reference to object");
1717 if(obref->_non_existent())
1718 throw ConversionException("non_existent object");
1719 if( CORBA::is_nil(obref) )
1720 throw ConversionException("Can't get reference to object");
1721 if(!obref->_is_a(t->id()))
1724 msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
1725 msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
1726 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
1727 throw YACS::ENGINE::ConversionException(msg.str());
1730 SALOME::GenericObj_var gobj=SALOME::GenericObj::_narrow(obref);
1731 if(!CORBA::is_nil(gobj))
1733 DEBTRACE("It's a SALOME::GenericObj register it");
1737 DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
1739 return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
1744 struct convertFromYacsSequence<NEUTRALImpl,YACS::ENGINE::Any*>
1746 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::vector<YACS::ENGINE::Any*>& v)
1748 std::vector<YACS::ENGINE::Any*>::const_iterator iter;
1749 //Objref are managed as string within YACS::ENGINE::Any objs
1751 any=SequenceAny::New(t->contentType());
1752 for(iter=v.begin();iter!=v.end();iter++)
1754 any->pushBack(*iter);
1757 DEBTRACE( "refcnt: " << any->getRefCnt() );
1763 struct convertFromYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*>
1765 static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::map<std::string,YACS::ENGINE::Any*>& m)
1767 StructAny * any = StructAny::New((TypeCodeStruct *)t);
1768 std::map<std::string,YACS::ENGINE::Any*>::const_iterator it;
1769 for (it=m.begin() ; it!=m.end() ; it++)
1771 any->setEltAtRank(it->first.c_str(), it->second);
1772 it->second->decrRef();
1777 /* End of FromYacs Convertor for NEUTRALImpl */
1779 //! ToYacs Convertor for CORBAImpl
1781 * This convertor converts Corba objects to intermediate YACS<TOUT> types
1782 * Template : Partial specialization for CORBA implementation with types CORBA::Any*
1784 template <ImplType IMPLOUT, class TOUT>
1785 struct convertToYacsDouble<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1787 static inline double convert(const TypeCode *t,CORBA::Any* o,void*)
1789 CORBA::TypeCode_var tc = o->type();
1790 if (tc->equivalent(CORBA::_tc_double))
1796 if (tc->equivalent(CORBA::_tc_long))
1803 msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1804 msg << " : " << __FILE__ << ":" << __LINE__;
1805 throw YACS::ENGINE::ConversionException(msg.str());
1808 template <ImplType IMPLOUT, class TOUT>
1809 struct convertToYacsInt<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1811 static inline long convert(const TypeCode *t,CORBA::Any* o,void*)
1817 msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1818 msg << " : " << __FILE__ << ":" << __LINE__;
1819 throw YACS::ENGINE::ConversionException(msg.str());
1822 template <ImplType IMPLOUT, class TOUT>
1823 struct convertToYacsString<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1825 static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*)
1831 msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
1832 msg << " : " << __FILE__ << ":" << __LINE__;
1833 throw YACS::ENGINE::ConversionException(msg.str());
1836 template <ImplType IMPLOUT, class TOUT>
1837 struct convertToYacsBool<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1839 static inline bool convert(const TypeCode *t,CORBA::Any* o,void*)
1842 if(*o >>= CORBA::Any::to_boolean(b))
1845 msg << "Problem in Corba to TOUT conversion: kind= " << t->kind() ;
1846 msg << " : " << __FILE__ << ":" << __LINE__;
1847 throw YACS::ENGINE::ConversionException(msg.str());
1850 template <ImplType IMPLOUT, class TOUT>
1851 struct convertToYacsObjref<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1853 static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*,int protocol)
1855 char file[]="/tmp/XXXXXX";
1856 if(t->isA(Runtime::_tc_file))
1858 Engines::Salome_file_ptr sf;
1860 Salome_file_i* f=new Salome_file_i();
1862 f->setDistributedFile(file);
1868 else if(strncmp(t->id(),"python",6)==0)
1871 Engines::fileBlock * buffer;
1874 s=(const char*)buffer->get_buffer();
1878 std::string mystr(s,buffer->length());
1882 PyGILState_STATE gstate = PyGILState_Ensure();
1883 PyObject* mod=PyImport_ImportModule("pickle");
1884 PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",s,buffer->length());
1885 PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",ob,protocol);
1886 DEBTRACE(PyObject_Repr(pickled));
1887 std::string mystr=PyBytes_AsString(pickled);
1891 PyGILState_Release(gstate);
1896 msg << "Problem in CORBA (protocol python) to TOUT conversion: kind= " << t->kind() ;
1897 msg << " : " << __FILE__ << ":" << __LINE__;
1898 throw YACS::ENGINE::ConversionException(msg.str());
1900 else if(strncmp(t->id(),"json",4)==0)
1908 msg << "Problem in CORBA (protocol json) to TOUT conversion: kind= " << t->kind() ;
1909 msg << " : " << __FILE__ << ":" << __LINE__;
1910 throw YACS::ENGINE::ConversionException(msg.str());
1914 CORBA::Object_var ObjRef ;
1915 *o >>= CORBA::Any::to_object(ObjRef) ;
1916 CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef);
1917 return (char *)objref;
1921 template <ImplType IMPLOUT, class TOUT>
1922 struct convertToYacsSequence<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1924 static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::vector<TOUT>& v)
1926 CORBA::TypeCode_var tc=o->type();
1927 if (tc->kind() != CORBA::tk_sequence)
1930 msg << "Not a sequence corba type " << tc->kind();
1931 msg << " : " << __FILE__ << ":" << __LINE__;
1932 throw YACS::ENGINE::ConversionException(msg.str());
1934 DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1935 DynamicAny::DynSequence_ptr ds=DynamicAny::DynSequence::_narrow(dynany);
1936 CORBA::release(dynany);
1937 DynamicAny::AnySeq_var as=ds->get_elements();
1938 int len=as->length();
1940 for(int i=0;i<len;i++)
1943 DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1945 TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(t->contentType(),&as[i],0);
1950 for(int i=0;i<len;i++)
1953 DEBTRACE("refcount CORBA as[i]: " << ((omni::TypeCode_base*)as[i].pd_tc.in())->pd_ref_count);
1958 template <ImplType IMPLOUT, class TOUT>
1959 struct convertToYacsStruct<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
1961 static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::map<std::string,TOUT>& m)
1963 CORBA::TypeCode_var tc=o->type();
1964 DEBTRACE(tc->kind());
1965 if (tc->kind() != CORBA::tk_struct)
1968 msg << "Not a struct corba type " << tc->kind();
1969 msg << " : " << __FILE__ << ":" << __LINE__;
1970 throw YACS::ENGINE::ConversionException(msg.str());
1972 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
1973 DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o);
1974 DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(dynany);
1975 CORBA::release(dynany);
1976 DynamicAny::NameValuePairSeq_var as=ds->get_members();
1977 int len=as->length();
1978 for(int i=0;i<len;i++)
1980 std::string name=as[i].id.in();
1982 CORBA::Any value=as[i].value;
1984 DEBTRACE("refcount CORBA value: " << ((omni::TypeCode_base*)value.pd_tc.in())->pd_ref_count);
1986 TOUT ro=YacsConvertor<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),&value,0);
1993 /* End of ToYacs Convertor for CORBAImpl */
1995 //! FromYacs Convertor for CORBAImpl
1997 * Convert YACS<CORBA::Any*> intermediate types to CORBA::Any* types (CORBAImpl)
2000 struct convertFromYacsDouble<CORBAImpl,CORBA::Any*>
2002 static inline CORBA::Any* convert(const TypeCode *t,double o)
2004 CORBA::Any *any = new CORBA::Any();
2005 *any <<= (CORBA::Double)o;
2010 struct convertFromYacsInt<CORBAImpl,CORBA::Any*>
2012 static inline CORBA::Any* convert(const TypeCode *t,long o)
2014 CORBA::Any *any = new CORBA::Any();
2015 *any <<= (CORBA::Long)o;
2020 struct convertFromYacsString<CORBAImpl,CORBA::Any*>
2022 static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2024 CORBA::Any *any = new CORBA::Any();
2030 struct convertFromYacsBool<CORBAImpl,CORBA::Any*>
2032 static inline CORBA::Any* convert(const TypeCode *t,bool o)
2034 CORBA::Any *any = new CORBA::Any();
2035 *any <<= CORBA::Any::from_boolean(o);
2040 struct convertFromYacsObjref<CORBAImpl,CORBA::Any*>
2042 static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
2044 CORBA::Object_var obref;
2046 if(t->isA(Runtime::_tc_file))
2048 //It's an objref file. Convert it specially
2049 Salome_file_i* aSalome_file = new Salome_file_i();
2052 aSalome_file->setLocalFile(o.c_str());
2053 obref = aSalome_file->_this();
2054 aSalome_file->_remove_ref();
2056 catch (const SALOME::SALOME_Exception& e)
2059 msg << e.details.text;
2060 msg << " : " << __FILE__ << ":" << __LINE__;
2061 throw YACS::ENGINE::ConversionException(msg.str());
2064 else if(strncmp(t->id(),"python",6)==0 )
2066 CORBA::Any *any = new CORBA::Any();
2067 Engines::fileBlock * buffer=new Engines::fileBlock();
2068 buffer->length(o.length());
2069 CORBA::Octet *buf=buffer->get_buffer();
2070 memcpy(buf,o.c_str(),o.length());
2074 else if(strncmp(t->id(),"json",4)==0)
2076 CORBA::Any *any = new CORBA::Any();
2084 obref=getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
2086 catch(CORBA::Exception& ex)
2088 throw ConversionException("Can't get reference to object");
2090 if( CORBA::is_nil(obref) )
2092 throw ConversionException("Can't get reference to object");
2096 DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2098 CORBA::Any *any = new CORBA::Any();
2101 DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
2108 struct convertFromYacsSequence<CORBAImpl,CORBA::Any*>
2110 static inline CORBA::Any* convert(const TypeCode *t,std::vector<CORBA::Any*>& v)
2112 CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2113 std::vector<CORBA::Any*>::const_iterator iter;
2115 // Build an Any from vector v
2117 if(t->contentType()->kind() == Objref)
2120 CORBA::TypeCode_var tc=getCorbaTC(t);
2122 DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2123 DynamicAny::DynSequence_var ds = DynamicAny::DynSequence::_narrow(dynany);
2124 ds->set_length(v.size());
2126 for(iter=v.begin();iter!=v.end();iter++)
2128 DynamicAny::DynAny_var temp=ds->current_component();
2129 CORBA::Any* a=*iter;
2130 //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2133 CORBA::Object_var zzobj ;
2134 *a >>= CORBA::Any::to_object(zzobj) ;
2135 temp->insert_reference(zzobj);
2140 //delete intermediate any
2145 CORBA::Any *any=ds->to_any();
2151 struct convertFromYacsStruct<CORBAImpl,CORBA::Any*>
2153 static inline CORBA::Any* convert(const TypeCode *t,std::map<std::string,CORBA::Any*>& m)
2155 CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
2157 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2158 int nMember=tst->memberCount();
2159 DEBTRACE("nMember="<<nMember);
2161 CORBA::TypeCode_var tc=getCorbaTC(t);
2162 DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
2163 DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(dynany);
2165 for(int i=0;i<nMember;i++)
2167 DynamicAny::DynAny_var temp=ds->current_component();
2168 const char * name=tst->memberName(i);
2169 DEBTRACE("Member name="<<name);
2170 //do not test member presence : test has been done in ToYacs convertor
2171 CORBA::Any* a=m[name];
2172 //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
2173 CORBA::TypeCode_var atc = tc->member_type(i);
2174 if(atc->kind()==CORBA::tk_objref)
2176 //special treatment for objref
2177 CORBA::Object_var zzobj ;
2178 *a >>= CORBA::Any::to_object(zzobj) ;
2179 temp->insert_reference(zzobj);
2185 //delete intermediate any
2189 CORBA::Any *any=ds->to_any();
2195 /* End of FromYacs Convertor for CORBAImpl */
2197 /* Some shortcuts for CORBA to CORBA conversion */
2199 inline CORBA::Any* convertDouble<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2201 CORBA::TypeCode_var tc = o->type();
2202 if (tc->equivalent(CORBA::_tc_double))
2206 if (tc->equivalent(CORBA::_tc_long))
2210 CORBA::Any *any = new CORBA::Any();
2211 *any <<= (CORBA::Double)d;
2215 msg << "Not a double or long corba type " << tc->kind();
2216 msg << " : " << __FILE__ << ":" << __LINE__;
2217 throw YACS::ENGINE::ConversionException(msg.str());
2220 inline CORBA::Any* convertInt<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2225 inline CORBA::Any* convertString<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2230 inline CORBA::Any* convertBool<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2235 inline CORBA::Any* convertObjref<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2240 inline CORBA::Any* convertStruct<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(const TypeCode *t,CORBA::Any* o,void* aux)
2244 /* End of shortcuts for CORBA to CORBA conversion */
2246 //! ToYacs Convertor for CPPImpl
2248 * This convertor converts Python object to YACS<TOUT> types
2249 * Partial specialization for Python implementation with type PyObject* (PYTHONImpl)
2251 template <ImplType IMPLOUT, class TOUT>
2252 struct convertToYacsDouble<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2254 static inline double convert(const TypeCode *t,void* o,const TypeCode* intype)
2256 if(intype->kind()==YACS::ENGINE::Double)
2260 else if(intype->kind()==YACS::ENGINE::Int)
2265 msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2266 msg << " : " << __FILE__ << ":" << __LINE__;
2267 throw YACS::ENGINE::ConversionException(msg.str());
2270 template <ImplType IMPLOUT, class TOUT>
2271 struct convertToYacsInt<CPPImpl,void*,const TypeCode*,IMPLOUT,TOUT>
2273 static inline long convert(const TypeCode *t,void* o,const TypeCode* intype)
2275 if(intype->kind()==YACS::ENGINE::Int)
2280 msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ;
2281 msg << " : " << __FILE__ << ":" << __LINE__;
2282 throw YACS::ENGINE::ConversionException(msg.str());
2285 /* End of ToYacs Convertor for CPPImpl */
2287 //Python conversions
2288 std::string convertPyObjectXml(const TypeCode *t,PyObject *data)
2290 return YacsConvertor<PYTHONImpl,PyObject*,void*,XMLImpl,std::string>(t,data,0);
2292 YACS::ENGINE::Any* convertPyObjectNeutral(const TypeCode *t,PyObject *data)
2294 return YacsConvertor<PYTHONImpl,PyObject*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2296 CORBA::Any* convertPyObjectCorba(const TypeCode *t,PyObject *data)
2298 return YacsConvertor<PYTHONImpl,PyObject*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2300 PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *data)
2302 return YacsConvertor<PYTHONImpl,PyObject*,void*,PYTHONImpl,PyObject*>(t,data,0);
2305 std::string convertPyObjectToString(PyObject* ob)
2308 PyGILState_STATE gstate = PyGILState_Ensure();
2309 // TODO: separate treatment for string (maybe with bad encoding?) and other types of PyObject ?
2310 // Do we need str() or repr() and what are the possible causes of failure of str() ?
2311 // not clear, needs more analysis.
2313 if (s == NULL) // for instance string with bad encoding, non utf-8
2315 s=PyObject_ASCII(ob); // escape non ASCII characters and like repr(), which is not the same as str()...
2318 const char* characters = PyUnicode_AsUTF8AndSize(s, &size);
2319 std::string ss( characters, size);
2321 PyGILState_Release(gstate);
2326 PyObject* convertXmlPyObject(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2328 return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,PYTHONImpl,PyObject*>(t,doc,cur);
2330 YACS::ENGINE::Any* convertXmlNeutral(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2332 return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,NEUTRALImpl,YACS::ENGINE::Any*>(t,doc,cur);
2334 CORBA::Any* convertXmlCorba(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
2336 return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,CORBAImpl,CORBA::Any*>(t,doc,cur);
2338 PyObject* convertXmlStrPyObject(const TypeCode *t,std::string data)
2343 doc = xmlParseMemory(data.c_str(), strlen(data.c_str()));
2346 std::stringstream msg;
2347 msg << "Problem in conversion: XML Document not parsed successfully ";
2348 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2349 throw YACS::ENGINE::ConversionException(msg.str());
2351 cur = xmlDocGetRootElement(doc);
2355 std::stringstream msg;
2356 msg << "Problem in conversion: empty XML Document";
2357 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2358 throw YACS::ENGINE::ConversionException(msg.str());
2362 if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
2364 ob=convertXmlPyObject(t,doc,cur);
2372 std::stringstream msg;
2373 msg << "Problem in conversion: incorrect XML value";
2374 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
2375 throw YACS::ENGINE::ConversionException(msg.str());
2379 //NEUTRAL conversions
2380 PyObject* convertNeutralPyObject(const TypeCode *t,YACS::ENGINE::Any* data)
2382 return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2384 std::string convertNeutralXml(const TypeCode *t,YACS::ENGINE::Any* data)
2386 return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,XMLImpl,std::string>(t,data,0);
2388 CORBA::Any* convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any* data)
2390 return YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2392 YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* data)
2399 PyObject* convertCorbaPyObject(const TypeCode *t,CORBA::Any* data)
2401 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,PYTHONImpl,PyObject*>(t,data,0);
2403 std::string convertCorbaXml(const TypeCode *t,CORBA::Any* data)
2405 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,XMLImpl,std::string>(t,data,0);
2407 YACS::ENGINE::Any* convertCorbaNeutral(const TypeCode *t,CORBA::Any* data)
2409 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,NEUTRALImpl,YACS::ENGINE::Any*>(t,data,0);
2411 CORBA::Any *convertCorbaCorba(const TypeCode *t,CORBA::Any *data)
2413 return YacsConvertor<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
2416 //! Basic template checker from type TIN
2418 * This checker does nothing : throws exception
2419 * It must be partially specialize for a specific type (TIN)
2421 template <ImplType IMPLIN,class TIN,class TIN2>
2422 static inline bool checkDouble(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 checkInt(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 checkBool(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 checkString(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 checkObjref(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 checkSequence(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());
2469 template <ImplType IMPLIN,class TIN,class TIN2>
2470 static inline bool checkStruct(const TypeCode *t,TIN o,TIN2 aux)
2473 msg << "Check not implemented for Implementation: " << IMPLIN ;
2474 msg << " : " << __FILE__ << ":" << __LINE__;
2475 throw YACS::ENGINE::ConversionException(msg.str());
2477 template <ImplType IMPLIN,class TIN,class TIN2>
2478 static inline bool checkArray(const TypeCode *t,TIN o,TIN2 aux)
2481 msg << "Check not implemented for Implementation: " << IMPLIN ;
2482 msg << " : " << __FILE__ << ":" << __LINE__;
2483 throw YACS::ENGINE::ConversionException(msg.str());
2486 template <ImplType IMPLIN,class TIN,class TIN2>
2487 inline bool YacsChecker(const TypeCode *t,TIN o,TIN2 aux)
2493 return checkDouble<IMPLIN,TIN,TIN2>(t,o,aux);
2495 return checkInt<IMPLIN,TIN,TIN2>(t,o,aux);
2497 return checkString<IMPLIN,TIN,TIN2>(t,o,aux);
2499 return checkBool<IMPLIN,TIN,TIN2>(t,o,aux);
2501 return checkObjref<IMPLIN,TIN,TIN2>(t,o,aux);
2503 return checkSequence<IMPLIN,TIN,TIN2>(t,o,aux);
2505 return checkArray<IMPLIN,TIN,TIN2>(t,o,aux);
2507 return checkStruct<IMPLIN,TIN,TIN2>(t,o,aux);
2512 msg << "Check not implemented for kind= " << tk ;
2513 msg << " : " << __FILE__ << ":" << __LINE__;
2514 throw YACS::ENGINE::ConversionException(msg.str());
2517 inline bool checkDouble<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2519 if (PyFloat_Check(o))
2521 else if(PyLong_Check(o))
2526 msg << "Not a python double ";
2527 throw YACS::ENGINE::ConversionException(msg.str());
2531 inline bool checkInt<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2533 if (PyLong_Check(o))
2538 msg << "Not a python integer ";
2539 throw YACS::ENGINE::ConversionException(msg.str());
2543 inline bool checkBool<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2545 if (PyBool_Check(o))
2547 else if(PyLong_Check(o))
2552 msg << "Not a python boolean " ;
2553 throw YACS::ENGINE::ConversionException(msg.str());
2558 inline bool checkString<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2560 if (PyUnicode_Check(o))
2565 msg << "Not a python string " ;
2566 throw YACS::ENGINE::ConversionException(msg.str());
2570 inline bool checkObjref<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2572 if (PyUnicode_Check(o))
2574 if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true)
2576 else if(strncmp(t->id(),"json",4)==0) // The python object must be json pickable
2578 // The python object should be json compliant (to improve)
2583 // The python object should be a CORBA obj (to improve)
2588 inline bool checkSequence<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2590 if(!PySequence_Check(o))
2593 msg << "python object is not a sequence " ;
2594 throw YACS::ENGINE::ConversionException(msg.str());
2596 int length=PySequence_Size(o);
2597 for(int i=0;i<length;i++)
2599 PyObject *item=PySequence_ITEM(o,i);
2602 YacsChecker<PYTHONImpl,PyObject*,void*>(t->contentType(),item,0);
2604 catch(ConversionException& ex)
2607 msg << ex.what() << " for sequence element " << i;
2608 throw YACS::ENGINE::ConversionException(msg.str(),false);
2615 inline bool checkStruct<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
2618 if(!PyDict_Check(o))
2621 msg << "python object is not a dict " ;
2622 throw YACS::ENGINE::ConversionException(msg.str());
2624 YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
2625 int nMember=tst->memberCount();
2626 for(int i=0;i<nMember;i++)
2628 std::string name=tst->memberName(i);
2629 TypeCode* tm=tst->memberType(i);
2630 value=PyDict_GetItemString(o, name.c_str());
2634 msg << "member " << name << " not present " ;
2635 throw YACS::ENGINE::ConversionException(msg.str());
2639 YacsChecker<PYTHONImpl,PyObject*,void*>(tm,value,0);
2641 catch(ConversionException& ex)
2643 std::string s=" for struct member "+name;
2644 throw YACS::ENGINE::ConversionException(ex.what()+s,false);
2650 bool checkPyObject(const TypeCode *t,PyObject* ob)
2652 return YacsChecker<PYTHONImpl,PyObject*,void*>(t,ob,0);