X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2FTypeConversions.cxx;h=23701e50eb7c7a7e8352d3c1968d178071f8593a;hb=4dae3b5416a884361d80462dc4d6ccb59a6f2503;hp=740fe72a409769cf8795598959d939bb053dcd54;hpb=3d5175677a8442c34b6d63e9a28b007b32776af9;p=modules%2Fyacs.git diff --git a/src/runtime/TypeConversions.cxx b/src/runtime/TypeConversions.cxx index 740fe72a4..23701e50e 100644 --- a/src/runtime/TypeConversions.cxx +++ b/src/runtime/TypeConversions.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2006-2015 CEA/DEN, EDF R&D +// Copyright (C) 2006-2022 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 @@ -33,8 +33,10 @@ #include "TypeCode.hxx" #include "Cstr2d.hxx" #include "SALOME_GenericObj.hh" +#include "PythonNode.hxx" #include +#include #include #ifdef WIN32 @@ -58,22 +60,6 @@ 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) @@ -256,6 +242,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; } }; @@ -606,8 +603,10 @@ namespace YACS inline TOUT convertObjref(const TypeCode *t,TIN o,TIN2 aux) { int protocol=-1; - if(IMPLOUT==XMLImpl || IMPLOUT==NEUTRALImpl) - protocol=0; + 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); @@ -683,8 +682,6 @@ 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 @@ -706,9 +703,7 @@ 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 { @@ -729,8 +724,14 @@ namespace YACS static inline std::string convert(const TypeCode *t,PyObject* o,void*) { std::string s; - if (PyString_Check(o)) - s= PyString_AS_STRING(o); + 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; @@ -752,8 +753,6 @@ 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 @@ -774,24 +773,35 @@ namespace YACS { static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol) { - if (PyString_Check(o) && strncmp(t->id(),"python",6)!=0) + 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) { + bool somthingToDo = YACS::ENGINE::PythonEntry::GetDestroyStatus(o); + if( somthingToDo ) + YACS::ENGINE::PythonEntry::DoNotTouchFileIfProxy(o); // It's a native Python object pickle it - PyObject* mod=PyImport_ImportModule("cPickle"); + PyObject* mod=PyImport_ImportModule("pickle"); PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol); - DEBTRACE(PyObject_REPR(pickled) ); + if( somthingToDo ) + YACS::ENGINE::PythonEntry::UnlinkOnDestructorIfProxy(o); + DEBTRACE(PyObject_Repr(pickled) ); Py_DECREF(mod); if(pickled==NULL) { PyErr_Print(); throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref @@ -966,14 +981,14 @@ namespace YACS 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) + if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0" { //It's a python pickled object, unpickled it - PyObject* mod=PyImport_ImportModule("cPickle"); - PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"s#",o.c_str(),o.length()); - DEBTRACE(PyObject_REPR(ob)); + 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) { @@ -991,7 +1006,7 @@ namespace YACS PyErr_Print(); throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjrefid(),"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); + if(s==0)return ""; + DEBTRACE( "convertToYacsString " << (const char *)s ); + std::string mystr=std::string((const char *)s); + xmlFree(s); return mystr; } cur = cur->next; @@ -1423,7 +1452,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(); } }; @@ -1462,7 +1491,7 @@ namespace YACS static inline std::string convert(const TypeCode *t,std::string& o) { if(strncmp(t->id(),"python",6)==0 ) - return "\n"; + return "\n"; else if(strncmp(t->id(),"json",4)==0) return "\n"; else @@ -1577,7 +1606,7 @@ namespace YACS { static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,int protocol) { - if(o->getType()->kind()==String) + if(o->getType()->kind()==String || o->getType()->kind()==Objref) return o->getStringValue(); stringstream msg; msg << "Problem in conversion: a objref(string) is expected " ; @@ -1663,7 +1692,7 @@ namespace YACS { //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); + return YACS::ENGINE::AtomAny::New(o, const_cast(t)); //Objref CORBA. prefix=IOR,corbaname,corbaloc CORBA::Object_var obref; @@ -1697,7 +1726,7 @@ namespace YACS else DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj"); - return YACS::ENGINE::AtomAny::New(o); + return YACS::ENGINE::AtomAny::New(o, const_cast(t)); } }; @@ -1834,18 +1863,18 @@ namespace YACS { s=(const char*)buffer->get_buffer(); - if(protocol !=0) + if(protocol !=4) { std::string mystr(s,buffer->length()); return mystr; } PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject* mod=PyImport_ImportModule("cPickle"); - PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"s#",s,buffer->length()); + 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=PyString_AsString(pickled); + DEBTRACE(PyObject_Repr(pickled)); + std::string mystr=PyBytes_AsString(pickled); Py_DECREF(mod); Py_DECREF(ob); Py_DECREF(pickled); @@ -2267,8 +2296,17 @@ namespace YACS { 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); - std::string ss(PyString_AsString(s),PyString_Size(s)); + 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; @@ -2470,8 +2508,6 @@ namespace YACS { if (PyFloat_Check(o)) return true; - else if (PyInt_Check(o)) - return true; else if(PyLong_Check(o)) return true; else @@ -2484,7 +2520,7 @@ namespace YACS template<> inline bool checkInt(const TypeCode *t,PyObject* o,void* aux) { - if (PyInt_Check(o) || PyLong_Check(o)) + if (PyLong_Check(o)) return true; else { @@ -2498,8 +2534,6 @@ namespace YACS { if (PyBool_Check(o)) return true; - else if (PyInt_Check(o)) - return true; else if(PyLong_Check(o)) return true; else @@ -2513,7 +2547,7 @@ namespace YACS template<> inline bool checkString(const TypeCode *t,PyObject* o,void* aux) { - if (PyString_Check(o)) + if (PyUnicode_Check(o)) return true; else { @@ -2525,7 +2559,7 @@ namespace YACS template<> inline bool checkObjref(const TypeCode *t,PyObject* o,void* aux) { - if (PyString_Check(o)) + if (PyUnicode_Check(o)) return true; if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true) return true;