Salome HOME
Update copyrights
[modules/yacs.git] / src / runtime / CORBAPorts.cxx
1 // Copyright (C) 2006-2019  CEA/DEN, EDF R&D
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
20 //#define REFCNT
21 //
22 #ifdef REFCNT
23 #define private public
24 #define protected public
25 #include <omniORB4/CORBA.h>
26 #include <omniORB4/internal/typecode.h>
27 #endif
28
29 #include "RuntimeSALOME.hxx"
30 #include "TypeConversions.hxx"
31 #include "TypeCode.hxx"
32 #include "AutoLocker.hxx"
33 #include "CORBAPorts.hxx"
34 #include "PythonPorts.hxx"
35 #include "ServiceNode.hxx"
36 #include "ComponentInstance.hxx"
37 #include "SALOME_GenericObj.hh"
38
39 #include <iostream>
40 #include <sstream>
41
42 //#define _DEVDEBUG_
43 #include "YacsTrace.hxx"
44
45 using namespace YACS::ENGINE;
46 using namespace std;
47
48 void releaseObj(CORBA::Any& data)
49 {
50   CORBA::Object_var obj;
51   if(data >>= CORBA::Any::to_object(obj))
52     {
53       SALOME::GenericObj_var gobj;
54       try
55         {
56           gobj=SALOME::GenericObj::_narrow(obj);
57         }
58       catch(const CORBA::SystemException& )
59         {
60           return;
61         }
62       if(!CORBA::is_nil(gobj))
63         {
64           DEBTRACE("It's a SALOME::GenericObj");
65           gobj->UnRegister();
66         }
67       else
68           DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
69     }
70   else
71     DEBTRACE("It's not a CORBA::Object");
72 }
73
74 void registerObj(CORBA::Any& data)
75 {
76   CORBA::Object_var obj;
77   if(data >>= CORBA::Any::to_object(obj))
78     {
79       SALOME::GenericObj_var gobj;
80       try
81         {
82           gobj=SALOME::GenericObj::_narrow(obj);
83         }
84       catch(const CORBA::SystemException& )
85         {
86           return;
87         }
88       if(!CORBA::is_nil(gobj))
89         {
90           DEBTRACE("It's a SALOME::GenericObj");
91           gobj->Register();
92         }
93       else
94           DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
95     }
96   else
97     DEBTRACE("It's not a CORBA::Object");
98 }
99
100 InputCorbaPort::InputCorbaPort(const std::string& name,
101                                Node *node,
102                                TypeCode * type)
103   : InputPort(name, node, type), DataPort(name, node, type), Port(node), _initData(0)
104 {
105   _orb = getSALOMERuntime()->getOrb();
106 }
107
108 InputCorbaPort::InputCorbaPort(const InputCorbaPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),
109                                                                              _initData(0)
110 {
111   _orb = getSALOMERuntime()->getOrb();
112   if(other._initData)
113     {
114       _initData=new CORBA::Any;
115       *_initData=*(other._initData);
116     }
117   _data=other._data;
118 }
119
120 InputCorbaPort::~InputCorbaPort()
121 {
122   delete _initData;
123   // Release or not release : all GenericObj are deleted when the input port is deleted
124   releaseObj(_data);
125 }
126
127 bool InputCorbaPort::edIsManuallyInitialized() const
128 {
129   return _initData!=0;
130 }
131
132 void InputCorbaPort::edRemoveManInit()
133 {
134   delete _initData;
135   _initData=0;
136   InputPort::edRemoveManInit();
137 }
138
139 void InputCorbaPort::put(const void *data) throw (ConversionException)
140 {
141   put((CORBA::Any *)data);
142 }
143
144 void display(CORBA::Any* data)
145 {
146   CORBA::TypeCode_var tc=data->type();
147   switch(tc->kind())
148     {
149     case CORBA::tk_double:
150       CORBA::Double d;
151       *data >>= d;
152       DEBTRACE( "Double: " << d );
153       break;
154     case CORBA::tk_long:
155       CORBA::Long l;
156       *data >>= l;
157       DEBTRACE( "Int: " << l );
158       break;
159     default:
160       break;
161     }
162 }
163
164 void InputCorbaPort::put(CORBA::Any *data) throw (ConversionException)
165 {
166 #ifdef REFCNT
167   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
168 #endif
169   YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
170 #ifdef _DEVDEBUG_
171   display(data);
172 #endif
173
174   releaseObj(_data);
175
176   // make a copy of the any (protect against deletion of any source)
177   _data=*data;
178   _stringRef="";
179
180   registerObj(_data);
181
182 #ifdef REFCNT
183   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
184 #endif
185 }
186
187 InputPort *InputCorbaPort::clone(Node *newHelder) const
188 {
189   return new InputCorbaPort(*this,newHelder);
190 }
191
192 void *InputCorbaPort::get() const throw(YACS::Exception)
193 {
194   return (void *)&_data;
195 }
196
197 bool InputCorbaPort::isEmpty()
198 {
199   CORBA::TypeCode_var tc=_data.type();
200   return tc->equivalent(CORBA::_tc_null);
201 }
202
203 CORBA::Any * InputCorbaPort::getAny()
204 {
205   // --- return a pointer to internal any
206   return &_data;
207 }
208
209 PyObject * InputCorbaPort::getPyObj()
210 {
211   YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
212   CORBA::TypeCode_var tc=getAny()->type();
213   if (!tc->equivalent(CORBA::_tc_null))
214     return convertCorbaPyObject(edGetType(),getAny());
215   else
216     {
217       Py_INCREF(Py_None);
218       return Py_None;
219     }
220 }
221
222 std::string InputCorbaPort::getAsString()
223 {
224   InterpreterUnlocker loc;
225   PyObject* ob=getPyObj();
226   std::string s=convertPyObjectToString(ob);
227   Py_DECREF(ob);
228   return s;
229 }
230
231
232 //! Save the current data value for further reinitialization of the port
233 /*!
234  *
235  */
236 void InputCorbaPort::exSaveInit()
237 {
238   if(_initData)
239     delete _initData;
240   _initData=new CORBA::Any;
241   *_initData=_data;
242 }
243
244 //! Restore the saved data value to current data value
245 /*!
246  * If no data has been saved (_initData == 0) don't restore
247  */
248 void InputCorbaPort::exRestoreInit()
249 {
250   if(!_initData)return;
251   put(_initData);
252 }
253
254 std::string InputCorbaPort::dump()
255 {
256   CORBA::TypeCode_var tc=_data.type();
257   if (tc->equivalent(CORBA::_tc_null))
258     return "<value>nil</value>";
259   if (edGetType()->kind() != YACS::ENGINE::Objref)
260     return convertCorbaXml(edGetType(), &_data);
261   if (! _stringRef.empty())
262     return _stringRef;
263   else 
264     return convertCorbaXml(edGetType(), &_data);
265 //     {
266 //       stringstream msg;
267 //       msg << "Cannot retreive init string reference string for port " << _name
268 //           << " on node " << _node->getName();
269 //       throw Exception(msg.str());      
270 //     }
271 }
272
273 std::string InputCorbaPort::valToStr()
274 {
275   int isString = PyBytes_Check(getPyObj());
276   PyObject *strPyObj = PyObject_Str(getPyObj());
277   string val = PyBytes_AsString(strPyObj);
278   if (isString)
279     val = "\"" + val + "\"";
280   Py_DECREF(strPyObj);
281   return val;
282 }
283
284 void InputCorbaPort::valFromStr(std::string valstr)
285 {
286 }
287
288 OutputCorbaPort::OutputCorbaPort(const std::string& name,
289                                  Node *node,
290                                  TypeCode * type)
291   : OutputPort(name, node, type), DataPort(name, node, type), Port(node)
292 {
293   _orb = getSALOMERuntime()->getOrb();
294 }
295
296 OutputCorbaPort::OutputCorbaPort(const OutputCorbaPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder)
297 {
298   _orb = getSALOMERuntime()->getOrb();
299 }
300
301 OutputCorbaPort::~OutputCorbaPort()
302 {
303   DEBTRACE(getName());
304   // Release or not release : all GenericObj are deleted when the output port is deleted
305   releaseObj(_data);
306 #ifdef REFCNT
307   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
308   DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
309 #endif
310 }
311
312 void OutputCorbaPort::put(const void *data) throw (ConversionException)
313 {
314   put((CORBA::Any *)data);
315 }
316
317 void OutputCorbaPort::put(CORBA::Any *data) throw (ConversionException)
318 {
319   InputPort *p;
320
321   {  
322     YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
323 #ifdef REFCNT
324     DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
325 #endif
326 #ifdef REFCNT
327     DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
328 #endif
329
330     releaseObj(_data);
331
332     _data=*data;
333
334     //no registerObj : we steal the output reference of the node
335   }
336
337 #ifdef REFCNT
338   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
339 #endif
340   OutputPort::put(data);
341 #ifdef REFCNT
342   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
343 #endif
344 #ifdef REFCNT
345   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
346 #endif
347 }
348
349 OutputPort *OutputCorbaPort::clone(Node *newHelder) const
350 {
351   return new OutputCorbaPort(*this,newHelder);
352 }
353
354 CORBA::Any * OutputCorbaPort::getAny()
355 {
356   // return a pointer to the internal any
357   return &_data;
358 }
359
360 CORBA::Any * OutputCorbaPort::getAnyOut() 
361 {
362   CORBA::Any* a=new CORBA::Any;
363   DynType kind=edGetType()->kind();
364   CORBA::TypeCode_var t;
365
366   if(kind == Int)
367     {
368       a->replace(CORBA::_tc_long, (void*) 0);
369     }
370   else if(kind == String)
371     {
372       a->replace(CORBA::_tc_string, (void*) 0);
373     }
374   else if(kind == Double)
375     {
376       a->replace(CORBA::_tc_double, (void*) 0);
377     }
378   else if(kind == Objref)
379     {
380       t = getCorbaTC(edGetType());
381       a->replace(t, (void*) 0);
382     }
383   else if(kind == Sequence)
384     {
385       t = getCorbaTC(edGetType());
386       a->replace(t, (void*) 0);
387     }
388   else if(kind == Struct)
389     {
390       t = getCorbaTC(edGetType());
391 #ifdef REFCNT
392   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count);
393 #endif
394       a->replace(t, (void*) 0);
395 #ifdef REFCNT
396   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count);
397 #endif
398     }
399   else if(kind == Bool)
400     {
401       a->replace(CORBA::_tc_boolean, (void*) 0);
402     }
403   else if(kind == NONE)
404     {
405       stringstream msg;
406       msg << "Cannot set Any Out for None" << __FILE__ << ":" << __LINE__;
407       throw Exception(msg.str());
408     }
409   else
410     {
411       stringstream msg;
412       msg << "Cannot set Any Out for unknown type" << __FILE__
413           << ":" << __LINE__;
414       throw Exception(msg.str());
415     }
416     
417   DEBTRACE( "getAnyOut:a: " << a );
418 #ifdef REFCNT
419   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)a->pd_tc.in())->pd_ref_count);
420 #endif
421   return a;
422 }
423
424 PyObject * OutputCorbaPort::getPyObj()
425 {
426   YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
427   CORBA::TypeCode_var tc=getAny()->type();
428   if (!tc->equivalent(CORBA::_tc_null))
429     return convertCorbaPyObject(edGetType(),getAny());
430   else
431     {
432       Py_INCREF(Py_None);
433       return Py_None;
434     }
435 }
436
437 std::string OutputCorbaPort::getAsString()
438 {
439   InterpreterUnlocker loc;
440   PyObject* ob=getPyObj();
441   std::string s=convertPyObjectToString(ob);
442   Py_DECREF(ob);
443   return s;
444 }
445
446 std::string OutputCorbaPort::dump()
447 {
448   CORBA::TypeCode_var tc=_data.type();
449   if (tc->equivalent(CORBA::_tc_null))
450     return "<value>nil</value>";
451   string xmldump = convertCorbaXml(edGetType(), &_data);
452   return xmldump;
453 }
454 namespace YACS {
455   namespace ENGINE {
456     ostream& operator<<(ostream& os, const OutputCorbaPort& p)
457     {
458       CORBA::Double l;
459       p._data>>=l;
460       os << p._name << " : " << l ;
461       return os;
462     }
463   };
464 };
465
466 std::string OutputCorbaPort::valToStr()
467 {
468   PyObject *strPyObj = PyObject_Str(getPyObj());
469   string val = PyBytes_AsString(strPyObj);
470   Py_DECREF(strPyObj);
471   return val;
472 }
473
474 void OutputCorbaPort::valFromStr(std::string valstr)
475 {
476 }
477