Salome HOME
Copyright update 2021
[tools/libbatch.git] / src / Python / libBatch_Swig_typemap.i
1 // Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 /*
23  * _typemap.i : 
24  *
25  * Auteur : Ivan DUTKA-MALEN - EDF R&D
26  * Date   : Septembre 2003
27  * Projet : SALOME 2
28  *
29  */
30
31 %{
32 #include <string>
33 #include <list>
34 #include <map>
35 #include "ParameterTypeMap.hxx"
36 #include "Parametre.hxx"
37 #include "JobId.hxx"
38 #include "FactBatchManager.hxx"
39 #include "RunTimeException.hxx"
40 %}
41
42 # // supprime toutes les definitions par defaut => sert au debug
43 # %typemap(in) SWIGTYPE ;
44
45 %{
46 // Helper function to initialize a Batch::Versatile from a PyObj
47 static bool initVersatile(Batch::Versatile & newVersatile, PyObject * input)
48 {
49   if (PyList_Check(input)) { // c'est une liste
50     for (Py_ssize_t i=0; i<PyList_Size(input); i++) {
51       PyObject * val = PyList_GetItem(input, i);
52       if (PyUnicode_Check(val)) {
53         newVersatile += PyUnicode_AsUTF8(val);
54       } else if (PyTuple_Check(val) &&
55           (PyTuple_Size(val) == 2) &&
56           PyUnicode_Check( PyTuple_GetItem(val,0) ) &&
57           PyUnicode_Check( PyTuple_GetItem(val,1) )   ) {
58         newVersatile += Batch::Couple( PyUnicode_AsUTF8(PyTuple_GetItem(val,0)),
59                                        PyUnicode_AsUTF8(PyTuple_GetItem(val,1)));
60
61       } else {
62         PyErr_SetString(PyExc_RuntimeWarning, "initVersatile : invalid PyObject");
63         return false;
64       }
65     }
66
67   } else if (PyUnicode_Check(input)) { // c'est une string
68     newVersatile = PyUnicode_AsUTF8(input);
69   } else if (PyBool_Check(input)) { // c'est un bool
70     newVersatile = (input == Py_True);
71   } else if (PyInt_Check(input)) { // c'est un int
72     newVersatile = PyInt_AsLong(input);
73   } else { // erreur
74     PyErr_SetString(PyExc_RuntimeWarning, "initVersatile : invalid PyObject");
75     return false;
76   }
77   return true;
78 }
79
80 // Helper function to create a PyObj from a Batch::Versatile
81 static PyObject * versatileToPyObj(const Batch::Versatile & vers)
82 {
83   PyObject * obj;
84
85   if (vers.getMaxSize() != 1) { // une liste
86     obj = PyList_New(0);
87     for(Batch::Versatile::const_iterator it=vers.begin(); it!=vers.end(); it++) {
88       std::string st;
89       Batch::Couple cp;
90       switch (vers.getType()) {
91       case Batch::LONG:
92         PyList_Append(obj, PyInt_FromLong(* static_cast<Batch::LongType *>(*it)));
93         break;
94
95       case Batch::STRING:
96         st = * static_cast<Batch::StringType *>(*it);
97         PyList_Append(obj, PyString_FromString(st.c_str()));
98         break;
99
100       case Batch::COUPLE:
101         cp = * static_cast<Batch::CoupleType *>(*it);
102         PyList_Append(obj, Py_BuildValue("(ss)", cp.getLocal().c_str(), cp.getRemote().c_str() ));
103         break;
104
105       default:
106         throw Batch::RunTimeException("Versatile object cannot be converted to Python object");
107       }
108
109     }
110
111   } else {
112     bool b;
113     std::string st;
114     Batch::Couple cp;
115     switch (vers.getType()) {
116     case Batch::BOOL:
117       b = (* static_cast<Batch::BoolType *>(vers.front()));
118       obj = PyBool_FromLong(b);
119       break;
120
121     case Batch::LONG:
122       obj = PyInt_FromLong(* static_cast<Batch::LongType *>(vers.front()));
123       break;
124
125     case Batch::STRING:
126       st = * static_cast<Batch::StringType *>(vers.front());
127       obj = PyString_FromString(st.c_str());
128       break;
129
130     case Batch::COUPLE:
131       cp = * static_cast<Batch::CoupleType *>(vers.front());
132       obj = Py_BuildValue("[(ss)]", cp.getLocal().c_str(), cp.getRemote().c_str() );
133       break;
134
135     default:
136       throw Batch::RunTimeException("Versatile object cannot be converted to Python object");
137     }
138   }
139
140   return obj;
141 }
142
143 // Helper function to initialize a Batch::Parametre from a PyObj
144 static bool initParameter(Batch::Parametre & newParam, PyObject * input)
145 {
146   if (!PyDict_Check(input)) {
147     PyErr_SetString(PyExc_ValueError, "Expected a dictionnary");
148     return false;
149   }
150
151   try {
152     // on itere sur toutes les clefs du dictionnaire, et on passe par la classe PyVersatile
153     // qui convertit un Versatile en PyObject et vice versa
154     PyObject *key, *value;
155     Py_ssize_t pos = 0;
156     while (PyDict_Next(input, &pos, &key, &value)) {
157       std::string mk = PyUnicode_AsUTF8(key);
158       bool res = initVersatile(newParam[mk], value);
159       if (!res)
160         return false;
161     }
162   }
163   catch (Batch::GenericException & ex) {
164       std::string msg = ex.type + " : " + ex.message;
165       PyErr_SetString(PyExc_RuntimeWarning, msg.c_str());
166       return false;
167   }
168   catch (...) {
169       PyErr_SetString(PyExc_RuntimeWarning, "unknown exception");
170       return false;
171   }
172   return true;
173 }
174
175 // Helper function to initialize a Batch::Environnement from a PyObj
176 static bool initEnvironment(Batch::Environnement & newEnv, PyObject * input)
177 {
178   if (!PyDict_Check(input)) {
179     PyErr_SetString(PyExc_ValueError, "Expected a dictionnary");
180     return false;
181   }
182
183   // on itere sur toutes les clefs du dictionnaire
184   PyObject *key, *value;
185   Py_ssize_t pos = 0;
186   while (PyDict_Next(input, &pos, &key, &value)) {
187     std::string mk  = PyUnicode_AsUTF8(key);
188     std::string val = PyUnicode_AsUTF8(value);
189     newEnv[mk] = val;
190   }
191   return true;
192 }
193 %}
194
195 # // construction d'un dictionnaire Python a partir d'un objet BatchManagerCatalog C++
196 %typemap(out) std::map<std::string, Batch::FactBatchManager *> *
197 {
198   $result = PyDict_New();
199
200   // on itere sur toutes les clefs de la map
201   for(std::map<std::string, Batch::FactBatchManager *>::const_iterator it=(* $1).begin(); it!=(* $1).end(); it++) {
202     std::string key = (*it).first;
203     PyObject * obj  = SWIG_NewPointerObj((void *) (*it).second, SWIGTYPE_p_Batch__FactBatchManager, 0);
204     PyDict_SetItem($result, PyString_FromString(key.c_str()), obj);
205   }
206 }
207
208 %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) Batch::Parametre
209 {
210   $1 = PyDict_Check($input)? 1 : 0;
211 }
212
213 # // construction d'un dictionnaire Python a partir d'un objet Parametre C++
214 %typemap(out) Batch::Parametre
215 {
216   $result = PyDict_New();
217
218   // on itere sur toutes les clefs de la map, et on passe par la classe PyVersatile
219         // qui convertit un Versatile en PyObject et vice versa
220   for(Batch::Parametre::const_iterator it=$1.begin(); it!=$1.end(); it++) {
221     const std::string & key = (*it).first;
222     const Batch::Versatile & vers = (*it).second;
223     PyDict_SetItem($result, PyString_FromString(key.c_str()), versatileToPyObj(vers));
224   }
225 }
226
227 // Build a C++ object Batch::Parametre from a Python dictionary
228 %typemap(in) const Batch::Parametre & (Batch::Parametre PM)
229 {
230   bool res = initParameter(PM, $input);
231   if (res)
232     $1 = &PM;
233   else
234     return NULL;
235 }
236
237 %typemap(in) Batch::Parametre
238 {
239   bool res = initParameter($1, $input);
240   if (!res) return NULL;
241 }
242
243 %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) Batch::Environnement
244 {
245   $1 = PyDict_Check($input)? 1 : 0;
246 }
247
248 # // construction d'un dictionnaire Python a partir d'un objet Environnement C++
249 %typemap(out) Batch::Environnement
250 {
251   $result = PyDict_New();
252
253   // on itere sur toutes les clefs de la map
254   for(Batch::Environnement::const_iterator it=$1.begin(); it!=$1.end(); it++) {
255     std::string key = (*it).first;
256     std::string val = (*it).second;
257     PyDict_SetItem($result, 
258                    PyString_FromString(key.c_str()),
259                    PyString_FromString(val.c_str()));
260   }
261 }
262
263 // Build a C++ object Batch::Environnement from a Python dictionary
264 %typemap(in) const Batch::Environnement & (Batch::Environnement E)
265 {
266   bool res = initEnvironment(E, $input);
267   if (res)
268     $1 = &E;
269   else
270     return NULL;
271 }
272
273 %typemap(in) Batch::Environnement
274 {
275   bool res = initEnvironment($1, $input);
276   if (!res) return NULL;
277 }