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