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