Salome HOME
Major refactoring in classes Versatile, Parametre and Swig wrappings.
[tools/libbatch.git] / src / Python / libBatch_Swig_typemap.i
1 //  Copyright (C) 2007-2011  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.
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 "Batch_ParameterTypeMap.hxx"
36 #include "Batch_Parametre.hxx"
37 #include "Batch_JobId.hxx"
38 #include "Batch_FactBatchManager.hxx"
39 #include "Batch_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 (PyString_Check(val)) {
53         newVersatile += PyString_AsString(val);
54
55       } else if (PyTuple_Check(val) &&
56           (PyTuple_Size(val) == 2) &&
57           PyString_Check( PyTuple_GetItem(val,0) ) &&
58           PyString_Check( PyTuple_GetItem(val,1) )   ) {
59         newVersatile += Batch::Couple( PyString_AsString( PyTuple_GetItem(val,0) ),
60                                        PyString_AsString( PyTuple_GetItem(val,1) )
61                                      );
62
63       } else {
64         PyErr_SetString(PyExc_RuntimeWarning, "initVersatile : invalid PyObject");
65         return false;
66       }
67     }
68
69   } else if (PyString_Check(input)) { // c'est une string
70     newVersatile = PyString_AsString(input);
71   } else if (PyInt_Check(input)) { // c'est un int
72     newVersatile = PyInt_AsLong(input);
73   } else if (PyBool_Check(input)) { // c'est un bool
74     newVersatile = (input == Py_True);
75   } else { // erreur
76     PyErr_SetString(PyExc_RuntimeWarning, "initVersatile : invalid PyObject");
77     return false;
78   }
79   return true;
80 }
81
82 // Helper function to create a PyObj from a Batch::Versatile
83 static PyObject * versatileToPyObj(const Batch::Versatile & vers)
84 {
85   PyObject * obj;
86
87   if (vers.getMaxSize() != 1) { // une liste
88     obj = PyList_New(0);
89     for(Batch::Versatile::const_iterator it=vers.begin(); it!=vers.end(); it++) {
90       std::string st;
91       Batch::Couple cp;
92       switch (vers.getType()) {
93       case Batch::LONG:
94         PyList_Append(obj, PyInt_FromLong(* static_cast<Batch::LongType *>(*it)));
95         break;
96
97       case Batch::STRING:
98         st = * static_cast<Batch::StringType *>(*it);
99         PyList_Append(obj, PyString_FromString(st.c_str()));
100         break;
101
102       case Batch::COUPLE:
103         cp = * static_cast<Batch::CoupleType *>(*it);
104         PyList_Append(obj, Py_BuildValue("(ss)", cp.getLocal().c_str(), cp.getRemote().c_str() ));
105         break;
106
107       default:
108         throw Batch::RunTimeException("Versatile object cannot be converted to Python object");
109       }
110
111     }
112
113   } else {
114     bool b;
115     std::string st;
116     Batch::Couple cp;
117     switch (vers.getType()) {
118     case Batch::BOOL:
119       b = (* static_cast<Batch::BoolType *>(vers.front()));
120       obj = PyBool_FromLong(b);
121       break;
122
123     case Batch::LONG:
124       obj = PyInt_FromLong(* static_cast<Batch::LongType *>(vers.front()));
125       break;
126
127     case Batch::STRING:
128       st = * static_cast<Batch::StringType *>(vers.front());
129       obj = PyString_FromString(st.c_str());
130       break;
131
132     case Batch::COUPLE:
133       cp = * static_cast<Batch::CoupleType *>(vers.front());
134       obj = Py_BuildValue("[(ss)]", cp.getLocal().c_str(), cp.getRemote().c_str() );
135       break;
136
137     default:
138       throw Batch::RunTimeException("Versatile object cannot be converted to Python object");
139     }
140   }
141
142   return obj;
143 }
144
145 // Helper function to initialize a Batch::Parametre from a PyObj
146 static bool initParameter(Batch::Parametre & newParam, PyObject * input)
147 {
148   if (!PyDict_Check(input)) {
149     PyErr_SetString(PyExc_ValueError, "Expected a dictionnary");
150     return false;
151   }
152
153   try {
154     // on itere sur toutes les clefs du dictionnaire, et on passe par la classe PyVersatile
155     // qui convertit un Versatile en PyObject et vice versa
156     PyObject *key, *value;
157     Py_ssize_t pos = 0;
158     while (PyDict_Next(input, &pos, &key, &value)) {
159       std::string mk = PyString_AsString(key);
160       bool res = initVersatile(newParam[mk], value);
161       if (!res)
162         return false;
163     }
164   }
165   catch (Batch::GenericException & ex) {
166       std::string msg = ex.type + " : " + ex.message;
167       PyErr_SetString(PyExc_RuntimeWarning, msg.c_str());
168       return false;
169   }
170   catch (...) {
171       PyErr_SetString(PyExc_RuntimeWarning, "unknown exception");
172       return false;
173   }
174   return true;
175 }
176
177 // Helper function to initialize a Batch::Environnement from a PyObj
178 static bool initEnvironment(Batch::Environnement & newEnv, PyObject * input)
179 {
180   if (!PyDict_Check(input)) {
181     PyErr_SetString(PyExc_ValueError, "Expected a dictionnary");
182     return false;
183   }
184
185   // on itere sur toutes les clefs du dictionnaire
186   PyObject *key, *value;
187   Py_ssize_t pos = 0;
188   while (PyDict_Next(input, &pos, &key, &value)) {
189     std::string mk  = PyString_AsString(key);
190     std::string val = PyString_AsString(value);
191     newEnv[mk] = val;
192   }
193   return true;
194 }
195 %}
196
197 # // construction d'un dictionnaire Python a partir d'un objet BatchManagerCatalog C++
198 %typemap(out) std::map<std::string, Batch::FactBatchManager *> *
199 {
200   $result = PyDict_New();
201
202   // on itere sur toutes les clefs de la map
203   for(std::map<std::string, Batch::FactBatchManager *>::const_iterator it=(* $1).begin(); it!=(* $1).end(); it++) {
204     std::string key = (*it).first;
205     PyObject * obj  = SWIG_NewPointerObj((void *) (*it).second, SWIGTYPE_p_Batch__FactBatchManager, 0);
206     PyDict_SetItem($result, PyString_FromString(key.c_str()), obj);
207   }
208 }
209
210 %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) Batch::Parametre
211 {
212   $1 = PyDict_Check($input)? 1 : 0;
213 }
214
215 # // construction d'un dictionnaire Python a partir d'un objet Parametre C++
216 %typemap(out) Batch::Parametre
217 {
218   $result = PyDict_New();
219
220   // on itere sur toutes les clefs de la map, et on passe par la classe PyVersatile
221         // qui convertit un Versatile en PyObject et vice versa
222   for(Batch::Parametre::const_iterator it=$1.begin(); it!=$1.end(); it++) {
223     const std::string & key = (*it).first;
224     const Batch::Versatile & vers = (*it).second;
225     PyDict_SetItem($result, PyString_FromString(key.c_str()), versatileToPyObj(vers));
226   }
227 }
228
229 // Build a C++ object Batch::Parametre from a Python dictionary
230 %typemap(in) const Batch::Parametre & (Batch::Parametre PM)
231 {
232   bool res = initParameter(PM, $input);
233   if (res)
234     $1 = &PM;
235   else
236     return NULL;
237 }
238
239 %typemap(in) Batch::Parametre
240 {
241   bool res = initParameter($1, $input);
242   if (!res) return NULL;
243 }
244
245 %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) Batch::Environnement
246 {
247   $1 = PyDict_Check($input)? 1 : 0;
248 }
249
250 # // construction d'un dictionnaire Python a partir d'un objet Environnement C++
251 %typemap(out) Batch::Environnement
252 {
253   $result = PyDict_New();
254
255   // on itere sur toutes les clefs de la map
256   for(Batch::Environnement::const_iterator it=$1.begin(); it!=$1.end(); it++) {
257     std::string key = (*it).first;
258     std::string val = (*it).second;
259     PyDict_SetItem($result, 
260                    PyString_FromString(key.c_str()),
261                    PyString_FromString(val.c_str()));
262   }
263 }
264
265 // Build a C++ object Batch::Environnement from a Python dictionary
266 %typemap(in) const Batch::Environnement & (Batch::Environnement E)
267 {
268   bool res = initEnvironment(E, $input);
269   if (res)
270     $1 = &E;
271   else
272     return NULL;
273 }
274
275 %typemap(in) Batch::Environnement
276 {
277   bool res = initEnvironment($1, $input);
278   if (!res) return NULL;
279 }
280
281 // Dynamic cast to FactBatchManager_eClient if necessary
282 %typemap(out) Batch::FactBatchManager *
283 {
284   if(dynamic_cast<Batch::FactBatchManager_eClient *>($1))
285     $result=SWIG_NewPointerObj((void*)$1,$descriptor(Batch::FactBatchManager_eClient *),$owner);
286   else
287     $result=SWIG_NewPointerObj((void*)$1,$descriptor(Batch::FactBatchManager *),$owner);
288 }