Coverity: Matio module memory leaks fixed
[scilab.git] / scilab / modules / matio / src / cpp / CreateMatlabTreeVariable.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent COUVERT
4  * Copyright (C) 2010 - DIGITEO - Yann COLLETTE
5  * Copyright (C) 2015 - Scilab Enterprises - Sylvain GENIN
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18 #include "CreateMatlabTreeVariable.hxx"
19 #include "cell.hxx"
20 #include "struct.hxx"
21 #include "string.hxx"
22 #include "sparse.hxx"
23 #include "int.hxx"
24
25 extern "C"
26 {
27 #include "CreateMatlabVariable.h"
28 #include "api_scilab.h"
29 #include "Scierror.h"
30 }
31
32 types::InternalType* CreateMatlabTreeVariable(matvar_t *matVariable)
33 {
34     types::InternalType* pOut = NULL;
35     /* To be sure isComplex is 0 or 1 */
36     bool isComplex = (matVariable->isComplex != 0);
37     int* piDims = NULL;
38
39     int iRank = matVariable->rank;
40     if (iRank != 0)
41     {
42         if (iRank == 1)
43         {
44             iRank = 2;
45             piDims = (int *)MALLOC(iRank * sizeof(int));
46             piDims[0] = (int)matVariable->dims[0];
47             piDims[1] = 1;
48         }
49         else
50         {
51             piDims = (int *)MALLOC(iRank * sizeof(int));
52
53             for (int i = 0; i < iRank; ++i)
54             {
55                 piDims[i] = (int)matVariable->dims[i];
56             }
57         }
58     }
59
60     if (!piDims)
61     {
62         return types::Double::Empty();
63     }
64
65     switch (matVariable->class_type)
66     {
67         case MAT_C_CELL: /* 1 */
68         {
69
70             if ((iRank == 2) && ((piDims[0] * piDims[1]) <= 0))
71             {
72                 pOut = new types::Cell();
73             }
74             else
75             {
76                 pOut = new types::Cell(iRank, piDims);
77
78                 matvar_t** allData = (matvar_t**)(matVariable->data);
79                 int iSize = pOut->getAs<types::Cell>()->getSize();
80                 types::InternalType** ppIT = new types::InternalType*[iSize];
81                 for (int i = 0; i < iSize; i++)
82                 {
83                     ppIT[i] = CreateMatlabTreeVariable(allData[i]);
84                 }
85
86                 pOut->getAs<types::Cell>()->set(ppIT);
87             }
88
89         }
90         break;
91         case MAT_C_STRUCT: /* 2 */
92         {
93             if (matVariable->data == NULL)
94             {
95                 pOut = new types::Struct();
96             }
97             else
98             {
99                 pOut = new types::Struct(iRank, piDims);
100                 int iSizeStruct = Mat_VarGetNumberOfFields(matVariable);
101
102                 matvar_t** allData = (matvar_t**)(matVariable->data);
103
104                 bool bSearchSizeStruck = false;
105                 for (int i = 0; (allData[i] != NULL) && (bSearchSizeStruck == false) && (i < iSizeStruct); i++)
106                 {
107                     for (int j = (i - 1); j >= 0; j--)
108                     {
109                         if (strcmp((char*)allData[i]->name, (char*)allData[j]->name) == 0)
110                         {
111                             bSearchSizeStruck = true;
112                             break;
113                         }
114                     }
115                     std::wstring wstField(to_wide_string((char*)allData[i]->name));
116                     pOut->getAs<types::Struct>()->addField(wstField);
117                 }
118
119                 for (int i = 0; i < pOut->getAs<types::Struct>()->getSize(); i++)
120                 {
121                     for (int j = 0; j < iSizeStruct; j++)
122                     {
123                         std::wstring wstField(to_wide_string((char*)allData[j]->name));
124                         pOut->getAs<types::Struct>()->get(i)->set(wstField, CreateMatlabTreeVariable(allData[i * iSizeStruct + j]));
125                     }
126                 }
127             }
128         }
129
130         break;
131         case MAT_C_CHAR: /* 4 */
132         {
133             char* pChar = (char*)MALLOC(sizeof(char) * (piDims[1] + 1));
134             pChar[0] = '\0';
135             strncat(pChar, (char*)matVariable->data, piDims[1]);
136             types::String* pString = new types::String(pChar);
137             pOut = pString;
138             FREE(pChar);
139         }
140         break;
141         case MAT_C_SPARSE: /* 5 */
142         {
143             mat_sparse_t *sparseData = (mat_sparse_t*)matVariable->data;
144
145             types::Sparse* pSparse = new types::Sparse(piDims[0], piDims[1], isComplex);
146             int *colIndexes = NULL;
147             int *rowIndexes = NULL;
148
149             /* Computes column indexes from Matlab indexes */
150             if (sparseData->njc > 1)
151             {
152                 colIndexes = (int*)MALLOC(sizeof(int) *  (sparseData->njc - 1));
153                 if (colIndexes == NULL)
154                 {
155                     Scierror(999, _("%s: No more memory.\n"), "CreateMatlabTreeVariable");
156                     delete pSparse;
157                     FREE(piDims);
158                     return NULL;
159                 }
160
161                 for (int K = 0; K < sparseData->njc - 1; K++)
162                 {
163                     colIndexes[K] = sparseData->jc[K + 1] - sparseData->jc[K];
164                 }
165             }
166
167             /* Computes row indexes from Matlab indexes */
168             rowIndexes = (int*)MALLOC(sizeof(int) * sparseData->nir);
169             if (rowIndexes == NULL)
170             {
171                 Scierror(999, _("%s: No more memory.\n"), "CreateMatlabTreeVariable");
172                 delete pSparse;
173                 FREE(colIndexes);
174                 FREE(piDims);
175                 return NULL;
176             }
177
178             for (int K = 0; K < sparseData->nir; K++)
179             {
180                 rowIndexes[K] = sparseData->ir[K] + 1;
181             }
182
183
184             if (isComplex)
185             {
186
187                 mat_complex_split_t *mat5ComplexData = NULL;
188                 mat5ComplexData = (mat_complex_split_t*)sparseData->data;
189
190                 double* pReal = (double*)mat5ComplexData->Re;
191                 double* pIm = (double*)mat5ComplexData->Im;
192
193                 int i = 0;
194                 for (int j = 0; j < (sparseData->njc - 1); j++)
195                 {
196                     for (int k = 0; k < colIndexes[j]; k++)
197                     {
198                         std::complex<double> dbl(pReal[i], pIm[i]);
199                         pSparse->set((rowIndexes[i] - 1), j, dbl);
200                         i++;
201                     }
202                 }
203
204             }
205             else
206             {
207                 double* pReal = (double*)sparseData->data;
208                 int i = 0;
209                 for (int j = 0; j < (sparseData->njc - 1); j++)
210                 {
211                     for (int k = 0; k < colIndexes[j]; k++)
212                     {
213                         pSparse->set((rowIndexes[i] - 1), j, pReal[i]);
214                         i++;
215                     }
216                 }
217             }
218             pOut = pSparse;
219             FREE(rowIndexes);
220             FREE(colIndexes);
221         }
222         break;
223         case MAT_C_DOUBLE: /* 6 */
224         case MAT_C_SINGLE: /* 7 */
225         {
226             types::Double* pDbl = new types::Double(iRank, piDims, isComplex);
227             if (isComplex)
228             {
229                 mat_complex_split_t *mat5ComplexData = NULL;
230                 mat5ComplexData = (mat_complex_split_t*)matVariable->data;
231
232                 pDbl->set((double*)mat5ComplexData->Re);
233                 pDbl->setImg((double*)mat5ComplexData->Im);
234             }
235             else
236             {
237                 pDbl->set((double*)matVariable->data);
238             }
239
240             pOut = pDbl;
241         }
242         break;
243         case MAT_C_INT8: /* 8 */
244         {
245             types::Int8* pInt8 = new types::Int8(iRank, piDims);
246
247             pInt8->set((char*)matVariable->data);
248
249             pOut = pInt8;
250         }
251         break;
252         case MAT_C_UINT8: /* 9 */
253         {
254             types::UInt8* pUInt8 = new types::UInt8(iRank, piDims);
255
256             pUInt8->set((unsigned char*)matVariable->data);
257
258             pOut = pUInt8;
259         }
260         break;
261         case MAT_C_INT16: /* 10 */
262         {
263             types::Int16* pInt16 = new types::Int16(iRank, piDims);
264
265             pInt16->set((short*)matVariable->data);
266
267             pOut = pInt16;
268         }
269         break;
270         case MAT_C_UINT16: /* 11 */
271         {
272             types::UInt16* pUInt16 = new types::UInt16(iRank, piDims);
273
274             pUInt16->set((unsigned short*)matVariable->data);
275
276             pOut = pUInt16;
277         }
278         break;
279         case MAT_C_INT32: /* 12 */
280         {
281             types::Int32* pInt32 = new types::Int32(iRank, piDims);
282
283             pInt32->set((int*)matVariable->data);
284
285             pOut = pInt32;
286         }
287         break;
288         case MAT_C_UINT32: /* 13 */
289         {
290             types::UInt32* pUInt32 = new types::UInt32(iRank, piDims);
291
292             pUInt32->set((unsigned int*)matVariable->data);
293
294             pOut = pUInt32;
295         }
296         break;
297 #ifdef __SCILAB_INT64__
298         case MAT_C_INT64: /* 14 */
299         {
300             types::Int64* pInt64 = new types::Int64(iRank, piDims);
301
302             pInt64->set((long long*)matVariable->data);
303
304             pOut = pInt64;
305         }
306         break;
307         case MAT_C_UINT64: /* 15 */
308         {
309             types::UInt64* pUInt64 = new types::UInt64(iRank, piDims);
310
311             pUInt64->set((unsigned long long*)matVariable->data);
312
313             pOut = pUInt64;
314         }
315         break;
316 #else
317         case MAT_C_INT64: /* 14 */
318         case MAT_C_UINT64: /* 15 */
319 #endif
320         case MAT_C_OBJECT: /* 3 to be written */
321         case MAT_C_FUNCTION: /* 16 to be written */
322         default:
323             /* Empty matrix returned */
324             FREE(piDims);
325             return types::Double::Empty();
326     }
327     FREE(piDims);
328     return pOut;
329 }