Scicos gateways: fix memory leaks
[scilab.git] / scilab / modules / scicos / sci_gateway / cpp / sci_buildouttb.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014 - Scilab Enterprises - Paul Bignier
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 #include <cstring>
14 #include <string>
15 #include <algorithm>
16
17 #include "gw_scicos.hxx"
18
19 #include "internal.hxx"
20 #include "types.hxx"
21 #include "double.hxx"
22 #include "function.hxx"
23 #include "int.hxx"
24 #include "list.hxx"
25
26 extern "C"
27 {
28 #include "localization.h"
29 #include "Scierror.h"
30 }
31
32 /*--------------------------------------------------------------------------*/
33 /* intbuildouttb build an initialized outtb list
34 *
35 * [outtb]=buildouttb(lnksz,lnktyp)
36 *
37 * rhs 1 : lnksz, give the size of scilab object in outtb
38 * can be all int type or double matrix
39 * can have n,2 or 2,n size
40 *
41 * rhs 2 : lnktyp, gives the type of scilab object in outtb
42 * 1 : double
43 * 2 : complex
44 * 3 : int32
45 * 4 : int16
46 * 5 : int8
47 * 6 : uint32
48 * 7 : uint16
49 * 8 : uint8
50 * else : double
51 * can be all int type or double matrix
52 * can have n,1 or 1,n size
53 *
54 * lhs 1 : a list of size n
55 *
56 * 02/07/06, Alan : Initial version.
57 * 21/11/06, Alan : Allow void rhs input param.
58 * 05/12/14, Paul : Rewrite to C++.
59 *
60 */
61 /*--------------------------------------------------------------------------*/
62
63 static const std::string funname = "buildouttb";
64
65 types::Function::ReturnValue sci_buildouttb(types::typed_list &in, int _iRetCount, types::typed_list &out)
66 {
67     if (in.size() != 2)
68     {
69         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), funname.data(), 2);
70         return types::Function::Error;
71     }
72
73     if (_iRetCount > 1)
74     {
75         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), funname.data(), 1);
76         return types::Function::Error;
77     }
78
79     int m1, n1, mn1;
80     int* p1Copy;
81     int m2, n2, mn2;
82     int* p2Copy;
83
84     switch (in[0]->getType())
85     {
86         case types::InternalType::ScilabDouble:
87         {
88             types::Double* p1D = in[0]->getAs<types::Double>();
89             if (p1D->isComplex())
90             {
91                 Scierror(999, _("%s: Wrong type for input argument #%d : A real or integer matrix expected.\n"), funname.data(), 1);
92                 return types::Function::Error;
93             }
94             m1 = p1D->getRows();
95             n1 = p1D->getCols();
96             mn1 = m1 * n1;
97
98             p1Copy = new int[mn1];
99             for (int i = 0; i < mn1; ++i)
100             {
101                 p1Copy[i] = static_cast<int>(p1D->get(i));
102             }
103             break;
104         }
105         case types::InternalType::ScilabInt8:
106         {
107             types::Int8* p1Int8 = in[0]->getAs<types::Int8>();
108             m1 = p1Int8->getRows();
109             n1 = p1Int8->getCols();
110             mn1 = m1 * n1;
111
112             char* buffer = new char[mn1];
113             memcpy(buffer, p1Int8->get(), mn1 * sizeof(char));
114             p1Copy = new int[mn1];
115             memcpy(p1Copy, buffer, mn1 * sizeof(int));
116             delete[] buffer;
117             break;
118         }
119         case types::InternalType::ScilabInt16:
120         {
121             types::Int16* p1Int16 = in[0]->getAs<types::Int16>();
122             m1 = p1Int16->getRows();
123             n1 = p1Int16->getCols();
124             mn1 = m1 * n1;
125
126             char* buffer = new char[mn1];
127             memcpy(buffer, p1Int16->get(), mn1 * sizeof(char));
128             p1Copy = new int[mn1];
129             memcpy(p1Copy, buffer, mn1 * sizeof(int));
130             delete[] buffer;
131             break;
132         }
133         case types::InternalType::ScilabInt32:
134         {
135             types::Int32* p1Int32 = in[0]->getAs<types::Int32>();
136             m1 = p1Int32->getRows();
137             n1 = p1Int32->getCols();
138             mn1 = m1 * n1;
139
140             char* buffer = new char[mn1];
141             memcpy(buffer, p1Int32->get(), mn1 * sizeof(char));
142             p1Copy = new int[mn1];
143             memcpy(p1Copy, buffer, mn1 * sizeof(int));
144             delete[] buffer;
145             break;
146         }
147         case types::InternalType::ScilabUInt8:
148         {
149             types::UInt8* p1UInt8 = in[0]->getAs<types::UInt8>();
150             m1 = p1UInt8->getRows();
151             n1 = p1UInt8->getCols();
152             mn1 = m1 * n1;
153
154             char* buffer = new char[mn1];
155             memcpy(buffer, p1UInt8->get(), mn1 * sizeof(char));
156             p1Copy = new int[mn1];
157             memcpy(p1Copy, buffer, mn1 * sizeof(int));
158             delete[] buffer;
159             break;
160         }
161         case types::InternalType::ScilabUInt16:
162         {
163             types::UInt16* p1UInt16 = in[0]->getAs<types::UInt16>();
164             m1 = p1UInt16->getRows();
165             n1 = p1UInt16->getCols();
166             mn1 = m1 * n1;
167
168             char* buffer = new char[mn1];
169             memcpy(buffer, p1UInt16->get(), mn1 * sizeof(char));
170             p1Copy = new int[mn1];
171             memcpy(p1Copy, buffer, mn1 * sizeof(int));
172             delete[] buffer;
173             break;
174         }
175         case types::InternalType::ScilabUInt32:
176         {
177             types::UInt32* p1UInt32 = in[0]->getAs<types::UInt32>();
178             m1 = p1UInt32->getRows();
179             n1 = p1UInt32->getCols();
180             mn1 = m1 * n1;
181
182             char* buffer = new char[mn1];
183             memcpy(buffer, p1UInt32->get(), mn1 * sizeof(char));
184             p1Copy = new int[mn1];
185             memcpy(p1Copy, buffer, mn1 * sizeof(int));
186             delete[] buffer;
187             break;
188         }
189         default:
190         {
191             Scierror(999, _("%s: Wrong type for input argument #%d : A real or integer matrix expected.\n"), funname.data(), 1);
192             return types::Function::Error;
193         }
194     }
195
196     switch (in[1]->getType())
197     {
198         case types::InternalType::ScilabDouble:
199         {
200             types::Double* p2D = in[1]->getAs<types::Double>();
201             if (p2D->isComplex())
202             {
203                 Scierror(999, _("%s: Wrong type for input argument #%d : A real or integer matrix expected.\n"), funname.data(), 2);
204                 delete[] p1Copy;
205                 return types::Function::Error;
206             }
207             m2 = p2D->getRows();
208             n2 = p2D->getCols();
209             mn2 = m2 * n2;
210
211             p2Copy = new int[mn2];
212             for (int i = 0; i < mn2; ++i)
213             {
214                 p2Copy[i] = static_cast<int>(p2D->get(i));
215             }
216             break;
217         }
218         case types::InternalType::ScilabInt8:
219         {
220             types::Int8* p2Int8 = in[1]->getAs<types::Int8>();
221             m2 = p2Int8->getRows();
222             n2 = p2Int8->getCols();
223             mn2 = m2 * n2;
224
225             char* buffer = new char[mn2];
226             memcpy(buffer, p2Int8->get(), mn2 * sizeof(char));
227             p2Copy = new int[mn2];
228             memcpy(p2Copy, buffer, mn2 * sizeof(int));
229             delete[] buffer;
230             break;
231         }
232         case types::InternalType::ScilabInt16:
233         {
234             types::Int16* p2Int16 = in[1]->getAs<types::Int16>();
235             m2 = p2Int16->getRows();
236             n2 = p2Int16->getCols();
237             mn2 = m2 * n2;
238
239             short* buffer = new short[mn2];
240             memcpy(buffer, p2Int16->get(), mn2 * sizeof(short));
241             p2Copy = new int[mn2];
242             memcpy(p2Copy, buffer, mn2 * sizeof(int));
243             delete[] buffer;
244             break;
245         }
246         case types::InternalType::ScilabInt32:
247         {
248             types::Int32* p2Int32 = in[1]->getAs<types::Int32>();
249             m2 = p2Int32->getRows();
250             n2 = p2Int32->getCols();
251             mn2 = m2 * n2;
252
253             p2Copy = new int[mn2];
254             memcpy(p2Copy, p2Int32->get(), mn2 * sizeof(int));
255             break;
256         }
257         case types::InternalType::ScilabUInt8:
258         {
259             types::UInt8* p2UInt8 = in[1]->getAs<types::UInt8>();
260             m2 = p2UInt8->getRows();
261             n2 = p2UInt8->getCols();
262             mn2 = m2 * n2;
263
264             unsigned char* buffer = new unsigned char[mn2];
265             memcpy(buffer, p2UInt8->get(), mn2 * sizeof(unsigned char));
266             p2Copy = new int[mn2];
267             memcpy(p2Copy, buffer, mn2 * sizeof(int));
268             delete[] buffer;
269             break;
270         }
271         case types::InternalType::ScilabUInt16:
272         {
273             types::UInt16* p2UInt16 = in[1]->getAs<types::UInt16>();
274             m2 = p2UInt16->getRows();
275             n2 = p2UInt16->getCols();
276             mn2 = m2 * n2;
277
278             unsigned short* buffer = new unsigned short[mn2];
279             memcpy(buffer, p2UInt16->get(), mn2 * sizeof(unsigned short));
280             p2Copy = new int[mn2];
281             memcpy(p2Copy, buffer, mn2 * sizeof(int));
282             delete[] buffer;
283             break;
284         }
285         case types::InternalType::ScilabUInt32:
286         {
287             types::UInt32* p2UInt32 = in[1]->getAs<types::UInt32>();
288             m2 = p2UInt32->getRows();
289             n2 = p2UInt32->getCols();
290             mn2 = m2 * n2;
291
292             p2Copy = new int[mn2];
293             memcpy(p2Copy, p2UInt32->get(), mn2 * sizeof(int));
294             break;
295         }
296         default:
297         {
298             Scierror(999, _("%s: Wrong type for input argument #%d : A real or integer matrix expected.\n"), funname.data(), 2);
299             delete[] p1Copy;
300             return types::Function::Error;
301         }
302     }
303
304     types::List* pOut = new types::List();
305
306     // Check size of Rhs 1
307     int np1 = 0;
308     if (m1 == 2)
309     {
310         np1 = n1;
311     }
312     else if (n1 == 2)
313     {
314         np1 = m1;
315     }
316     // void double input give void list output
317     else if ((n1 == 0) || (m1 == 0))
318     {
319         if ((n2 == 0) || (m2 == 0))
320         {
321             out.push_back(pOut);
322             delete[] p1Copy;
323             delete[] p2Copy;
324             return types::Function::OK;
325         }
326         else
327         {
328             Scierror(888, _("%s : inconsistent dimensions between arguments.\n"), funname.data());
329             delete[] p1Copy;
330             delete[] p2Copy;
331             delete pOut;
332             return types::Function::Error;
333         }
334     }
335     else
336     {
337         Scierror(888, _("%s : bad dimension for argument #%d.\n"), funname.data(), 1);
338         delete[] p1Copy;
339         delete[] p2Copy;
340         delete pOut;
341         return types::Function::Error;
342     }
343
344     // Check size of Rhs 2
345     int np2 = 0;
346     if (m2 == 1)
347     {
348         np2 = n2;
349     }
350     else if (n2 == 1)
351     {
352         np2 = m2;
353     }
354     else if ((n2 == 0) || (m2 == 0))
355     {
356         if ( (n1 != 0) && (m1 != 0) )
357         {
358             Scierror(888, _("%s : inconsistent dimensions between arguments.\n"), funname.data());
359             delete[] p1Copy;
360             delete[] p2Copy;
361             delete pOut;
362             return types::Function::Error;
363         }
364     }
365     else
366     {
367         Scierror(888, _("%s : bad dimension for argument #%d.\n"), funname.data(), 2);
368         delete[] p1Copy;
369         delete[] p2Copy;
370         delete pOut;
371         return types::Function::Error;
372     }
373
374     // Cross size checking
375     if (np1 != np2)
376     {
377         Scierror(888, _("%s : arguments must have the same length.\n"), funname.data());
378         delete[] p1Copy;
379         delete[] p2Copy;
380         delete pOut;
381         return types::Function::Error;
382     }
383
384     for (int i = 0; i < np2; ++i)
385     {
386         int nm = p1Copy[i] * p1Copy[i + np2];
387         switch (p2Copy[i])
388         {
389             case 1  :
390             {
391                 double* data;
392                 types::Double* pOutD = new types::Double(p1Copy[i], p1Copy[i + np2], &data);
393                 for (int j = 0; j < nm; ++j)
394                 {
395                     data[j] = 0;
396                 }
397                 pOut->set(i, pOutD);
398                 break;
399             }
400             case 2  :
401             {
402                 double* data;
403                 double* dataComplex;
404                 types::Double* pOutDC = new types::Double(p1Copy[i], p1Copy[i + np2], &data, &dataComplex);
405                 for (int j = 0; j < nm; ++j)
406                 {
407                     data[j] = 0;
408                     dataComplex[j] = 0;
409                 }
410                 pOut->set(i, pOutDC);
411                 break;
412             }
413             case 3  :
414             {
415                 int* data;
416                 types::Int32* pOutInt32 = new types::Int32(p1Copy[i], p1Copy[i + np2], &data);
417                 for (int j = 0; j < nm; ++j)
418                 {
419                     data[j] = 0;
420                 }
421                 pOut->set(i, pOutInt32);
422                 break;
423             }
424             case 4  :
425             {
426                 short* data;
427                 types::Int16* pOutInt16 = new types::Int16(p1Copy[i], p1Copy[i + np2], &data);
428                 for (int j = 0; j < nm; ++j)
429                 {
430                     data[j] = 0;
431                 }
432                 pOut->set(i, pOutInt16);
433                 break;
434             }
435             case 5  :
436             {
437                 char* data;
438                 types::Int8* pOutInt8 = new types::Int8(p1Copy[i], p1Copy[i + np2], &data);
439                 for (int j = 0; j < nm; ++j)
440                 {
441                     data[j] = 0;
442                 }
443                 pOut->set(i, pOutInt8);
444                 break;
445             }
446             case 6  :
447             {
448                 unsigned int* data;
449                 types::UInt32* pOutUInt32 = new types::UInt32(p1Copy[i], p1Copy[i + np2], &data);
450                 for (int j = 0; j < nm; ++j)
451                 {
452                     data[j] = 0;
453                 }
454                 pOut->set(i, pOutUInt32);
455                 break;
456             }
457             case 7  :
458             {
459                 unsigned short* data;
460                 types::UInt16* pOutUInt16 = new types::UInt16(p1Copy[i], p1Copy[i + np2], &data);
461                 for (int j = 0; j < nm; ++j)
462                 {
463                     data[j] = 0;
464                 }
465                 pOut->set(i, pOutUInt16);
466                 break;
467             }
468             case 8  :
469             {
470                 unsigned char* data;
471                 types::UInt8* pOutUInt8 = new types::UInt8(p1Copy[i], p1Copy[i + np2], &data);
472                 for (int j = 0; j < nm; ++j)
473                 {
474                     data[j] = 0;
475                 }
476                 pOut->set(i, pOutUInt8);
477                 break;
478             }
479             default:
480             {
481                 // By default, apply case 1
482                 double* data;
483                 types::Double* pOutD = new types::Double(p1Copy[i], p1Copy[i + np2], &data);
484                 for (int j = 0; j < nm; ++j)
485                 {
486                     data[j] = 0;
487                 }
488                 pOut->set(i, pOutD);
489                 break;
490             }
491         }
492     }
493
494     out.push_back(pOut);
495
496     delete[] p1Copy;
497     delete[] p2Copy;
498
499     return types::Function::OK;
500 }