Salome HOME
Merge changes from 'master' branch.
[modules/kernel.git] / src / DSC / DSC_Python / calcium.i
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
20 %define DOCSTRING
21 "CALCIUM python wrapping : Superv_Component class
22 "
23 %enddef
24
25 %module(docstring=DOCSTRING) calcium
26
27 %feature("autodoc", "1");
28
29 %include cstring.i
30
31 %{
32 //C++ Includes 
33 #include <SALOMEconfig.h>
34 #include <Calcium.hxx>
35 #include <calcium.h>
36 #include <Superv_Component_i.hxx>
37 #include <Salome_file_i.hxx>
38 #include <omniORB4/CORBA.h>
39
40 //--- from omniORBpy.h (not present on Debian Sarge packages)
41
42 struct omniORBpyAPI {
43
44   PyObject* (*cxxObjRefToPyObjRef)(const CORBA::Object_ptr cxx_obj,
45            CORBA::Boolean hold_lock);
46   // Convert a C++ object reference to a Python object reference.
47   // If <hold_lock> is true, caller holds the Python interpreter lock.
48
49   CORBA::Object_ptr (*pyObjRefToCxxObjRef)(PyObject* py_obj,
50              CORBA::Boolean hold_lock);
51   // Convert a Python object reference to a C++ object reference.
52   // Raises BAD_PARAM if the Python object is not an object reference.
53   // If <hold_lock> is true, caller holds the Python interpreter lock.
54
55   PyObject* (*handleCxxSystemException)(const CORBA::SystemException& ex);
56   // Sets the Python exception state to reflect the given C++ system
57   // exception. Always returns NULL. The caller must hold the Python
58   // interpreter lock.
59 };
60
61   omniORBpyAPI* api;
62   PyObject* dsc ;
63
64
65 %}
66
67 %init
68 %{
69 #include <capsulethunk.h>
70   // init section
71 #ifdef WITH_NUMPY
72   import_array()
73 #endif
74
75   PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
76   if (!omnipy)
77   {
78     PyErr_SetString(PyExc_ImportError,
79         (char*)"Cannot import _omnipy");
80     return NULL;
81   }
82   PyObject* pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
83   api = (omniORBpyAPI*)PyCapsule_New(pyapi,NULL,NULL);
84   Py_DECREF(pyapi);
85
86   PyObject* engines = PyImport_ImportModule("Engines");
87   dsc = PyObject_GetAttrString(engines, "DSC");
88 %}
89
90 %include <exception.i>
91
92
93
94 /*
95  * Most of this code is borrowed from numpy distribution
96  * The following code originally appeared in enthought/kiva/agg/src/numeric.i,
97  * author unknown.  It was translated from C++ to C by John Hunter.  Bill
98  * Spotz has modified it slightly to fix some minor bugs, add some comments
99  * and some functionality.
100  */
101
102 %{
103
104 #ifdef WITH_NUMPY
105 /* With Numpy */
106 #ifdef HAVE_ISINF
107 #undef HAVE_ISINF
108 #endif
109 #include <numpy/arrayobject.h>
110
111 typedef PyArrayObject ArrayObject;
112
113 /* Macros to extract array attributes.
114  */
115 #define is_array(a)            ((a) && PyArray_Check((PyArrayObject *)a))
116 #define array_type(a)          (int)(PyArray_TYPE(a))
117 #define array_dimensions(a)    (((PyArrayObject *)a)->nd)
118 #define array_size(a,i)        (((PyArrayObject *)a)->dimensions[i])
119 #define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
120
121 const char* pytype_string(PyObject*);
122 const char* typecode_string(int);
123 int type_match(int, int);
124 int require_size(PyArrayObject*, int*, int);
125 int require_dimensions_n(PyArrayObject*, int*, int);
126 int require_dimensions(PyArrayObject*, int);
127 int require_contiguous(PyArrayObject*);
128 PyArrayObject* make_contiguous(PyArrayObject*, int*, int, int);
129 PyArrayObject* obj_to_array_no_conversion(PyObject*, int);
130 PyArrayObject* obj_to_array_allow_conversion(PyObject*, int, int*);
131 PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject*, int, int*);
132 PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject*, int, int*);
133
134 /* Given a PyObject, return a string describing its type.
135  */
136 const char* pytype_string(PyObject* py_obj) {
137   if (py_obj == NULL          ) return "C NULL value";
138   if (PyCallable_Check(py_obj)) return "callable"    ;
139   if (PyString_Check(  py_obj)) return "string"      ;
140   if (PyInt_Check(     py_obj)) return "int"         ;
141   if (PyFloat_Check(   py_obj)) return "float"       ;
142   if (PyDict_Check(    py_obj)) return "dict"        ;
143   if (PyList_Check(    py_obj)) return "list"        ;
144   if (PyTuple_Check(   py_obj)) return "tuple"       ;
145   if (PyModule_Check(  py_obj)) return "module"      ;
146 #if PY_MAJOR_VERSION < 3
147   if (PyFile_Check(    py_obj)) return "file"        ;
148   if (PyInstance_Check(py_obj)) return "instance"    ;
149 #endif
150
151   return "unknown type";
152 }
153
154 /*
155 For documentation only : numpy typecodes
156
157 enum NPY_TYPECHAR { NPY_BOOLLTR = '?',
158                         NPY_BYTELTR = 'b',
159                         NPY_UBYTELTR = 'B',
160                         NPY_SHORTLTR = 'h',
161                         NPY_USHORTLTR = 'H',
162                         NPY_INTLTR = 'i',
163                         NPY_UINTLTR = 'I',
164                         NPY_LONGLTR = 'l',
165                         NPY_ULONGLTR = 'L',
166                         NPY_LONGLONGLTR = 'q',
167                         NPY_ULONGLONGLTR = 'Q',
168                         NPY_FLOATLTR = 'f',
169                         NPY_DOUBLELTR = 'd',
170                         NPY_LONGDOUBLELTR = 'g',
171                         NPY_CFLOATLTR = 'F',
172                         NPY_CDOUBLELTR = 'D',
173                         NPY_CLONGDOUBLELTR = 'G',
174                         NPY_OBJECTLTR = 'O',
175                         NPY_STRINGLTR = 'S',
176                         NPY_STRINGLTR2 = 'a',
177                         NPY_UNICODELTR = 'U',
178                         NPY_VOIDLTR = 'V',
179                         NPY_CHARLTR = 'c',
180
181                         NPY_INTPLTR = 'p',
182                         NPY_UINTPLTR = 'P',
183
184                         NPY_GENBOOLLTR ='b',
185                         NPY_SIGNEDLTR = 'i',
186                         NPY_UNSIGNEDLTR = 'u',
187                         NPY_FLOATINGLTR = 'f',
188                         NPY_COMPLEXLTR = 'c'
189 };
190 */
191
192 /* Given a Numeric typecode, return a string describing the type.
193  */
194 const char* typecode_string(int typecode) {
195   const char* type_names[] = {"bool","byte","unsigned byte","short",
196         "unsigned short","int","unsigned int","long","unsigned long",
197         "longlong","unsigned longlong",
198         "float","double","long double","complex float","complex double","complex long double",
199         "object","string","unicode","void","ntypes","notype","char","unknown"};
200   return type_names[typecode];
201 }
202
203 /* Make sure input has correct numeric type.  Allow character and byte
204  * to match.  Also allow int and long to match.
205  */
206 int type_match(int actual_type, int desired_type) {
207   return PyArray_EquivTypenums(actual_type, desired_type);
208 }
209
210 /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
211  * legal.  If not, set the python error string appropriately and
212  * return NULL./
213  */
214 PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode) {
215   PyArrayObject* ary = NULL;
216   if (is_array(input) && (typecode == PyArray_NOTYPE ||
217         PyArray_EquivTypenums(array_type(input),
218             typecode))) {
219         ary = (PyArrayObject*) input;
220     }
221     else if is_array(input) {
222       const char* desired_type = typecode_string(typecode);
223       const char* actual_type = typecode_string(array_type(input));
224       PyErr_Format(PyExc_TypeError,
225        "Array of type '%s' required.  Array of type '%s' given",
226        desired_type, actual_type);
227       ary = NULL;
228     }
229     else {
230       const char * desired_type = typecode_string(typecode);
231       const char * actual_type = pytype_string(input);
232       PyErr_Format(PyExc_TypeError,
233        "Array of type '%s' required.  A %s was given",
234        desired_type, actual_type);
235       ary = NULL;
236     }
237   return ary;
238 }
239
240 /* Convert the given PyObject to a Numeric array with the given
241  * typecode.  On Success, return a valid PyArrayObject* with the
242  * correct type.  On failure, the python error string will be set and
243  * the routine returns NULL.
244  */
245 PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
246                                              int* is_new_object)
247 {
248   PyArrayObject* ary = NULL;
249   PyObject* py_obj;
250   if (is_array(input) && (typecode == PyArray_NOTYPE || type_match(array_type(input),typecode))) {
251     ary = (PyArrayObject*) input;
252     *is_new_object = 0;
253   }
254   else {
255     py_obj = PyArray_FromObject(input, typecode, 0, 0);
256     /* If NULL, PyArray_FromObject will have set python error value.*/
257     ary = (PyArrayObject*) py_obj;
258     *is_new_object = 1;
259   }
260   return ary;
261 }
262
263 /* Given a PyArrayObject, check to see if it is contiguous.  If so,
264  * return the input pointer and flag it as not a new object.  If it is
265  * not contiguous, create a new PyArrayObject using the original data,
266  * flag it as a new object and return the pointer.
267  */
268 PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
269                                int min_dims, int max_dims)
270 {
271   PyArrayObject* result;
272   if (array_is_contiguous(ary)) {
273     result = ary;
274     *is_new_object = 0;
275   }
276   else {
277     result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
278                  array_type(ary),
279                  min_dims,
280                  max_dims);
281     *is_new_object = 1;
282   }
283   return result;
284 }
285
286 /* Convert a given PyObject to a contiguous PyArrayObject of the
287  * specified type.  If the input object is not a contiguous
288  * PyArrayObject, a new one will be created and the new object flag
289  * will be set.
290  */
291 PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
292                                                         int typecode,
293                                                         int* is_new_object) {
294   int is_new1 = 0;
295   int is_new2 = 0;
296   PyArrayObject* ary2;
297   PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
298                   &is_new1);
299   if (ary1) {
300     ary2 = make_contiguous(ary1, &is_new2, 0, 0);
301     if ( is_new1 && is_new2) {
302       Py_DECREF(ary1);
303     }
304     ary1 = ary2;
305   }
306   *is_new_object = is_new1 || is_new2;
307   return ary1;
308 }
309
310 /* Test whether a python object is contiguous.  If array is
311  * contiguous, return 1.  Otherwise, set the python error string and
312  * return 0.
313  */
314 int require_contiguous(PyArrayObject* ary) {
315   int contiguous = 1;
316   if (!array_is_contiguous(ary)) {
317     PyErr_SetString(PyExc_TypeError, "Array must be contiguous.  A discontiguous array was given");
318     contiguous = 0;
319   }
320   return contiguous;
321 }
322
323 /* Require the given PyArrayObject to have a specified number of
324  * dimensions.  If the array has the specified number of dimensions,
325  * return 1.  Otherwise, set the python error string and return 0.
326  */
327 int require_dimensions(PyArrayObject* ary, int exact_dimensions) {
328   int success = 1;
329   if (array_dimensions(ary) != exact_dimensions) {
330     PyErr_Format(PyExc_TypeError,
331      "Array must have %d dimensions.  Given array has %d dimensions",
332      exact_dimensions, array_dimensions(ary));
333     success = 0;
334   }
335   return success;
336 }
337
338 /* Require the given PyArrayObject to have one of a list of specified
339  * number of dimensions.  If the array has one of the specified number
340  * of dimensions, return 1.  Otherwise, set the python error string
341  * and return 0.
342  */
343 int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n) {
344   int success = 0;
345   int i;
346   char dims_str[255] = "";
347   char s[255];
348   for (i = 0; i < n && !success; i++) {
349     if (array_dimensions(ary) == exact_dimensions[i]) {
350       success = 1;
351     }
352   }
353   if (!success) {
354     for (i = 0; i < n-1; i++) {
355       sprintf(s, "%d, ", exact_dimensions[i]);
356       strcat(dims_str,s);
357     }
358     sprintf(s, " or %d", exact_dimensions[n-1]);
359     strcat(dims_str,s);
360     PyErr_Format(PyExc_TypeError,
361      "Array must have %s dimensions.  Given array has %d dimensions",
362      dims_str, array_dimensions(ary));
363   }
364   return success;
365 }
366
367 /* Require the given PyArrayObject to have a specified shape.  If the
368  * array has the specified shape, return 1.  Otherwise, set the python
369  * error string and return 0.
370  */
371 int require_size(PyArrayObject* ary, int* size, int n) {
372   int i;
373   int success = 1;
374   int len;
375   char desired_dims[255] = "[";
376   char s[255];
377   char actual_dims[255] = "[";
378   for(i=0; i < n;i++) {
379     if (size[i] != -1 &&  size[i] != array_size(ary,i)) {
380       success = 0;
381     }
382   }
383   if (!success) {
384     for (i = 0; i < n; i++) {
385       if (size[i] == -1) {
386         sprintf(s, "*,");
387       }
388       else
389       {
390         sprintf(s, "%d,", size[i]);
391       }
392       strcat(desired_dims,s);
393     }
394     len = strlen(desired_dims);
395     desired_dims[len-1] = ']';
396     for (i = 0; i < n; i++) {
397       sprintf(s, "%d,", array_size(ary,i));
398       strcat(actual_dims,s);
399     }
400     len = strlen(actual_dims);
401     actual_dims[len-1] = ']';
402     PyErr_Format(PyExc_TypeError,
403      "Array must have shape of %s.  Given array has shape of %s",
404      desired_dims, actual_dims);
405   }
406   return success;
407 }
408
409 #else
410 /* Without Numpy */
411 typedef PyObject ArrayObject;
412
413 #endif
414 %}
415
416 %include "carrays.i" 
417
418 %array_class(int,    intArray);
419 %array_class(long,   longArray);
420 %array_class(float,  floatArray);
421 %array_class(double, doubleArray);
422
423 /* special struct to handle string arrays */
424 %inline %{
425 struct stringArray
426 {
427   stringArray(int nelements,int size=0) {
428     nelem=nelements;
429     size=size;
430     data= new char*[nelements];
431     for(int i=0;i<nelements;i++)
432     {
433       data[i]=(char *)malloc((size+1)*sizeof(char));
434       data[i][size+1]='\0';
435     }
436   }
437   ~stringArray() 
438   {
439     for(int i=0;i<nelem;i++)
440       free(data[i]);
441     delete [] data;
442   }
443   char* __getitem__(int index) {
444     return data[index];
445   }
446   void __setitem__(int index, char* value) {
447     free(data[index]);
448     data[index] = strdup(value);
449   }
450   char** data;
451   int nelem;
452   int size;
453 };
454 %}
455 /* End of special struct to handle string arrays */
456
457 /* input typemap 
458    This typemap can be used for input array objects only.
459    It accepts swig carray objects or numpy contiguous or non contiguous objects.
460    In case of non-contiguous numpy object, it is converted (new object) into a contiguous numpy object
461    This new object is deleted after the call.
462 */
463 %define TYPEMAP_IN3(type,typecode)
464 %typemap(in) type* IN_ARRAY3
465              (ArrayObject* array=NULL, int is_new_object) {
466   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
467   {
468 %#ifdef WITH_NUMPY
469     int size[1] = {-1};
470     array = obj_to_array_contiguous_allow_conversion($input, typecode, &is_new_object);
471     if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
472     $1 = (type*) array->data;
473 %#else
474     SWIG_exception(SWIG_TypeError, "type* expected");
475 %#endif
476   }
477 }
478 %typemap(freearg) type* IN_ARRAY3 {
479 %#ifdef WITH_NUMPY
480   if (is_new_object$argnum && array$argnum) 
481     {
482       Py_DECREF(array$argnum);
483     }
484 %#endif
485 }
486 %enddef
487
488 TYPEMAP_IN3(int,     PyArray_INT)
489 TYPEMAP_IN3(long,    PyArray_LONG)
490 TYPEMAP_IN3(float,   PyArray_FLOAT )
491 TYPEMAP_IN3(double,  PyArray_DOUBLE)
492
493 #undef TYPEMAP_IN3
494
495 %apply int*    IN_ARRAY3 {int    *eval};
496 %apply long*   IN_ARRAY3 {long   *eval};
497 %apply float*  IN_ARRAY3 {float  *eval};
498 %apply double* IN_ARRAY3 {double *eval};
499
500 /*  Specific typemap for complex */
501 %typemap(in) float*  ecpval
502              (ArrayObject* array=NULL, int is_new_object) {
503   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
504   {
505 %#ifdef WITH_NUMPY
506     int size[1] = {-1};
507     array = obj_to_array_contiguous_allow_conversion($input, PyArray_CFLOAT, &is_new_object);
508     if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
509     $1 = (float*) array->data;
510 %#else
511     SWIG_exception(SWIG_TypeError, "complex array expected");
512 %#endif
513   }
514 }
515 %typemap(freearg) float* ecpval {
516 %#ifdef WITH_NUMPY
517   if (is_new_object$argnum && array$argnum) 
518     {
519       Py_DECREF(array$argnum);
520     }
521 %#endif
522 }
523 /* End of  Specific typemap for complex */
524
525 /* array of strings on input */
526 %typemap(in) (char** eval,int strSize)
527          (ArrayObject* array=NULL, int is_new_object) {
528   stringArray* sarray;
529   if ((SWIG_ConvertPtr($input, (void **) &sarray, $descriptor(stringArray *),0)) == -1)
530   {
531 %#ifdef WITH_NUMPY
532     int size[1] = {-1};
533     array = obj_to_array_contiguous_allow_conversion($input, PyArray_STRING, &is_new_object);
534     if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
535     $1 = (char**) malloc(array_size(array,0)*sizeof(char*));
536     $2 = array->strides[0];
537     for(int i=0;i<array_size(array,0);i++)
538       {
539         $1[i]=(char*) malloc(sizeof(char)*(array->strides[0]+1));
540         strncpy($1[i],(char*) array->data + i* array->strides[0],array->strides[0]);
541         *($1[i]+array->strides[0])='\0';
542       }
543 %#else
544     SWIG_exception(SWIG_TypeError, "string array expected");
545 %#endif
546   }
547   else
548   {
549     $1=sarray->data;
550     $2=sarray->size;
551   }
552 }
553
554 %typemap(freearg) (char** eval,int strSize) {
555 %#ifdef WITH_NUMPY
556   if (array$argnum)
557     {
558       for(int i=0;i<array_size(array$argnum,0);i++)
559         free($1[i]);
560       free($1);
561     }
562   if (is_new_object$argnum && array$argnum) 
563     {
564       Py_DECREF(array$argnum);
565     }
566 %#endif
567 }
568 /* End of array of strings on input */
569
570 /* inplace typemaps 
571    This typemap can be used for input/output array objects.
572    It accepts swig carray objects or numpy contiguous objects.
573 */
574
575 %define TYPEMAP_INPLACE3(type,typecode)
576 %typemap(in) type* INPLACE_ARRAY3 (ArrayObject* temp=NULL) {
577   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
578   {
579 %#ifdef WITH_NUMPY
580     temp = obj_to_array_no_conversion($input,typecode);
581     if (!temp  || !require_contiguous(temp)) SWIG_fail;
582     $1 = (type*) temp->data;
583 %#else
584     temp = NULL;
585     SWIG_exception(SWIG_TypeError, "type* expected");
586 %#endif
587   }
588 }
589 %enddef
590
591 TYPEMAP_INPLACE3(int,     PyArray_INT)
592 TYPEMAP_INPLACE3(long,    PyArray_LONG)
593 TYPEMAP_INPLACE3(float,   PyArray_FLOAT )
594 TYPEMAP_INPLACE3(double,  PyArray_DOUBLE)
595
596 #undef TYPEMAP_INPLACE3
597
598 %apply int*    INPLACE_ARRAY3 {int    *lval};
599 %apply long*   INPLACE_ARRAY3 {long   *lval};
600 %apply float*  INPLACE_ARRAY3 {float  *lval};
601 %apply double* INPLACE_ARRAY3 {double *lval};
602
603 /*  typemap for complex inout */
604 %typemap(in) float* lcpval
605              (ArrayObject* temp=NULL) {
606   if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
607   {
608 %#ifdef WITH_NUMPY
609     temp = obj_to_array_no_conversion($input,PyArray_CFLOAT);
610     if (!temp  || !require_contiguous(temp)) SWIG_fail;
611     $1 = (float*) temp->data;
612 %#else
613     temp = NULL;
614     SWIG_exception(SWIG_TypeError, "complex array expected");
615 %#endif
616   }
617 }
618 /*  End of typemap for complex inout */
619
620 /* typemap for array of strings on input/output */
621 %typemap(in) (char** lval,int strSize)
622             (ArrayObject* temp=NULL) {
623   stringArray* sarray;
624   if ((SWIG_ConvertPtr($input, (void **) &sarray, $descriptor(stringArray *) ,0)) == -1)
625   {
626 %#ifdef WITH_NUMPY
627     temp = obj_to_array_no_conversion($input,PyArray_STRING);
628     if (!temp  || !require_contiguous(temp)) SWIG_fail;
629     $1 = (char**) malloc(array_size(temp,0)*sizeof(char*));
630     $2 = temp->strides[0];
631     for(int i=0;i<array_size(temp,0);i++)
632       {
633         $1[i]=(char*) temp->data+i*temp->strides[0];
634         memset($1[i],0,temp->strides[0]); //numpy strings must be completed with 0 up to elsize
635       }
636 %#else
637     temp = NULL;
638     SWIG_exception(SWIG_TypeError, "string array expected");
639 %#endif
640   }
641   else
642   {
643     $1=sarray->data;
644     $2=sarray->size;
645   }
646 }
647 %typemap(freearg) (char** lval,int strSize) {
648 %#ifdef WITH_NUMPY
649   if (temp$argnum) free($1);
650 %#endif
651 }
652 /* End of typemap for array of strings on input/output */
653
654 %typemap(in) CORBA::Boolean
655 {
656   $1=(CORBA::Boolean)PyInt_AsLong($input);
657 }
658 %typemap(out) CORBA::Boolean
659 {
660   $result=PyInt_FromLong($1 ? 1 : 0);
661 }
662
663 %define CORBAPTR(type)
664 %typemap(in) type##_ptr
665 {
666   Py_BEGIN_ALLOW_THREADS
667   try
668   {
669      CORBA::Object_var obj = api->pyObjRefToCxxObjRef($input,0);
670      $1 = type##::_narrow(obj);
671   }
672   catch(...)
673   {
674      Py_BLOCK_THREADS
675      PyErr_SetString(PyExc_RuntimeError, "not a valid CORBA object ptr");
676   }
677   Py_END_ALLOW_THREADS
678 }
679 %typemap(freearg) type##_ptr {
680   CORBA::release($1);
681 }
682 %enddef
683
684 CORBAPTR(CORBA::ORB)
685 CORBAPTR(Ports::PortProperties)
686 CORBAPTR(Ports::Port)
687 CORBAPTR(Engines::Container)
688 CORBAPTR(PortableServer::POA)
689
690 %typemap(out) Ports::Port_ptr 
691 {
692   $result = api->cxxObjRefToPyObjRef($1, 1);
693   //All output Ports::Port_ptr variables are duplicated by security. Need to release them for python.
694   CORBA::release($1);
695 }
696
697 %typemap(out) Ports::PortProperties_ptr, Engines::Salome_file_ptr
698 {
699   $result = api->cxxObjRefToPyObjRef($1, 1);
700   //the _ptr is duplicated by the routine called. 
701   //Need to release it for Python because the call to cxxObjRefToPyObjRef has created another ref with a count of 1
702   CORBA::release($1);
703 }
704
705 %typemap(out) Engines::DSC::uses_port *
706 {
707    $result = PyList_New($1->length());
708    for (CORBA::ULong i=0; i < $1->length() ; i++)
709      PyList_SetItem($result,i,api->cxxObjRefToPyObjRef((*$1)[i], 1));
710    //delete the copy (created by new) of uses port sequence
711    delete $1;
712 }
713
714 /*
715  * Exception section
716  */
717 // a general exception handler
718 %exception {
719    Py_BEGIN_ALLOW_THREADS
720    try {
721       $action
722    }
723    catch(Engines::DSC::PortNotDefined& _e) {
724       Py_BLOCK_THREADS
725       PyObject* excc = PyObject_GetAttrString(dsc, "PortNotDefined");
726       PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL);
727       PyErr_SetObject(excc, exci);
728       Py_XDECREF(excc);
729       Py_XDECREF(exci);
730       return NULL;
731    }
732    catch(Engines::DSC::PortNotConnected& _e) {
733       Py_BLOCK_THREADS
734       PyObject* excc = PyObject_GetAttrString(dsc, "PortNotConnected");
735       PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL);
736       PyErr_SetObject(excc, exci);
737       Py_XDECREF(excc);
738       Py_XDECREF(exci);
739       return NULL;
740    }
741    catch(Engines::DSC::BadPortType& _e) {
742       Py_BLOCK_THREADS
743       PyObject* excc = PyObject_GetAttrString(dsc, "BadPortType");
744       PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL);
745       PyErr_SetObject(excc, exci);
746       Py_XDECREF(excc);
747       Py_XDECREF(exci);
748       return NULL;
749    }
750    catch (SALOME_Exception &e) {
751       Py_BLOCK_THREADS
752       PyErr_SetString(PyExc_RuntimeError,e.what());
753       return NULL;
754    }
755    catch (SALOME::SALOME_Exception &e) {
756       Py_BLOCK_THREADS
757       //This one should be converted into a python corba exception
758       PyErr_SetString(PyExc_RuntimeError,e.details.text);
759       return NULL;
760    }
761    catch (const CORBA::SystemException& e) {
762       Py_BLOCK_THREADS 
763       return api->handleCxxSystemException(e);
764    }
765    catch(...) {
766       Py_BLOCK_THREADS
767       PyErr_SetString(PyExc_ValueError,"Unknown exception");
768       return NULL;
769    }
770    Py_END_ALLOW_THREADS
771 }
772
773 /*
774  * End of Exception section
775  */
776 namespace Engines
777 {
778 class DSC
779 {
780   public:
781     enum Message { AddingConnection, RemovingConnection, ApplicationError };
782 };
783 }
784
785 class PySupervCompo:public Superv_Component_i
786 {
787   public:
788
789     PySupervCompo(CORBA::ORB_ptr orb,
790          PortableServer::POA_ptr poa,
791          Engines::Container_ptr contai,
792          const char *instanceName,
793          const char *interfaceName);
794
795     virtual ~PySupervCompo();
796     CORBA::Boolean init_service(const char * service_name){return true;};
797     virtual provides_port * create_provides_data_port(const char* port_fab_type)
798         throw (BadFabType);
799     virtual uses_port * create_uses_data_port(const char* port_fab_type)
800         throw (BadFabType);
801     virtual void add_port(const char * port_fab_type,
802         const char * port_type,
803         const char * port_name)
804         throw (PortAlreadyDefined, BadFabType, BadType, BadProperty);
805     template < typename SpecificPortType >
806     SpecificPortType * add_port(const char * port_fab_type,
807             const char * port_type,
808             const char * port_name)
809           throw (PortAlreadyDefined, BadFabType, BadType, BadCast, BadProperty);
810     virtual void add_port(provides_port * port,
811           const char* provides_port_name)
812           throw (PortAlreadyDefined, NilPort, BadProperty);
813     virtual void add_port(uses_port * port,
814           const char* uses_port_name)
815           throw (PortAlreadyDefined, NilPort, BadProperty);
816     template <typename SpecificPortType >
817     SpecificPortType * get_port( const char * port_name)
818           throw (PortNotDefined, PortNotConnected, BadCast, UnexpectedState);
819     virtual Ports::Port_ptr get_provides_port(const char* provides_port_name,
820               const CORBA::Boolean connection_error)
821               throw (Engines::DSC::PortNotDefined,
822                      Engines::DSC::PortNotConnected,
823                      Engines::DSC::BadPortType);
824     virtual void connect_uses_port(const char* uses_port_name,
825                          Ports::Port_ptr provides_port_ref)
826               throw (Engines::DSC::PortNotDefined,
827                      Engines::DSC::BadPortType,
828                      Engines::DSC::NilPort);
829     virtual void connect_provides_port(const char* provides_port_name)
830               throw (Engines::DSC::PortNotDefined);
831     virtual void disconnect_provides_port(const char* provides_port_name,
832               const Engines::DSC::Message message)
833               throw (Engines::DSC::PortNotDefined,
834                      Engines::DSC::PortNotConnected);
835
836     virtual void disconnect_uses_port(const char* uses_port_name,
837                   Ports::Port_ptr provides_port_ref,
838                   const Engines::DSC::Message message)
839               throw (Engines::DSC::PortNotDefined,
840                      Engines::DSC::PortNotConnected,
841                      Engines::DSC::BadPortReference);
842
843     virtual Ports::PortProperties_ptr get_port_properties(const char* port_name);
844
845 // Interface for Salome_file
846     Engines::Salome_file_ptr getInputFileToService(const char* service_name, const char* Salome_file_name);
847     void checkInputFilesToService(const char* service_name);
848     Engines::Salome_file_ptr setInputFileToService(const char* service_name, const char* Salome_file_name);
849     Engines::Salome_file_ptr getOutputFileToService(const char* service_name, const char* Salome_file_name);
850     void checkOutputFilesToService(const char* service_name);
851     Engines::Salome_file_ptr setOutputFileToService(const char* service_name, const char* Salome_file_name);
852 // End of Interface for Salome_file
853
854 // DSC interface for python components
855   virtual void add_provides_port(Ports::Port_ptr ref, const char* provides_port_name, Ports::PortProperties_ptr port_prop);
856   virtual void add_uses_port(const char* repository_id, const char* uses_port_name, Ports::PortProperties_ptr port_prop);
857   virtual Engines::DSC::uses_port * get_uses_port(const char* uses_port_name);
858   CORBA::Boolean is_connected(const char* port_name) throw (Engines::DSC::PortNotDefined);
859 // End of DSC interface for python components
860
861    static void setTimeOut();
862
863
864     %extend
865       {
866        //To get the address of the component
867         long ptr()
868         {
869           return (long)self;
870         }
871       }
872 };
873
874 %apply int *OUTPUT { int *nval };
875 %apply float *INOUT { float  *ti };
876 %apply float *INPUT { float  *tf };
877 %apply int *INOUT { int  *niter };
878 %apply double *INOUT { double  *ti };
879 %apply double *INPUT { double  *tf };
880
881 extern "C" void create_calcium_port(Superv_Component_i* compo,char* name,char* type,char *mode,char* depend);
882
883 %ignore CPMESSAGE;
884 %include "calciumP.h"
885
886 %cstring_bounded_output(char *instanceName, 1024);
887
888 int  cp_cd(Superv_Component_i *component,char *instanceName);
889
890 int cp_een(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,int    *eval);
891 int cp_edb(Superv_Component_i *component,int dep,double t,int n,char *nom,int nval,double *eval);
892 int cp_ere(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *eval);
893 int cp_erd(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *eval);
894 int cp_ecp(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *ecpval);
895 int cp_elo(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,int    *eval);
896 int cp_ech(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,char** eval,int strSize);
897 int cp_elg(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,long   *eval);
898 int cp_eln(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,long   *eval);
899
900
901 int cp_len(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,int    *lval);
902 int cp_ldb(Superv_Component_i *component,int dep,double *ti,double *tf,int *niter,char *nom,int nmax,int *nval,double *lval);
903 int cp_lre(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lval);
904 int cp_lrd(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lval);
905 int cp_lcp(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lcpval);
906 int cp_llo(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,int    *lval);
907 int cp_lch(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,char** lval,int strSize);
908 int cp_llg(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,long   *lval);
909 int cp_lln(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,long   *lval);
910
911 int cp_fini(Superv_Component_i *component,char *nom, int n);
912 int cp_fint(Superv_Component_i *component,char *nom, float t);
913 int cp_effi(Superv_Component_i *component,char *nom, int n);
914 int cp_efft(Superv_Component_i *component,char *nom, float t);
915
916 int cp_fin(Superv_Component_i *component,int cp_end);
917