Coverity: Matio module memory leaks fixed
[scilab.git] / scilab / modules / matio / src / cpp / GetStructVariable.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) 2011 - DIGITEO - Vincent COUVERT
6  * Copyright (C) 2015 - Scilab Enterprises - Sylvain GENIN
7  *
8  * Copyright (C) 2012 - 2016 - Scilab Enterprises
9  *
10  * This file is hereby licensed under the terms of the GNU GPL v2.0,
11  * pursuant to article 5.3.4 of the CeCILL v.2.1.
12  * This file was originally licensed under the terms of the CeCILL v2.1,
13  * and continues to be available under such terms.
14  * For more information, see the COPYING file which you should have received
15  * along with this program.
16  *
17  */
18
19 #include "GetMatlabVariable.hxx"
20 #include "ConvertSciVarToMatVar.hxx"
21
22 extern "C"
23 {
24 #include "sci_types.h"
25 #include "api_scilab.h"
26 #include "freeArrayOfString.h"
27 #include "sci_malloc.h"
28 #include "charEncoding.h"
29 }
30
31 matvar_t *GetStructVariable(void *pvApiCtx, int iVar, const char *name, int matfile_version, int * parent, int item_position)
32 {
33     types::GatewayStruct* pGS = (types::GatewayStruct*)pvApiCtx;
34     types::typed_list in = *pGS->m_pIn;
35
36     if (in[iVar - 1]->isStruct() == false)
37     {
38         Scierror(999, _("%s: Wrong type for first input argument: string expected.\n"), "GetStructVariable");
39         return NULL;
40     }
41
42     types::Struct* pStruct = in[iVar - 1]->getAs<types::Struct>();
43
44     return GetStructMatVar(pStruct, name, matfile_version);
45 }
46
47 matvar_t* GetStructMatVar(types::Struct* pStruct, const char *name, int matfile_version)
48 {
49     matvar_t **structEntries = NULL;
50
51     int Dims = pStruct->getDims();
52     int* pDims = pStruct->getDimsArray();
53     int prodDims = pStruct->getSize();
54
55     matvar_t* pMatVarOut = NULL;
56
57     /* OTHERS LIST ENTRIES: ALL CELL VALUES */
58     size_t* pszDims = (size_t*)MALLOC(Dims * sizeof(size_t));
59     if (pszDims == NULL)
60     {
61         Scierror(999, _("%s: No more memory.\n"), "GetStructMatVar");
62         return NULL;
63     }
64
65     types::String* pFieldNames = pStruct->getFieldNames();
66     wchar_t** ppwchFieldNames = pFieldNames->get();
67     int isizeFieldNames = pFieldNames->getSize();
68
69     /* Total number of entries */
70     for (int K = 0; K < Dims; ++K)
71     {
72         pszDims[K] = ((int*)pDims)[K];
73     }
74
75     structEntries = (matvar_t **)MALLOC(sizeof(matvar_t*) * prodDims * isizeFieldNames + 1);
76     if (structEntries == NULL)
77     {
78         Scierror(999, _("%s: No more memory.\n"), "GetStructMatVar");
79         FREE(pszDims);
80         return NULL;
81     }
82
83     for (int K = 0; K < prodDims * isizeFieldNames + 1; ++K)
84     {
85         structEntries[K] = NULL;
86     }
87
88     types::SingleStruct** ppSingleStruct = pStruct->get();
89
90     for (int i = 0; i < prodDims; i++)
91     {
92         for (int j = 0; j < isizeFieldNames; j++)
93         {
94             structEntries[i * isizeFieldNames + j] = ConvertSciVarToMatVar(ppSingleStruct[i]->get(pFieldNames->get(j)), wide_string_to_UTF8(pFieldNames->get(j)), matfile_version);
95             if (structEntries[i * isizeFieldNames + j] == NULL)
96             {
97                 FREE(structEntries);
98                 FREE(pszDims);
99                 return NULL;
100             }
101         }
102     }
103
104     pMatVarOut = Mat_VarCreate(name, MAT_C_STRUCT, MAT_T_STRUCT, prodDims * isizeFieldNames, pszDims, structEntries, 0);
105
106     FREE(pszDims);
107     return pMatVarOut;
108 }