X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2FTypeConversions.cxx;h=f75e20abf45c4bb71a8e53241a6e760b8cdf2510;hb=5233153d20a18e4a7cc1fab659f9cfc58ebb3154;hp=c51ca9ae26d1d3429933b4361e26ee94beae11a2;hpb=a84e60a749da66dffb73297fa5082b70b9d62f7d;p=modules%2Fyacs.git diff --git a/src/runtime/TypeConversions.cxx b/src/runtime/TypeConversions.cxx index c51ca9ae2..f75e20abf 100644 --- a/src/runtime/TypeConversions.cxx +++ b/src/runtime/TypeConversions.cxx @@ -1,5 +1,24 @@ +// Copyright (C) 2006-2019 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// //#define REFCNT +// #ifdef REFCNT #define private public #define protected public @@ -10,12 +29,27 @@ #include "TypeConversions.hxx" #include "ConversionException.hxx" #include "RuntimeSALOME.hxx" +#include "Salome_file_i.hxx" #include "TypeCode.hxx" #include "Cstr2d.hxx" +#include "SALOME_GenericObj.hh" #include +#include #include +#ifdef WIN32 +#include +#define _S_IREAD 256 +#define _S_IWRITE 128 +int mkstemp(char *tmpl) +{ + int ret=-1; + mktemp(tmpl); ret=open(tmpl,O_RDWR|O_BINARY|O_CREAT|O_EXCL|_O_SHORT_LIVED, _S_IREAD|_S_IWRITE); + return ret; +} +#endif + //#define _DEVDEBUG_ #include "YacsTrace.hxx" @@ -25,6 +59,40 @@ namespace YACS { namespace ENGINE { + void printbin(const std::string& bin) + { + register char c; + for(int i=0;i= 0x7f) + { + fprintf(stderr,"\\x%02x",c & 0xff); + } + else + fprintf(stderr,"%c",c); + } + fprintf(stderr,"\n"); + } + + std::string getImplName(ImplType impl) + { + switch(impl) + { + case CORBAImpl: + return "CORBA"; + case PYTHONImpl: + return "PYTHON"; + case NEUTRALImpl: + return "NEUTRAL"; + case XMLImpl: + return "XML"; + case CPPImpl: + return "CPP"; + default: + return "UNKNOWN"; + } + } /* * Functions to return a CORBA TypeCode equivalent to a YACS TypeCode */ @@ -61,8 +129,14 @@ namespace YACS CORBA::TypeCode_ptr getCorbaTCObjref(const TypeCode *t) { - DEBTRACE( t->name() << " " << t->shortName()); - CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName()); + DEBTRACE( t->name() << " " << t->shortName() << " " << t->id()); + CORBA::TypeCode_ptr tc; + if(strncmp(t->id(),"python",6)==0 ) + tc= CORBA::TypeCode::_duplicate(Engines::_tc_fileBlock); + else if(strncmp(t->id(),"json",4)==0) + tc= CORBA::TypeCode::_duplicate(CORBA::_tc_string); + else + tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName()); #ifdef REFCNT DEBTRACE("refcount CORBA tc Objref: " << ((omni::TypeCode_base*)tc)->pd_ref_count); #endif @@ -183,6 +257,17 @@ namespace YACS if( t1->isA(t2->id()) ) return 1; } + else if(t1->kind() == Sequence) + { + const TypeCodeSeq *t1c(dynamic_cast(t1)); + if(!t1c) + return 0; + const TypeCode *t1cc(t1c->contentType()); + if(t1cc==t2) + return 1; + if(t1cc->kind() == Objref && std::string(t1cc->id())==std::string(t2->id())) + return 1; + } return 0; } }; @@ -216,7 +301,7 @@ namespace YACS { if(t1->kind() == Struct) { - if( t1->isA(t2->id()) ) + if( t1->isA(t2) ) return 1; } return 0; @@ -363,7 +448,7 @@ namespace YACS template struct convertToYacsObjref { - static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux) + static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux,int protocol) { stringstream msg; msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; @@ -532,7 +617,12 @@ namespace YACS template inline TOUT convertObjref(const TypeCode *t,TIN o,TIN2 aux) { - std::string d=convertToYacsObjref::convert(t,o,aux); + int protocol=-1; + if(IMPLOUT==XMLImpl) + protocol=0;//to avoid presence of \0 into XML generated file + if(IMPLOUT==NEUTRALImpl) + protocol=4; + std::string d=convertToYacsObjref::convert(t,o,aux,protocol); DEBTRACE( d ); TOUT r=convertFromYacsObjref::convert(t,d); return r; @@ -607,15 +697,16 @@ namespace YACS double x; if (PyFloat_Check(o)) x=PyFloat_AS_DOUBLE(o); - else if (PyInt_Check(o)) - x=PyInt_AS_LONG(o); else if(PyLong_Check(o)) x=PyLong_AsLong(o); else { stringstream msg; - msg << "Not a python double. kind=" << t->kind() ; + msg << "Not a python double. "; +#ifdef _DEVDEBUG_ + msg << "kind=" << t->kind() ; msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; +#endif throw YACS::ENGINE::ConversionException(msg.str()); } return x; @@ -627,15 +718,16 @@ namespace YACS static inline long convert(const TypeCode *t,PyObject* o,void*) { long l; - if (PyInt_Check(o)) - l=PyInt_AS_LONG(o); - else if(PyLong_Check(o)) + if(PyLong_Check(o)) l=PyLong_AsLong(o); else { stringstream msg; - msg << "Not a python integer. kind=" << t->kind() ; + msg << "Not a python integer. "; +#ifdef _DEVDEBUG_ + msg << "kind=" << t->kind() ; msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; +#endif throw YACS::ENGINE::ConversionException(msg.str()); } return l; @@ -646,15 +738,26 @@ namespace YACS { static inline std::string convert(const TypeCode *t,PyObject* o,void*) { - if (PyString_Check(o)) - return PyString_AS_STRING(o); + std::string s; + if (PyUnicode_Check(o)) + { + Py_ssize_t size; + const char *ptr = PyUnicode_AsUTF8AndSize(o, &size); + if (!ptr) + throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed"); + s.assign(ptr, size); + } else { stringstream msg; - msg << "Not a python string. kind=" << t->kind() ; + msg << "Not a python string. "; +#ifdef _DEVDEBUG_ + msg << "kind=" << t->kind() ; msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; +#endif throw YACS::ENGINE::ConversionException(msg.str()); } + return s; } }; template @@ -665,15 +768,16 @@ namespace YACS bool l; if (PyBool_Check(o)) l=(o==Py_True); - else if (PyInt_Check(o)) - l=(PyInt_AS_LONG(o)!=0); else if(PyLong_Check(o)) l=(PyLong_AsLong(o)!=0); else { stringstream msg; - msg << "Problem in Python to xml conversion: kind= " << t->kind() ; - msg << " : " << __FILE__ << ":" << __LINE__; + msg << "Not a python boolean. "; +#ifdef _DEVDEBUG_ + msg << "kind=" << t->kind() ; + msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; +#endif throw YACS::ENGINE::ConversionException(msg.str()); } return l; @@ -682,17 +786,73 @@ namespace YACS template struct convertToYacsObjref { - static inline std::string convert(const TypeCode *t,PyObject* o,void*) + static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol) { - if (PyString_Check(o)) + if (PyUnicode_Check(o) && strncmp(t->id(),"python",6)!=0) { // the objref is used by Python as a string (prefix:value) keep it as a string - return PyString_AS_STRING(o); + Py_ssize_t size; + std::string s; + const char *ptr = PyUnicode_AsUTF8AndSize(o, &size); + if (!ptr) + throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed"); + s.assign(ptr, size); + return s; + } + if(strncmp(t->id(),"python",6)==0) + { + // It's a native Python object pickle it + PyObject* mod=PyImport_ImportModule("pickle"); + PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol); + DEBTRACE(PyObject_Repr(pickled) ); + Py_DECREF(mod); + if(pickled==NULL) + { + PyErr_Print(); + throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjrefid(),"json",4)==0) + { + // It's a Python object convert it to json + PyObject* mod=PyImport_ImportModule("simplejson"); + if(mod==NULL) + { + PyErr_Print(); + throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjrefgetPyOrb(),(char *)"object_to_string",(char *)"O",o); + if(pystring==NULL) + { + PyErr_Print(); + throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjrefgetPyOrb(),"object_to_string","O",o); - std::string mystr=PyString_AsString(pystring); - Py_DECREF(pystring); - return mystr; } }; template @@ -700,6 +860,15 @@ namespace YACS { static inline void convert(const TypeCode *t,PyObject* o,void*,std::vector& v) { + if(!PySequence_Check(o)) + { + stringstream msg; + msg << "Problem in conversion: the python object is not a sequence " << std::endl; +#ifdef _DEVDEBUG_ + msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; +#endif + throw YACS::ENGINE::ConversionException(msg.str()); + } int length=PySequence_Size(o); DEBTRACE("length: " << length ); v.resize(length); @@ -712,9 +881,18 @@ namespace YACS std::cerr << std::endl; #endif DEBTRACE( "item refcnt: " << item->ob_refcnt ); - TOUT ro=YacsConvertor(t->contentType(),item,0); - v[i]=ro; - Py_DECREF(item); + try + { + TOUT ro=YacsConvertor(t->contentType(),item,0); + v[i]=ro; + Py_DECREF(item); + } + catch(ConversionException& ex) + { + stringstream msg; + msg << ex.what() << " for sequence element " << i; + throw YACS::ENGINE::ConversionException(msg.str(),false); + } } } }; @@ -743,13 +921,20 @@ namespace YACS std::cerr << std::endl; #endif stringstream msg; - msg << "Problem in conversion: member " << name << " not present " << endl; - msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + msg << "member " << name << " not present " ; throw YACS::ENGINE::ConversionException(msg.str()); } DEBTRACE( "value refcnt: " << value->ob_refcnt ); - TOUT ro=YacsConvertor(tm,value,0); - m[name]=ro; + try + { + TOUT ro=YacsConvertor(tm,value,0); + m[name]=ro; + } + catch(ConversionException& ex) + { + std::string s=" for struct member "+name; + throw YACS::ENGINE::ConversionException(ex.what()+s,false); + } } } }; @@ -782,7 +967,7 @@ namespace YACS { static inline PyObject* convert(const TypeCode *t,std::string& o) { - return PyString_FromString(o.c_str()); + return PyUnicode_FromString(o.c_str()); } }; template <> @@ -798,15 +983,50 @@ namespace YACS { static inline PyObject* convert(const TypeCode *t,std::string& o) { - std::string::size_type pos=o.find_first_of(":"); - std::string prefix=o.substr(0,pos); - DEBTRACE(prefix); - if(prefix == "file") + if(o=="") + { + Py_INCREF(Py_None); + return Py_None; + } + if(t->isA(Runtime::_tc_file)) { //It's an objref file. Convert it specially - return PyString_FromString(o.c_str()); + return PyUnicode_FromString(o.c_str()); + } + if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0" + { + //It's a python pickled object, unpickled it + PyObject* mod=PyImport_ImportModule("pickle"); + PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length()); + DEBTRACE(PyObject_Repr(ob)); + Py_DECREF(mod); + if(ob==NULL) + { + PyErr_Print(); + throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjrefid(),"json",4)==0) + { + // It's a json object unpack it + PyObject* mod=PyImport_ImportModule("simplejson"); + if(mod==NULL) + { + PyErr_Print(); + throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjrefgetPyOrb(),"string_to_object","s",o.c_str()); DEBTRACE( "Objref python refcnt: " << ob->ob_refcnt ); return ob; @@ -827,6 +1047,11 @@ namespace YACS throw ConversionException("Can't get reference to object"); } + if(obref->_non_existent()) + { + throw ConversionException("non_existent object"); + } + if( CORBA::is_nil(obref) ) { DEBTRACE( "Can't get reference to object (or it was nil)." ); @@ -841,12 +1066,46 @@ namespace YACS msg << " (" << __FILE__ << ":" << __LINE__ << ")"; throw YACS::ENGINE::ConversionException(msg.str()); } - //hold_lock is true: caller is supposed to hold the GIL. - //omniorb will not take the GIL #ifdef REFCNT DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount); #endif +#ifdef _DEVDEBUG_ + std::cerr << "_PD_repoId: " << obref->_PD_repoId << std::endl; + std::cerr << "_mostDerivedRepoId: " << obref->_PR_getobj()->_mostDerivedRepoId() << std::endl; +#endif + + //hold_lock is true: caller is supposed to hold the GIL. + //omniorb will not take the GIL PyObject* ob= getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(obref, 1); + +#ifdef _DEVDEBUG_ + PyObject_Print(ob,stderr,Py_PRINT_RAW); + std::cerr << std::endl; + std::cerr << "obref is a generic: " << obref->_is_a("IDL:SALOME/GenericObj:1.0") << std::endl; + PyObject_Print(getSALOMERuntime()->get_omnipy(),stderr,Py_PRINT_RAW); + std::cerr << std::endl; +#endif + + //ob is a CORBA::Object. Try to convert it to more specific type SALOME/GenericObj + if(obref->_is_a("IDL:SALOME/GenericObj:1.0")) + { + PyObject *result = PyObject_CallMethod(getSALOMERuntime()->get_omnipy(), (char *)"narrow", (char *)"Osi",ob,"IDL:SALOME/GenericObj:1.0",1); + if(result==NULL) + PyErr_Clear();//Exception during narrow. Keep ob + else if(result==Py_None) + Py_DECREF(result); //Can't narrow. Keep ob + else + { + //Can narrow. Keep result +#ifdef _DEVDEBUG_ + PyObject_Print(result,stderr,Py_PRINT_RAW); + std::cerr << std::endl; +#endif + Py_DECREF(ob); + ob=result; + } + } + #ifdef REFCNT DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount); #endif @@ -905,7 +1164,7 @@ namespace YACS { static inline double convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) { - double d; + double d=0; cur = cur->xmlChildrenNode; while (cur != NULL) { @@ -914,9 +1173,16 @@ namespace YACS //wait a double, got a double xmlChar * s = NULL; s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - DEBTRACE( "convertToYacsDouble " << (const char *)s ); - d=Cstr2d((const char *)s); - xmlFree(s); + if (s) + { + DEBTRACE( "convertToYacsDouble " << (const char *)s ); + d=Cstr2d((const char *)s); + xmlFree(s); + } + else + { + DEBTRACE("############### workaround to improve..."); + } return d; } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int"))) @@ -924,16 +1190,23 @@ namespace YACS //wait a double, got an int xmlChar * s = NULL; s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - DEBTRACE( "convertToYacsDouble " << (const char *)s ); - d=Cstr2d((const char *)s); - xmlFree(s); + if (s) + { + DEBTRACE( "convertToYacsDouble " << (const char *)s ); + d=Cstr2d((const char *)s); + xmlFree(s); + } + else + { + DEBTRACE("############### workaround to improve..."); + } return d; } cur = cur->next; } stringstream msg; - msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; - msg << " : " << __FILE__ << ":" << __LINE__; + msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; throw YACS::ENGINE::ConversionException(msg.str()); } }; @@ -942,25 +1215,31 @@ namespace YACS { static inline long convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) { - long d; + long d=0; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"int"))) { - //wait a double, got an int xmlChar * s = NULL; s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - DEBTRACE( "convertToYacsInt " << (const char *)s ); - d=atol((const char *)s); - xmlFree(s); + if (s) + { + DEBTRACE( "convertToYacsInt " << (const char *)s ); + d=atol((const char *)s); + xmlFree(s); + } + else + { + DEBTRACE("############### workaround to improve..."); + } return d; } cur = cur->next; } stringstream msg; - msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; - msg << " : " << __FILE__ << ":" << __LINE__; + msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; throw YACS::ENGINE::ConversionException(msg.str()); } }; @@ -986,8 +1265,8 @@ namespace YACS cur = cur->next; } stringstream msg; - msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; - msg << " : " << __FILE__ << ":" << __LINE__; + msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; throw YACS::ENGINE::ConversionException(msg.str()); } }; @@ -1004,23 +1283,31 @@ namespace YACS //wait a boolean, got a boolean xmlChar * s = NULL; s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - DEBTRACE( "convertToYacsBool " << (const char *)s ); - bool ob=atoi((const char*)s)!=0; - xmlFree(s); + bool ob =false; + if (s) + { + DEBTRACE( "convertToYacsBool " << (const char *)s ); + ob=atoi((const char*)s)!=0; + xmlFree(s); + } + else + { + DEBTRACE("############### workaround to improve..."); + } return ob; } cur = cur->next; } stringstream msg; - msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; - msg << " : " << __FILE__ << ":" << __LINE__; + msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; throw YACS::ENGINE::ConversionException(msg.str()); } }; template struct convertToYacsObjref { - static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,int protocol) { cur = cur->xmlChildrenNode; while (cur != NULL) @@ -1029,16 +1316,38 @@ namespace YACS { //we wait a objref, we have got a objref xmlChar * s = NULL; + std::string mystr = ""; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + if (s) + { + DEBTRACE( "convertToYacsObjref " << (const char *)s ); + mystr = (const char *)s; + xmlFree(s); + } + else + { + DEBTRACE("############### workaround to improve..."); + } + if(strncmp(t->id(),"python",6)==0 ) + return FromBase64Safe(mystr); + else + return mystr; + } + 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 + { + //wait a string, got a string + xmlChar * s = NULL; s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - DEBTRACE( "convertToYacsObjref " << (const char *)s ); - std::string mystr((const char *)s); + if(s==0)return ""; + DEBTRACE( "convertToYacsString " << (const char *)s ); + std::string mystr=std::string((const char *)s); xmlFree(s); return mystr; } cur = cur->next; } stringstream msg; - msg << "Problem in conversion: a objref is expected " ; + msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type: " << t->id() ; msg << " (" << __FILE__ << ":" << __LINE__ << ")"; throw YACS::ENGINE::ConversionException(msg.str()); } @@ -1153,7 +1462,7 @@ namespace YACS static inline std::string convert(const TypeCode *t,double o) { stringstream msg ; - msg << "" << o << "\n"; + msg << "" << setprecision(16) << o << "\n"; return msg.str(); } }; @@ -1191,7 +1500,12 @@ namespace YACS { static inline std::string convert(const TypeCode *t,std::string& o) { - return "" + o + "\n"; + if(strncmp(t->id(),"python",6)==0 ) + return "\n"; + else if(strncmp(t->id(),"json",4)==0) + return "\n"; + else + return "" + o + "\n"; } }; @@ -1261,7 +1575,12 @@ namespace YACS { static inline long convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) { - return o->getIntValue(); + if(o->getType()->kind()==Int) + return o->getIntValue(); + stringstream msg; + msg << "Problem in conversion: a int is expected " ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); } }; template @@ -1269,7 +1588,12 @@ namespace YACS { static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) { - return o->getStringValue(); + if(o->getType()->kind()==String) + return o->getStringValue(); + stringstream msg; + msg << "Problem in conversion: a string is expected " ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); } }; template @@ -1284,14 +1608,20 @@ namespace YACS stringstream msg; msg << "Problem in conversion: a bool or int is expected " ; msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); } }; template struct convertToYacsObjref { - static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) + static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,int protocol) { - return o->getStringValue(); + if(o->getType()->kind()==String || o->getType()->kind()==Objref) + return o->getStringValue(); + stringstream msg; + msg << "Problem in conversion: a objref(string) is expected " ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); } }; template @@ -1309,6 +1639,23 @@ namespace YACS } } }; + template + struct convertToYacsStruct + { + static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::map& m) + { + StructAny * sdata = dynamic_cast(o); + YASSERT(sdata != NULL); + const TypeCodeStruct * tst = dynamic_cast(t); + YASSERT(tst != NULL); + for (int i=0 ; imemberCount() ; i++) + { + string name = tst->memberName(i); + TOUT ro=YacsConvertor(tst->memberType(i),(*sdata)[name.c_str()],0); + m[name]=ro; + } + } + }; /* End of ToYacs Convertor for NEUTRALImpl */ //! FromYacs Convertor for NEUTRALImpl @@ -1353,7 +1700,43 @@ namespace YACS { static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o) { - return YACS::ENGINE::AtomAny::New(o); + //Check if objref is a GenericObj and register it if it is the case (workaround for bad management of GenericObj) + if(o=="" || (t->isA(Runtime::_tc_file)) || (strncmp(t->id(),"python",6)==0) || (strncmp(t->id(),"json",4)==0)) + return YACS::ENGINE::AtomAny::New(o, const_cast(t)); + + //Objref CORBA. prefix=IOR,corbaname,corbaloc + CORBA::Object_var obref; + try + { + obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str()); + } + catch(CORBA::Exception& ex) + { + throw ConversionException("Can't get reference to object"); + } + if(obref->_non_existent()) + throw ConversionException("non_existent object"); + if( CORBA::is_nil(obref) ) + throw ConversionException("Can't get reference to object"); + if(!obref->_is_a(t->id())) + { + stringstream msg; + msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl; + msg << "An objref of type " << obref->_PD_repoId << " is given " << endl; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + + SALOME::GenericObj_var gobj=SALOME::GenericObj::_narrow(obref); + if(!CORBA::is_nil(gobj)) + { + DEBTRACE("It's a SALOME::GenericObj register it"); + gobj->Register(); + } + else + DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj"); + + return YACS::ENGINE::AtomAny::New(o, const_cast(t)); } }; @@ -1375,6 +1758,22 @@ namespace YACS return any; } }; + + template <> + struct convertFromYacsStruct + { + static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::map& m) + { + StructAny * any = StructAny::New((TypeCodeStruct *)t); + std::map::const_iterator it; + for (it=m.begin() ; it!=m.end() ; it++) + { + any->setEltAtRank(it->first.c_str(), it->second); + it->second->decrRef(); + } + return any; + } + }; /* End of FromYacs Convertor for NEUTRALImpl */ //! ToYacs Convertor for CORBAImpl @@ -1412,8 +1811,12 @@ namespace YACS static inline long convert(const TypeCode *t,CORBA::Any* o,void*) { CORBA::Long d; - *o >>= d; - return d; + if(*o >>= d) + return d; + stringstream msg; + msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); } }; template @@ -1422,8 +1825,12 @@ namespace YACS static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*) { const char *s; - *o >>=s; - return s; + if(*o >>=s) + return s; + stringstream msg; + msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); } }; template @@ -1443,12 +1850,72 @@ namespace YACS template struct convertToYacsObjref { - static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*) + static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*,int protocol) { - CORBA::Object_var ObjRef ; - *o >>= (CORBA::Any::to_object ) ObjRef ; - CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef); - return (char *)objref; + char file[]="/tmp/XXXXXX"; + if(t->isA(Runtime::_tc_file)) + { + Engines::Salome_file_ptr sf; + *o >>= sf; + Salome_file_i* f=new Salome_file_i(); + mkstemp(file); + f->setDistributedFile(file); + f->connect(sf); + f->recvFiles(); + delete f; + return file; + } + else if(strncmp(t->id(),"python",6)==0) + { + const char *s; + Engines::fileBlock * buffer; + if(*o >>=buffer) + { + s=(const char*)buffer->get_buffer(); + + if(protocol !=4) + { + std::string mystr(s,buffer->length()); + return mystr; + } + + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* mod=PyImport_ImportModule("pickle"); + PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",s,buffer->length()); + PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",ob,protocol); + DEBTRACE(PyObject_Repr(pickled)); + std::string mystr=PyBytes_AsString(pickled); + Py_DECREF(mod); + Py_DECREF(ob); + Py_DECREF(pickled); + PyGILState_Release(gstate); + + return mystr; + } + stringstream msg; + msg << "Problem in CORBA (protocol python) to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + else if(strncmp(t->id(),"json",4)==0) + { + const char *s; + if(*o >>=s) + { + return s; + } + stringstream msg; + msg << "Problem in CORBA (protocol json) to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + else + { + CORBA::Object_var ObjRef ; + *o >>= CORBA::Any::to_object(ObjRef) ; + CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef); + return (char *)objref; + } } }; template @@ -1535,7 +2002,7 @@ namespace YACS static inline CORBA::Any* convert(const TypeCode *t,double o) { CORBA::Any *any = new CORBA::Any(); - *any <<= o; + *any <<= (CORBA::Double)o; return any; } }; @@ -1545,7 +2012,7 @@ namespace YACS static inline CORBA::Any* convert(const TypeCode *t,long o) { CORBA::Any *any = new CORBA::Any(); - *any <<= o; + *any <<= (CORBA::Long)o; return any; } }; @@ -1574,17 +2041,57 @@ namespace YACS { static inline CORBA::Any* convert(const TypeCode *t,std::string& o) { - /* - std::string::size_type pos=o.find_first_of(":"); - std::string prefix=o.substr(0,pos); - DEBTRACE(prefix); - if(prefix == "file") + CORBA::Object_var obref; + + if(t->isA(Runtime::_tc_file)) { //It's an objref file. Convert it specially + Salome_file_i* aSalome_file = new Salome_file_i(); + try + { + aSalome_file->setLocalFile(o.c_str()); + obref = aSalome_file->_this(); + aSalome_file->_remove_ref(); + } + catch (const SALOME::SALOME_Exception& e) + { + stringstream msg; + msg << e.details.text; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + } + else if(strncmp(t->id(),"python",6)==0 ) + { + CORBA::Any *any = new CORBA::Any(); + Engines::fileBlock * buffer=new Engines::fileBlock(); + buffer->length(o.length()); + CORBA::Octet *buf=buffer->get_buffer(); + memcpy(buf,o.c_str(),o.length()); + *any <<= buffer; + return any; + } + else if(strncmp(t->id(),"json",4)==0) + { + CORBA::Any *any = new CORBA::Any(); + *any <<= o.c_str(); + return any; + } + else + { + try + { + obref=getSALOMERuntime()->getOrb()->string_to_object(o.c_str()); + } + catch(CORBA::Exception& ex) + { + throw ConversionException("Can't get reference to object"); + } + if( CORBA::is_nil(obref) ) + { + throw ConversionException("Can't get reference to object"); + } } - */ - CORBA::Object_var obref = - getSALOMERuntime()->getOrb()->string_to_object(o.c_str()); #ifdef REFCNT DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount); #endif @@ -1602,52 +2109,41 @@ namespace YACS { static inline CORBA::Any* convert(const TypeCode *t,std::vector& v) { - CORBA::Any *any; - CORBA::TypeCode_ptr seqTC; + CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb(); + std::vector::const_iterator iter; - //the equivalent CORBA TypeCode - seqTC=getCorbaTC(t); -#ifdef REFCNT - DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)seqTC)->pd_ref_count); -#endif - DynamicAny::DynAny_ptr dynany = - getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(seqTC); - CORBA::release(seqTC); - DynamicAny::DynSequence_ptr ds = - DynamicAny::DynSequence::_narrow(dynany); - CORBA::release(dynany); + // Build an Any from vector v + int isObjref=0; + if(t->contentType()->kind() == Objref) + isObjref=1; + + CORBA::TypeCode_var tc=getCorbaTC(t); + + DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc); + DynamicAny::DynSequence_var ds = DynamicAny::DynSequence::_narrow(dynany); + ds->set_length(v.size()); - std::vector::const_iterator iter; - DynamicAny::AnySeq as ; - as.length(v.size()); - int i=0; for(iter=v.begin();iter!=v.end();iter++) { - //Can we avoid making a copy ? + DynamicAny::DynAny_var temp=ds->current_component(); CORBA::Any* a=*iter; - as[i]=*a; - i++; + //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference + if(isObjref) + { + CORBA::Object_var zzobj ; + *a >>= CORBA::Any::to_object(zzobj) ; + temp->insert_reference(zzobj); + } + else + temp->from_any(*a); + //delete intermediate any delete a; + ds->next(); } - try - { - ds->set_elements(as); - } - catch(DynamicAny::DynAny::TypeMismatch& ex) - { - throw YACS::ENGINE::ConversionException("type mismatch"); - } - catch(DynamicAny::DynAny::InvalidValue& ex) - { - throw YACS::ENGINE::ConversionException("invalid value"); - } - any=ds->to_any(); + + CORBA::Any *any=ds->to_any(); ds->destroy(); - CORBA::release(ds); -#ifdef REFCNT - DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)seqTC)->pd_ref_count); -#endif return any; } }; @@ -1656,69 +2152,43 @@ namespace YACS { static inline CORBA::Any* convert(const TypeCode *t,std::map& m) { - CORBA::Any *any; - CORBA::TypeCode_ptr structTC; + CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb(); - //the equivalent CORBA TypeCode - structTC=getCorbaTC(t); -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t; int nMember=tst->memberCount(); DEBTRACE("nMember="<getDynFactory()->create_dyn_any_from_type_code(structTC); -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif - CORBA::release(structTC); -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif - DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(da); - CORBA::release(da); -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif - DynamicAny::NameValuePairSeq members; - members.length(nMember); + + CORBA::TypeCode_var tc=getCorbaTC(t); + DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc); + DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(dynany); + for(int i=0;icurrent_component(); const char * name=tst->memberName(i); DEBTRACE("Member name="<memberType(i); //do not test member presence : test has been done in ToYacs convertor CORBA::Any* a=m[name]; - members[i].id=CORBA::string_dup(name); - members[i].value=*a; + //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference + CORBA::TypeCode_var atc = tc->member_type(i); + if(atc->kind()==CORBA::tk_objref) + { + //special treatment for objref + CORBA::Object_var zzobj ; + *a >>= CORBA::Any::to_object(zzobj) ; + temp->insert_reference(zzobj); + } + else + { + temp->from_any(*a); + } //delete intermediate any delete a; + ds->next(); } -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif - ds->set_members(members); -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif - any=ds->to_any(); -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif + CORBA::Any *any=ds->to_any(); ds->destroy(); - CORBA::release(ds); -#ifdef REFCNT - DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); - DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); -#endif + return any; } }; @@ -1827,6 +2297,30 @@ namespace YACS { return YacsConvertor(t,data,0); } + PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *data) + { + return YacsConvertor(t,data,0); + } + + std::string convertPyObjectToString(PyObject* ob) + { + PyObject *s; + PyGILState_STATE gstate = PyGILState_Ensure(); + // TODO: separate treatment for string (maybe with bad encoding?) and other types of PyObject ? + // Do we need str() or repr() and what are the possible causes of failure of str() ? + // not clear, needs more analysis. + s=PyObject_Str(ob); + if (s == NULL) // for instance string with bad encoding, non utf-8 + { + s=PyObject_ASCII(ob); // escape non ASCII characters and like repr(), which is not the same as str()... + } + Py_ssize_t size; + const char* characters = PyUnicode_AsUTF8AndSize(s, &size); + std::string ss( characters, size); + Py_DECREF(s); + PyGILState_Release(gstate); + return ss; + } //XML conversions PyObject* convertXmlPyObject(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) @@ -1841,6 +2335,47 @@ namespace YACS { return YacsConvertor(t,doc,cur); } + PyObject* convertXmlStrPyObject(const TypeCode *t,std::string data) + { + xmlDocPtr doc; + xmlNodePtr cur; + PyObject *ob=NULL; + doc = xmlParseMemory(data.c_str(), strlen(data.c_str())); + if (doc == NULL ) + { + std::stringstream msg; + msg << "Problem in conversion: XML Document not parsed successfully "; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + std::stringstream msg; + msg << "Problem in conversion: empty XML Document"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) + { + ob=convertXmlPyObject(t,doc,cur); + break; + } + cur = cur->next; + } + xmlFreeDoc(doc); + if(ob==NULL) + { + std::stringstream msg; + msg << "Problem in conversion: incorrect XML value"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + return ob; + } //NEUTRAL conversions PyObject* convertNeutralPyObject(const TypeCode *t,YACS::ENGINE::Any* data) { @@ -1877,5 +2412,244 @@ namespace YACS { return YacsConvertor(t,data,0); } + + //! Basic template checker from type TIN + /*! + * This checker does nothing : throws exception + * It must be partially specialize for a specific type (TIN) + */ + template + static inline bool checkDouble(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template + static inline bool checkInt(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template + static inline bool checkBool(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template + static inline bool checkString(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template + static inline bool checkObjref(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template + static inline bool checkSequence(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template + static inline bool checkStruct(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template + static inline bool checkArray(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Check not implemented for Implementation: " << IMPLIN ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + + template + inline bool YacsChecker(const TypeCode *t,TIN o,TIN2 aux) + { + int tk=t->kind(); + switch(t->kind()) + { + case Double: + return checkDouble(t,o,aux); + case Int: + return checkInt(t,o,aux); + case String: + return checkString(t,o,aux); + case Bool: + return checkBool(t,o,aux); + case Objref: + return checkObjref(t,o,aux); + case Sequence: + return checkSequence(t,o,aux); + case Array: + return checkArray(t,o,aux); + case Struct: + return checkStruct(t,o,aux); + default: + break; + } + stringstream msg; + msg << "Check not implemented for kind= " << tk ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + template<> + inline bool checkDouble(const TypeCode *t,PyObject* o,void* aux) + { + if (PyFloat_Check(o)) + return true; + else if(PyLong_Check(o)) + return true; + else + { + stringstream msg; + msg << "Not a python double "; + throw YACS::ENGINE::ConversionException(msg.str()); + } + } + template<> + inline bool checkInt(const TypeCode *t,PyObject* o,void* aux) + { + if (PyLong_Check(o)) + return true; + else + { + stringstream msg; + msg << "Not a python integer "; + throw YACS::ENGINE::ConversionException(msg.str()); + } + } + template<> + inline bool checkBool(const TypeCode *t,PyObject* o,void* aux) + { + if (PyBool_Check(o)) + return true; + else if(PyLong_Check(o)) + return true; + else + { + stringstream msg; + msg << "Not a python boolean " ; + throw YACS::ENGINE::ConversionException(msg.str()); + } + + } + template<> + inline bool checkString(const TypeCode *t,PyObject* o,void* aux) + { + if (PyUnicode_Check(o)) + return true; + else + { + stringstream msg; + msg << "Not a python string " ; + throw YACS::ENGINE::ConversionException(msg.str()); + } + } + template<> + inline bool checkObjref(const TypeCode *t,PyObject* o,void* aux) + { + if (PyUnicode_Check(o)) + return true; + if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true) + return true; + else if(strncmp(t->id(),"json",4)==0) // The python object must be json pickable + { + // The python object should be json compliant (to improve) + return true; + } + else + { + // The python object should be a CORBA obj (to improve) + return true; + } + } + template<> + inline bool checkSequence(const TypeCode *t,PyObject* o,void* aux) + { + if(!PySequence_Check(o)) + { + stringstream msg; + msg << "python object is not a sequence " ; + throw YACS::ENGINE::ConversionException(msg.str()); + } + int length=PySequence_Size(o); + for(int i=0;i(t->contentType(),item,0); + } + catch(ConversionException& ex) + { + stringstream msg; + msg << ex.what() << " for sequence element " << i; + throw YACS::ENGINE::ConversionException(msg.str(),false); + } + Py_DECREF(item); + } + return true; + } + template<> + inline bool checkStruct(const TypeCode *t,PyObject* o,void* aux) + { + PyObject *value; + if(!PyDict_Check(o)) + { + stringstream msg; + msg << "python object is not a dict " ; + throw YACS::ENGINE::ConversionException(msg.str()); + } + YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t; + int nMember=tst->memberCount(); + for(int i=0;imemberName(i); + TypeCode* tm=tst->memberType(i); + value=PyDict_GetItemString(o, name.c_str()); + if(value==NULL) + { + stringstream msg; + msg << "member " << name << " not present " ; + throw YACS::ENGINE::ConversionException(msg.str()); + } + try + { + YacsChecker(tm,value,0); + } + catch(ConversionException& ex) + { + std::string s=" for struct member "+name; + throw YACS::ENGINE::ConversionException(ex.what()+s,false); + } + } + return true; + } + + bool checkPyObject(const TypeCode *t,PyObject* ob) + { + return YacsChecker(t,ob,0); + } } }