Salome HOME
Merge tag 'V8_3_0a2' into ngr/python3_dev
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_PickelizedPyObjRdExtServer.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony GEAY (EDF R&D)
20
21 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
22 #include "SALOMESDS_DataScopeServer.hxx"
23 #include "SALOMESDS_Exception.hxx"
24
25 #include <iostream>
26 #include <sstream>
27
28 using namespace SALOMESDS;
29
30 const char PickelizedPyObjRdExtServer::ACCESS_REPR[]="RdExt";
31
32 PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServerModifiable(father,varName,value)
33 {
34 }
35
36 //! obj is consumed
37 PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServerModifiable(father,varName,obj)
38 {
39 }
40
41 PickelizedPyObjRdExtServer::~PickelizedPyObjRdExtServer()
42 {
43 }
44
45 /*!
46  * Called remotely -> to protect against throw
47  */
48 SALOME::PickelizedPyObjRdExtServer_ptr PickelizedPyObjRdExtServer::invokePythonMethodOn(const char *method, const SALOME::ByteVec& args)
49 {
50   if(!_self)
51     throw Exception("PickelizedPyObjRdExtServer::invokePythonMethodOn : self is NULL !");
52   std::string argsCpp;
53   FromByteSeqToCpp(args,argsCpp);
54   PyObject *argsPy(getPyObjFromPickled(argsCpp));
55   checkRdExtnessOf(method,argsPy);
56   //
57   PyObject *selfMeth(PyObject_GetAttrString(_self,method));
58   if(!selfMeth)
59     {
60       std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::invokePythonMethodOn : Method \"" << method << "\" is not available !";
61       throw Exception(oss.str());
62     }
63   PyObject *res(PyObject_CallObject(selfMeth,argsPy));// self can have been modified by this call !
64   Py_XDECREF(selfMeth);
65   Py_XDECREF(argsPy);
66   if(!res)
67     {
68       std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::invokePythonMethodOn : Problem during invokation serverside of Method \"" << method << "\" !";
69       throw Exception(oss.str());
70     }
71   PickelizedPyObjRdExtServer *ret(new PickelizedPyObjRdExtServer(_father,DataScopeServer::BuildTmpVarNameFrom(getVarNameCpp()),res));
72   PortableServer::POA_var poa(_father->getPOA());
73   PortableServer::ObjectId_var id(poa->activate_object(ret));
74   CORBA::Object_var obj(poa->id_to_reference(id));
75   return SALOME::PickelizedPyObjRdExtServer::_narrow(obj);
76 }
77
78 void PickelizedPyObjRdExtServer::checkRdExtnessOf(const std::string& methodName, PyObject *argsPy)
79 {
80   if(!_self)
81     {
82       Py_XDECREF(argsPy);
83       throw Exception("PickelizedPyObjRdExtServer::checkRdExtnessOf : self is NULL !");
84     }
85   if(PyTuple_Check(_self)==1 || PyBytes_Check(_self)==1 || PyLong_Check(_self)==1 || PyBool_Check(_self)==1 || PyFloat_Check(_self)==1)
86     return ;//_self is tuple, str, int or float -> immutable in python. So no method can break the RdExtness of _self.
87   if(PyList_Check(_self)==1)
88     checkListRdExtnessOf(methodName,argsPy);
89   else if(PyDict_Check(_self)==1)
90     checkDictRdExtnessOf(methodName,argsPy);
91   else
92     throw Exception("PickelizedPyObjRdExtServer::checkRdExtnessOf : Supported python types are [list,tuple,dict,str,int,float] !");
93 }
94
95 void PickelizedPyObjRdExtServer::checkListRdExtnessOf(const std::string& methodName, PyObject *argsPy)
96 {
97   static const char *THE_RDEXT_METH_OF_LIST[]={"__getitem__","append","extend","insert","reverse","sort"};
98   for(std::size_t i=0;i<sizeof(THE_RDEXT_METH_OF_LIST)/sizeof(const char *);i++)
99     if(methodName==THE_RDEXT_METH_OF_LIST[i])
100       return ;
101   Py_XDECREF(argsPy);
102   std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::checkListRdExtnessOf : The method \"" << methodName << "\" is a method that can lead to a loss of data ! Supported method of \"list \"without loss of data are : __getitem__, append, extend, insert, reverse, sort !";
103   throw Exception(oss.str());
104 }
105
106 void PickelizedPyObjRdExtServer::checkDictRdExtnessOf(const std::string& methodName, PyObject *argsPy)
107 {
108   static const char *THE_RDEXT_METH_OF_DICT[]={"__getitem__","get","items","keys","setdefault","update","values"};
109   for(std::size_t i=0;i<sizeof(THE_RDEXT_METH_OF_DICT)/sizeof(const char *);i++)
110     if(methodName==THE_RDEXT_METH_OF_DICT[i])
111       return ;
112   if(methodName=="__setitem__")
113     {
114       checkDictSetitemRdExtness(argsPy);
115       return ;
116     }
117   Py_XDECREF(argsPy);
118   std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::checkDictRdExtnessOf : The method \"" << methodName << "\" is a method that can lead to a loss of data ! Supported method of \"list \"without loss of data are : __getitem__, __setitem__(with conditions), get, items, keys, setdefault, update, values !";
119   throw Exception(oss.str());
120 }
121
122 void PickelizedPyObjRdExtServer::checkDictSetitemRdExtness(PyObject *argsPy)
123 {
124   if(PyTuple_Check(argsPy)==0)
125     {
126       Py_XDECREF(argsPy);
127       throw Exception("PickelizedPyObjRdExtServer::checkDictSetitemRdExtness : args of dic(self).__setitem__ is not a tuple !");
128     }
129   if(PyTuple_Size(argsPy)!=2)
130     {
131       Py_XDECREF(argsPy);
132       throw Exception("PickelizedPyObjRdExtServer::checkDictSetitemRdExtness : tuple of dic(self).__setitem__ has not a size equal to 2 !");
133     }
134   if(PyDict_GetItem(_self,PyTuple_GetItem(argsPy,0))!=0)
135     {// argsPy[0] is already a key of _self -> __setitem__ is NOT RdExt !
136       Py_XDECREF(argsPy);
137       throw Exception("PickelizedPyObjRdExtServer::checkDictSetitemRdExtness : specified key of __setitem__ already exists ! RdExt property is not applied !");
138     }
139 }
140
141 std::string PickelizedPyObjRdExtServer::getAccessStr() const
142 {
143   return std::string(ACCESS_REPR);
144 }