Salome HOME
Updated copyright comment
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_DataScopeServer.cxx
index 2010d89ef5aa0c12948fd3ac13b8f313758c4da1..12005b9fa90be75d4de251952022dc53a640fd9c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
 #include "SALOMESDS_TrustTransaction.hxx"
 #include "SALOMESDS_KeyWaiter.hxx"
 #include "SALOMESDS_Transaction.hxx"
-#include "SALOME_NamingService.hxx"
+#include "SALOME_NamingService_Abstract.hxx"
 #include "SALOMESDS_Exception.hxx"
 
 #include <sstream>
@@ -46,22 +46,8 @@ using namespace SALOMESDS;
 
 std::size_t DataScopeServerBase::COUNTER=0;
 
-#if PY_VERSION_HEX < 0x03050000
-static char*
-Py_EncodeLocale(const wchar_t *arg, size_t *size)
-{
-       return _Py_wchar2char(arg, size);
-}
-static wchar_t*
-Py_DecodeLocale(const char *arg, size_t *size)
-{
-       return _Py_char2wchar(arg, size);
-}
-#endif
-
 void DataScopeKiller::shutdown()
 {
-  Py_Finalize();
   _orb->shutdown(0);
 }
 
@@ -84,19 +70,16 @@ void RequestSwitcher::fetchAndGetAccessOfVar(const char *varName, CORBA::String_
   return _ds->fetchAndGetAccessOfVar(varName,access,data);
 }
 
-DataScopeServerBase::DataScopeServerBase(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName),_killer(killer)
+DataScopeServerBase::DataScopeServerBase(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName, SALOME_NamingService_Container_Abstract *ns):_ns(ns),_pyHelper(pyHelper),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName),_killer(killer)
 {
 }
 
-DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
+DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_ns(other._ns->clone()),_pyHelper(other._pyHelper),_name(other._name),_vars(other._vars),_killer(other._killer)
 {
 }
 
 DataScopeServerBase::~DataScopeServerBase()
 {
-  // _globals is borrowed ref -> do nothing
-  Py_XDECREF(_locals);
-  Py_XDECREF(_pickler);
   for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
     {
        BasicDataServer *obj((*it).second);
@@ -105,6 +88,7 @@ DataScopeServerBase::~DataScopeServerBase()
            obj->decrRef();
          }
     }
