-// Copyright (C) 2006-2013 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
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// 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
#include "TypeCode.hxx"
#include "Cstr2d.hxx"
#include "SALOME_GenericObj.hh"
+#include "PythonNode.hxx"
#include <iostream>
+#include <iomanip>
#include <sstream>
#ifdef WIN32
{
namespace ENGINE
{
- void printbin(const std::string& bin)
- {
- register char c;
- for(int i=0;i<bin.length();i++)
- {
- c=bin[i];
- if (c < ' ' || c >= 0x7f)
- {
- fprintf(stderr,"\\x%02x",c & 0xff);
- }
- else
- fprintf(stderr,"%c",c);
- }
- fprintf(stderr,"\n");
- }
-
std::string getImplName(ImplType impl)
{
switch(impl)
if( t1->isA(t2->id()) )
return 1;
}
+ else if(t1->kind() == Sequence)
+ {
+ const TypeCodeSeq *t1c(dynamic_cast<const TypeCodeSeq *>(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;
}
};
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<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,protocol);
DEBTRACE( d );
TOUT r=convertFromYacsObjref<IMPLOUT,TOUT>::convert(t,d);
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
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
{
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;
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
{
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)
{
+ 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<PYTHONImpl");
}
- std::string mystr(PyString_AsString(pickled),PyString_Size(pickled));
+ std::string mystr(PyBytes_AsString(pickled),PyBytes_Size(pickled));
Py_DECREF(pickled);
return mystr;
}
PyErr_Print();
throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
}
- std::string mystr=PyString_AsString(pickled);
+ std::string mystr=PyBytes_AsString(pickled);
Py_DECREF(pickled);
return mystr;
}
PyErr_Print();
throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
}
- std::string mystr=PyString_AsString(pystring);
+ Py_ssize_t size;
+ std::string mystr;
+ const char *ptr = PyUnicode_AsUTF8AndSize(pystring, &size);
+ if (!ptr)
+ throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
+ mystr.assign(ptr, size);
Py_DECREF(pystring);
return mystr;
}
{
static inline PyObject* convert(const TypeCode *t,std::string& o)
{
- return PyString_FromString(o.c_str());
+ return PyUnicode_FromString(o.c_str());
}
};
template <>
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)
{
PyErr_Print();
throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
}
- PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"s",o.c_str());
+ PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y",o.c_str());
Py_DECREF(mod);
if(ob==NULL)
{
{
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);
+ if(s==0)return "";
+ DEBTRACE( "convertToYacsString " << (const char *)s );
+ std::string mystr=std::string((const char *)s);
+ xmlFree(s);
return mystr;
}
cur = cur->next;
static inline std::string convert(const TypeCode *t,double o)
{
stringstream msg ;
- msg << "<value><double>" << o << "</double></value>\n";
+ msg << "<value><double>" << setprecision(16) << o << "</double></value>\n";
return msg.str();
}
};
static inline std::string convert(const TypeCode *t,std::string& o)
{
if(strncmp(t->id(),"python",6)==0 )
- return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
+ return "<value><objref><![CDATA[" + ToBase64(o) + "]]></objref></value>\n";
else if(strncmp(t->id(),"json",4)==0)
return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
else
{
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 " ;
{
//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<TypeCode *>(t));
//Objref CORBA. prefix=IOR,corbaname,corbaloc
CORBA::Object_var obref;
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<TypeCode *>(t));
}
};
{
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);
{
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;
{
if (PyFloat_Check(o))
return true;
- else if (PyInt_Check(o))
- return true;
else if(PyLong_Check(o))
return true;
else
template<>
inline bool checkInt<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
{
- if (PyInt_Check(o) || PyLong_Check(o))
+ if (PyLong_Check(o))
return true;
else
{
{
if (PyBool_Check(o))
return true;
- else if (PyInt_Check(o))
- return true;
else if(PyLong_Check(o))
return true;
else
template<>
inline bool checkString<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
{
- if (PyString_Check(o))
+ if (PyUnicode_Check(o))
return true;
else
{
template<>
inline bool checkObjref<PYTHONImpl,PyObject*,void*>(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;