Version: 9.15.0
CORBAPorts.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2025 CEA, EDF
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 {
106 }
107 
108 InputCorbaPort::InputCorbaPort(const InputCorbaPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),
109  _initData(0)
110 {
112  if(other._initData)
113  {
114  _initData=new CORBA::Any;
115  *_initData=*(other._initData);
116  }
117  _data=other._data;
118 }
119 
121 {
122  delete _initData;
123  // Release or not release : all GenericObj are deleted when the input port is deleted
124  releaseObj(_data);
125 }
126 
128 {
129  return _initData!=0;
130 }
131 
133 {
134  delete _initData;
135  _initData=0;
137 }
138 
139 void InputCorbaPort::put(const void *data)
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 
165 {//do nothing - to be implemented
166 }
167 
168 void InputCorbaPort::put(CORBA::Any *data)
169 {
170 #ifdef REFCNT
171  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
172 #endif
174 #ifdef _DEVDEBUG_
175  display(data);
176 #endif
177 
178  releaseObj(_data);
179 
180  // make a copy of the any (protect against deletion of any source)
181  _data=*data;
182  _stringRef="";
183 
185 
186 #ifdef REFCNT
187  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
188 #endif
189 }
190 
192 {
193  return new InputCorbaPort(*this,newHelder);
194 }
195 
196 void *InputCorbaPort::get() const
197 {
198  return (void *)&_data;
199 }
200 
202 {
203  CORBA::TypeCode_var tc=_data.type();
204  return tc->equivalent(CORBA::_tc_null);
205 }
206 
208 {
209  // --- return a pointer to internal any
210  return &_data;
211 }
212 
214 {
216  CORBA::TypeCode_var tc=getAny()->type();
217  if (!tc->equivalent(CORBA::_tc_null))
219  else
220  {
221  Py_INCREF(Py_None);
222  return Py_None;
223  }
224 }
225 
227 {
229  PyObject* ob=getPyObj();
230  std::string s=convertPyObjectToString(ob);
231  Py_DECREF(ob);
232  return s;
233 }
234 
235 
237 
241 {
242  if(_initData)
243  delete _initData;
244  _initData=new CORBA::Any;
245  *_initData=_data;
246 }
247 
249 
253 {
254  if(!_initData)return;
255  put(_initData);
256 }
257 
258 std::string InputCorbaPort::dump()
259 {
260  CORBA::TypeCode_var tc=_data.type();
261  if (tc->equivalent(CORBA::_tc_null))
262  return "<value>nil</value>";
263  if (edGetType()->kind() != YACS::ENGINE::Objref)
264  return convertCorbaXml(edGetType(), &_data);
265  if (! _stringRef.empty())
266  return _stringRef;
267  else
268  return convertCorbaXml(edGetType(), &_data);
269 // {
270 // stringstream msg;
271 // msg << "Cannot retreive init string reference string for port " << _name
272 // << " on node " << _node->getName();
273 // throw Exception(msg.str());
274 // }
275 }
276 
278 {
279  int isString = PyBytes_Check(getPyObj());
280  PyObject *strPyObj = PyObject_Str(getPyObj());
281  string val = PyBytes_AsString(strPyObj);
282  if (isString)
283  val = "\"" + val + "\"";
284  Py_DECREF(strPyObj);
285  return val;
286 }
287 
288 void InputCorbaPort::valFromStr(std::string valstr)
289 {
290 }
291 
292 OutputCorbaPort::OutputCorbaPort(const std::string& name,
293  Node *node,
294  TypeCode * type)
295  : OutputPort(name, node, type), DataPort(name, node, type), Port(node)
296 {
298 }
299 
300 OutputCorbaPort::OutputCorbaPort(const OutputCorbaPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder)
301 {
303 }
304 
306 {
307  DEBTRACE(getName());
308  // Release or not release : all GenericObj are deleted when the output port is deleted
309  releaseObj(_data);
310 #ifdef REFCNT
311  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
312  DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
313 #endif
314 }
315 
316 void OutputCorbaPort::put(const void *data)
317 {
318  put((CORBA::Any *)data);
319 }
320 
321 void OutputCorbaPort::put(CORBA::Any *data)
322 {
323  InputPort *p;
324 
325  {
327 #ifdef REFCNT
328  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
329 #endif
330 #ifdef REFCNT
331  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
332 #endif
333 
334  releaseObj(_data);
335 
336  _data=*data;
337 
338  //no registerObj : we steal the output reference of the node
339  }
340 
341 #ifdef REFCNT
342  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
343 #endif
344  OutputPort::put(data);
345 #ifdef REFCNT
346  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
347 #endif
348 #ifdef REFCNT
349  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count);
350 #endif
351 }
352 
354 {
355  return new OutputCorbaPort(*this,newHelder);
356 }
357 
359 {
360  // return a pointer to the internal any
361  return &_data;
362 }
363 
365 {
366  CORBA::Any* a=new CORBA::Any;
367  DynType kind=edGetType()->kind();
368  CORBA::TypeCode_var t;
369 
370  if(kind == Int)
371  {
372  a->replace(CORBA::_tc_long, (void*) 0);
373  }
374  else if(kind == String)
375  {
376  a->replace(CORBA::_tc_string, (void*) 0);
377  }
378  else if(kind == Double)
379  {
380  a->replace(CORBA::_tc_double, (void*) 0);
381  }
382  else if(kind == Objref)
383  {
384  t = getCorbaTC(edGetType());
385  a->replace(t, (void*) 0);
386  }
387  else if(kind == Sequence)
388  {
389  t = getCorbaTC(edGetType());
390  a->replace(t, (void*) 0);
391  }
392  else if(kind == Struct)
393  {
394  t = getCorbaTC(edGetType());
395 #ifdef REFCNT
396  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count);
397 #endif
398  a->replace(t, (void*) 0);
399 #ifdef REFCNT
400  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count);
401 #endif
402  }
403  else if(kind == Bool)
404  {
405  a->replace(CORBA::_tc_boolean, (void*) 0);
406  }
407  else if(kind == NONE)
408  {
409  stringstream msg;
410  msg << "Cannot set Any Out for None" << __FILE__ << ":" << __LINE__;
411  throw Exception(msg.str());
412  }
413  else
414  {
415  stringstream msg;
416  msg << "Cannot set Any Out for unknown type" << __FILE__
417  << ":" << __LINE__;
418  throw Exception(msg.str());
419  }
420 
421  DEBTRACE( "getAnyOut:a: " << a );
422 #ifdef REFCNT
423  DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)a->pd_tc.in())->pd_ref_count);
424 #endif
425  return a;
426 }
427 
429 {
431  CORBA::TypeCode_var tc=getAny()->type();
432  if (!tc->equivalent(CORBA::_tc_null))
434  else
435  {
436  Py_INCREF(Py_None);
437  return Py_None;
438  }
439 }
440 
442 {
444  PyObject* ob=getPyObj();
445  std::string s=convertPyObjectToString(ob);
446  Py_DECREF(ob);
447  return s;
448 }
449 
451 {
452  CORBA::TypeCode_var tc=_data.type();
453  if (tc->equivalent(CORBA::_tc_null))
454  return "<value>nil</value>";
455  string xmldump = convertCorbaXml(edGetType(), &_data);
456  return xmldump;
457 }
458 namespace YACS {
459  namespace ENGINE {
460  ostream& operator<<(ostream& os, const OutputCorbaPort& p)
461  {
463  p._data>>=l;
464  os << p._name << " : " << l ;
465  return os;
466  }
467  };
468 };
469 
471 {
472  PyObject *strPyObj = PyObject_Str(getPyObj());
473  string val = PyBytes_AsString(strPyObj);
474  Py_DECREF(strPyObj);
475  return val;
476 }
477 
478 void OutputCorbaPort::valFromStr(std::string valstr)
479 {
480 }
481 
void display(CORBA::Any *data)
Definition: CORBAPorts.cxx:144
void registerObj(CORBA::Any &data)
Definition: CORBAPorts.cxx:74
void releaseObj(CORBA::Any &data)
Definition: CORBAPorts.cxx:48
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
TypeCode * edGetType() const
Definition: DataPort.hxx:53
std::string getName() const
Definition: DataPort.hxx:55
Class for CORBA Input Ports.
Definition: CORBAPorts.hxx:45
virtual std::string getAsString()
returns port value as a string that can be used in a GUI for example
Definition: CORBAPorts.cxx:226
virtual std::string valToStr()
Gives a string representation of the data, for user interfaces.
Definition: CORBAPorts.cxx:277
virtual void exRestoreInit()
Restore the saved data value to current data value.
Definition: CORBAPorts.cxx:252
void edRemoveManInit()
Removes eventually previous manual initialisation.
Definition: CORBAPorts.cxx:132
virtual std::string dump()
Definition: CORBAPorts.cxx:258
InputCorbaPort(const std::string &name, Node *node, TypeCode *type)
Definition: CORBAPorts.cxx:100
virtual void valFromStr(std::string valstr)
Allows to set data from a string representation used in user interface.
Definition: CORBAPorts.cxx:288
bool edIsManuallyInitialized() const
Specifies if this port has been manually set by the call of InputPort::edInit.
Definition: CORBAPorts.cxx:127
InputPort * clone(Node *newHelder) const
Definition: CORBAPorts.cxx:191
virtual CORBA::Any * getAny()
Definition: CORBAPorts.cxx:207
YACS::BASES::Mutex _mutex
Definition: CORBAPorts.hxx:72
virtual void put(const void *data)
Definition: CORBAPorts.cxx:139
virtual PyObject * getPyObj()
Definition: CORBAPorts.cxx:213
virtual void exSaveInit()
Save the current data value for further reinitialization of the port.
Definition: CORBAPorts.cxx:240
Base class for Input Ports.
Definition: InputPort.hxx:44
virtual void edRemoveManInit()
Removes eventually previous manual initialisation.
Definition: InputPort.cxx:140
std::string _stringRef
Definition: InputPort.hxx:90
Base class for all nodes.
Definition: Node.hxx:70
std::string _name
Definition: Node.hxx:89
virtual std::string dump()
Definition: CORBAPorts.cxx:450
OutputCorbaPort(const std::string &name, Node *node, TypeCode *type)
Definition: CORBAPorts.cxx:292
virtual std::string getAsString()
returns port value as a string that can be used in a GUI for example
Definition: CORBAPorts.cxx:441
virtual void valFromStr(std::string valstr)
Allows to set data from a string representation used in user interface.
Definition: CORBAPorts.cxx:478
virtual std::string valToStr()
Gives a string representation of the data, for user interfaces.
Definition: CORBAPorts.cxx:470
virtual void put(const void *data)
Definition: CORBAPorts.cxx:316
virtual CORBA::Any * getAnyOut()
Definition: CORBAPorts.cxx:364
YACS::BASES::Mutex _mutex
Definition: CORBAPorts.hxx:103
OutputPort * clone(Node *newHelder) const
Definition: CORBAPorts.cxx:353
virtual CORBA::Any * getAny()
Definition: CORBAPorts.cxx:358
virtual PyObject * getPyObj()
Definition: CORBAPorts.cxx:428
virtual void put(const void *data)
Definition: OutputPort.cxx:66
Base class for all ports.
Definition: Port.hxx:43
CORBA::ORB_ptr getOrb() const
Base class for all type objects.
Definition: TypeCode.hxx:68
DynType kind() const
Definition: TypeCode.cxx:47
Proc * p
Definition: driver.cxx:216
std::string convertPyObjectToString(PyObject *ob)
YACSRUNTIMESALOME_EXPORT RuntimeSALOME * getSALOMERuntime()
ostream & operator<<(ostream &os, const OutputCorbaPort &p)
Definition: CORBAPorts.cxx:460
CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t)
PyObject * convertCorbaPyObject(const TypeCode *t, CORBA::Any *data)
std::string convertCorbaXml(const TypeCode *t, CORBA::Any *data)