Version: 8.3.0
CORBAPorts.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 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 {
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) 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
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 
188 {
189  return new InputCorbaPort(*this,newHelder);
190 }
191 
192 void *InputCorbaPort::get() const throw(YACS::Exception)
193 {
194  return (void *)&_data;
195 }
196 
198 {
199  CORBA::TypeCode_var tc=_data.type();
200  return tc->equivalent(CORBA::_tc_null);
201 }
202 
204 {
205  // --- return a pointer to internal any
206  return &_data;
207 }
208 
210 {
212  CORBA::TypeCode_var tc=getAny()->type();
213  if (!tc->equivalent(CORBA::_tc_null))
215  else
216  {
217  Py_INCREF(Py_None);
218  return Py_None;
219  }
220 }
221 
223 {
225  PyObject* ob=getPyObj();
226  std::string s=convertPyObjectToString(ob);
227  Py_DECREF(ob);
228  return s;
229 }
230 
231 
233 
237 {
238  if(_initData)
239  delete _initData;
240  _initData=new CORBA::Any;
241  *_initData=_data;
242 }
243 
245 
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 
274 {
275  int isString = PyString_Check(getPyObj());
276  PyObject *strPyObj = PyObject_Str(getPyObj());
277  string val = PyString_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 {
294 }
295 
296 OutputCorbaPort::OutputCorbaPort(const OutputCorbaPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder)
297 {
299 }
300 
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  {
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 
350 {
351  return new OutputCorbaPort(*this,newHelder);
352 }
353 
355 {
356  // return a pointer to the internal any
357  return &_data;
358 }
359 
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 
425 {
427  CORBA::TypeCode_var tc=getAny()->type();
428  if (!tc->equivalent(CORBA::_tc_null))
430  else
431  {
432  Py_INCREF(Py_None);
433  return Py_None;
434  }
435 }
436 
438 {
440  PyObject* ob=getPyObj();
441  std::string s=convertPyObjectToString(ob);
442  Py_DECREF(ob);
443  return s;
444 }
445 
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 
467 {
468  PyObject *strPyObj = PyObject_Str(getPyObj());
469  string val = PyString_AsString(strPyObj);
470  Py_DECREF(strPyObj);
471  return val;
472 }
473 
474 void OutputCorbaPort::valFromStr(std::string valstr)
475 {
476 }
477