+  delete _ns;
 }
 
 /*!
@@ -129,13 +113,13 @@ SALOME::StringVec *DataScopeServerBase::listVars()
 {
   SALOME::StringVec *ret(new SALOME::StringVec);
   std::size_t sz(_vars.size());
-  ret->length(sz);
+  ret->length((CORBA::ULong)sz); //!< TODO: size_t to CORBA::ULong
   std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
   for(std::size_t i=0;i<sz;it++,i++)
     {
       BasicDataServer *obj((*it).second);
       std::string name(obj->getVarNameCpp());
-      (*ret)[i]=CORBA::string_dup(name.c_str());
+      (*ret)[(CORBA::ULong)i]=CORBA::string_dup(name.c_str()); //!< TODO: size_t to CORBA::ULong
     }
   return ret;
 }
@@ -181,14 +165,13 @@ void DataScopeServerBase::deleteVar(const char *varName)
 
 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
 {
-  SALOME_NamingService ns(_orb);
-  CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
+  CORBA::Object_var obj(_ns->Resolve(DataServerManager::NAME_IN_NS));
   SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
   if(CORBA::is_nil(dsm))
     throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
   // destroy ref in the naming service
   std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
-  ns.Destroy_Name(fullScopeName.c_str());
+  _ns->Destroy_Name(fullScopeName.c_str());
   // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
   PortableServer::ServantBase *ret(0);
   try
@@ -246,18 +229,47 @@ SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const cha
     }
   Py_ssize_t sz(PyList_Size(keys));
   SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
-  ret->length(sz);
+  ret->length((CORBA::ULong)sz); //!< TODO: convert Py_ssize_t in CORBA::ULong
   for(Py_ssize_t i=0;i<sz;i++)
     {
       PyObject *item(PyList_GetItem(keys,i));
       Py_XINCREF(item);
       std::string pickel(varc->pickelize(item));//item consumed
-      PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[i]);
+      PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[(CORBA::ULong)i]); //!< TODO: convert Py_ssize_t in CORBA::ULong
     }
   Py_XDECREF(keys);
   return ret;
 }
 
+SALOME::ByteVec *DataScopeServerBase::getValueOfVarWithTypeDict(const char *varName, const SALOME::ByteVec& constKey)
+{
+  BasicDataServer *var(retrieveVarInternal2(varName));
+  PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
+  if(!varc)
+    {
+      std::ostringstream oss; oss << "DataScopeServerBase::getValueOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
+      throw Exception(oss.str());
+    }
+  if(!varc->isDict())
+    {
+      std::ostringstream oss; oss << "DataScopeServerBase::getValueOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
+      throw Exception(oss.str());
+    }
+  //
+  std::string keyCpp;
+  PickelizedPyObjServer::FromByteSeqToCpp(constKey,keyCpp);
+  SALOME::AutoPyRef key(PickelizedPyObjServer::GetPyObjFromPickled(keyCpp,this));
+  PyObject *value(PyDict_GetItem(varc->getPyObj(),key.get()));//borrowed
+  if(!value)
+    {
+      std::ostringstream oss; oss << "DataScopeServerBase::getValueOfVarWithTypeDict : var \"" << varName << "\" seems to not have key specified !";
+      throw Exception(oss.str());
+    }
+  Py_XINCREF(value);
+  std::string ret(PickelizedPyObjServer::Pickelize(value,this));//value is consumed
+  return PickelizedPyObjServer::FromCppToByteSeq(ret);
+}
+
 void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
 {
   if(napDurationInSec<0.)
@@ -276,44 +288,9 @@ void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
 #endif
 }
 
-void DataScopeServerBase::initializePython(int argc, char *argv[])
-{
-  Py_Initialize();
-  PyEval_InitThreads();
-  wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments
-  for (int i = 0; i < argc; i++)
-    changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
-  PySys_SetArgv(argc, changed_argv);
-  PyObject *mainmod(PyImport_AddModule("__main__"));
-  _globals=PyModule_GetDict(mainmod);
-  if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
-    {
-      PyObject *bimod(PyImport_ImportModule("__builtin__"));
-      if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
-        Py_FatalError("can't add __builtins__ to __main__");
-      Py_XDECREF(bimod);
-    }
-  _locals=PyDict_New();
-  PyObject *tmp(PyList_New(0));
-  _pickler=PyImport_ImportModuleLevel(const_cast<char *>("pickle"),_globals,_locals,tmp,0);
-}
-
 void DataScopeServerBase::registerToSalomePiDict() const
 {
-  PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
-  if(!mod)
-    return;
-  PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
-  if(!meth)
-    { Py_XDECREF(mod); return ; }
-  PyObject *args(PyTuple_New(2));
-  PyTuple_SetItem(args,0,PyLong_FromLong(getpid()));
-  PyTuple_SetItem(args,1,PyUnicode_FromString("SALOME_DataScopeServerBase"));
-  PyObject *res(PyObject_CallObject(meth,args));
-  Py_XDECREF(args);
-  Py_XDECREF(res);
-  Py_XDECREF(meth);
-  Py_XDECREF(mod);
+  _pyHelper->registerToSalomePiDict("SALOME_DataScopeServerBase",getpid());
 }
 
 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
@@ -324,8 +301,7 @@ void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
 {
   std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
-  SALOME_NamingService ns(_orb);
-  ns.Register(ptr,fullScopeName.c_str());
+  _ns->Register(ptr,fullScopeName.c_str());
 }
 
 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
@@ -496,7 +472,7 @@ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterat
 
 ///////
 
-DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
+DataScopeServer::DataScopeServer(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName, SALOME_NamingService_Container_Abstract *ns):DataScopeServerBase(pyHelper,orb,killer,scopeName,ns)
 {
 }
 
@@ -543,7 +519,7 @@ DataScopeServer::~DataScopeServer()
 
 ////////
 
-DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
+DataScopeServerTransaction::DataScopeServerTransaction(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName, SALOME_NamingService_Container_Abstract *ns):DataScopeServerBase(pyHelper,orb,killer,scopeName,ns)
 {
   CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
   PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
@@ -604,11 +580,11 @@ void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varNa
   _vars.push_back(p);
 }
 
-void DataScopeServerTransaction::createRdExtVarFreeStyleInternal(const std::string& varName, const SALOME::ByteVec& constValue, std::vector<unsigned char>&& sha1)
+void DataScopeServerTransaction::createRdExtVarFreeStyleInternal(const std::string& varName, const SALOME::ByteVec& constValue, std::string&& compareFuncContent, SALOME::AutoPyRef&& compareFunc)
 {
   if(!isExistingVar(varName))
     {
-      PickelizedPyObjRdExtFreeStyleServer *tmp(new PickelizedPyObjRdExtFreeStyleServer(this,varName,constValue,std::move(sha1)));
+      PickelizedPyObjRdExtFreeStyleServer *tmp(new PickelizedPyObjRdExtFreeStyleServer(this,varName,constValue,std::move(compareFuncContent),std::move(compareFunc)));
       CORBA::Object_var ret(tmp->activate());
       std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
       _vars.push_back(p);
@@ -626,10 +602,26 @@ void DataScopeServerTransaction::createRdExtVarFreeStyleInternal(const std::stri
       if(!ds2)
         {
           std::ostringstream oss;
-          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non RdExtFreeStyle type !";
+          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non Sha1Keeper type !";
+          throw Exception(oss.str());
+        }
+      PickelizedPyObjServer *ds3(dynamic_cast<PickelizedPyObjServer *>(ds));
+      if(!ds3)
+        {
+          std::ostringstream oss;
+          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non PickelizedPyObjServer type !";
+          throw Exception(oss.str());
+        }
+      std::vector<unsigned char> constValueAsCpp;
+      Transaction::FromByteSeqToVB(constValue,constValueAsCpp);
+      SALOME::AutoPyRef newObj(PickelizedPyObjServer::GetPyObjFromPickled(constValueAsCpp,this));
+      if(newObj.isNull())
+        {
+          std::ostringstream oss;
+          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists but input pickelized object is not loadable !";
           throw Exception(oss.str());
         }
-      ds2->checkSha1(varName,sha1);
+      ds2->checkSame(varName,compareFuncContent,ds3->getPyObj(),newObj);
     }
 }
 
@@ -667,9 +659,9 @@ SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const
   return SALOME::Transaction::_narrow(obj);
 }
 
-SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarFreeStyleTransac(const char *varName, const SALOME::ByteVec& constValue, const SALOME::ByteVec& sha1)
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarFreeStyleTransac(const char *varName, const SALOME::ByteVec& constValue, const char *compareFuncContent)
 {// no check on varName done here. Will be done on perform
-  TransactionRdExtVarFreeStyleCreate *ret(new TransactionRdExtVarFreeStyleCreate(this,varName,constValue,sha1));
+  TransactionRdExtVarFreeStyleCreate *ret(new TransactionRdExtVarFreeStyleCreate(this,varName,constValue,compareFuncContent));
   CORBA::Object_var obj(ret->activate());
   return SALOME::Transaction::_narrow(obj);
 }
@@ -706,7 +698,7 @@ void DataScopeServerTransaction::pingKey(PyObject *keyObj)
   for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
     {
       PyObject *waitKey((*it)->getKeyPyObj());
-      PyObject *meth(PyObject_GetAttrString(keyObj,"__eq__"));
+      PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__"));
       if(!meth)
       {
          std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
@@ -744,7 +736,7 @@ void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject
           continue;
         }
       PyObject *waitKey((*it)->getKeyPyObj());
-      PyObject *meth(PyObject_GetAttrString(keyObj,"__eq__"));
+      PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__"));
       if(!meth)
       {
          std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
@@ -899,7 +891,7 @@ void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& tr
       Transaction *elt(0);
       try
         {
-          eltBase=_poa->reference_to_servant(transactions[i]);
+          eltBase=_poa->reference_to_servant(transactions[(CORBA::ULong)i]); //!< TODO: size_t to CORBA::ULong
           elt=dynamic_cast<Transaction *>(eltBase);
         }
       catch(...)