[api_scilab] memory leak fixed in Struct API C++
[scilab.git] / scilab / modules / api_scilab / src / cpp / template / api_struct.hpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13 */
14
15 #include "gatewaystruct.hxx"
16 #include "struct.hxx"
17
18 extern "C"
19 {
20 #include "api_scilab.h"
21 }
22
23 scilabVar API_PROTO(createStruct)(scilabEnv env)
24 {
25     types::Struct* s = new types::Struct(1, 1);
26 #ifdef __API_SCILAB_SAFE__
27     if (s == nullptr)
28     {
29         scilab_setInternalError(env, L"createStruct", _W("memory allocation error"));
30         return nullptr;
31     }
32 #endif
33     return (scilabVar)s;
34 }
35
36 scilabVar API_PROTO(createStructMatrix)(scilabEnv env, int dim, const int* dims)
37 {
38 #ifdef __API_SCILAB_SAFE__
39     if (dims == nullptr)
40     {
41         scilab_setInternalError(env, L"createStructMatrix", _W("dims array cannot be NULL"));
42         return nullptr;
43     }
44
45     for (int i = 0; i < dim; ++i)
46     {
47         if (dims[i] < 0)
48         {
49             scilab_setInternalError(env, L"createStructMatrix", _W("dimensions cannot be negative"));
50             return nullptr;
51         }
52     }
53 #endif
54     types::Struct* s = new types::Struct(dim, dims);
55 #ifdef __API_SCILAB_SAFE__
56     if (s == nullptr)
57     {
58         scilab_setInternalError(env, L"createStructMatrix", _W("memory allocation error"));
59         return nullptr;
60     }
61 #endif
62     return (scilabVar)s;
63 }
64
65 scilabVar API_PROTO(createStructMatrix2d)(scilabEnv env, int row, int col)
66 {
67     int dims[2] = {row, col};
68 #ifdef __API_SCILAB_SAFE__
69     for (int i = 0; i < 2; ++i)
70     {
71         if (dims[i] < 0)
72         {
73             scilab_setInternalError(env, L"createStructMatrix2d", _W("dimensions cannot be negative"));
74             return nullptr;
75         }
76     }
77 #endif
78     types::Struct* s = new types::Struct(2, dims);
79 #ifdef __API_SCILAB_SAFE__
80     if (s == nullptr)
81     {
82         scilab_setInternalError(env, L"createStructMatrix2d", _W("memory allocation error"));
83         return nullptr;
84     }
85 #endif
86     return (scilabVar)s;
87 }
88
89 /*fields*/
90 scilabStatus API_PROTO(addFields)(scilabEnv env, scilabVar var, int count, const wchar_t** fields)
91 {
92     types::Struct* s = (types::Struct*)var;
93 #ifdef __API_SCILAB_SAFE__
94     if (s->isStruct() == false)
95     {
96         scilab_setInternalError(env, L"addFields", _W("var must be a struct variable"));
97         return STATUS_ERROR;
98     }
99 #endif
100
101     for (int i = 0; i < count; ++i)
102     {
103         s->addField(fields[i]);
104     }
105
106     return STATUS_OK;
107 }
108
109 scilabStatus API_PROTO(addField)(scilabEnv env, scilabVar var, const wchar_t* field)
110 {
111     types::Struct* s = (types::Struct*)var;
112 #ifdef __API_SCILAB_SAFE__
113     if (s->isStruct() == false)
114     {
115         scilab_setInternalError(env, L"addField", _W("var must be a struct variable"));
116         return STATUS_ERROR;
117     }
118 #endif
119     s->addField(field);
120     return STATUS_OK;
121 }
122
123 int API_PROTO(getFields)(scilabEnv env, scilabVar var, wchar_t***  fields)
124 {
125     types::Struct* s = (types::Struct*)var;
126 #ifdef __API_SCILAB_SAFE__
127     if (s->isStruct() == false)
128     {
129         scilab_setInternalError(env, L"getFields", _W("var must be a struct variable"));
130         return STATUS_ERROR;
131     }
132 #endif
133
134     std::unordered_map<std::wstring, int> fieldsMap = s->get(0)->getFields();
135     *fields = new wchar_t*[fieldsMap.size()];
136     int iter = 0;
137     for (const auto & field : fieldsMap)
138     {
139         (*fields)[iter++] = os_wcsdup(field.first.data());
140     }
141
142     return (int)fieldsMap.size();
143 }
144
145 /*data*/
146 scilabVar API_PROTO(getStructMatrixData)(scilabEnv env, scilabVar var, const wchar_t* field, const int* index)
147 {
148     types::Struct* s = (types::Struct*)var;
149 #ifdef __API_SCILAB_SAFE__
150     if (s->isStruct() == false)
151     {
152         scilab_setInternalError(env, L"getStructMatrixData", _W("var must be a struct variable"));
153         return nullptr;
154     }
155 #endif
156
157     types::SingleStruct* ss = s->get(s->getIndex(index));
158     return (scilabVar)ss->get(field);
159 }
160 scilabVar API_PROTO(getStructMatrix2dData)(scilabEnv env, scilabVar var, const wchar_t* field, int row, int col)
161 {
162     int index[2] = {row, col};
163     types::Struct* s = (types::Struct*)var;
164 #ifdef __API_SCILAB_SAFE__
165     if (s->isStruct() == false)
166     {
167         scilab_setInternalError(env, L"getStructMatrix2dData", _W("var must be a struct variable"));
168         return nullptr;
169     }
170 #endif
171     types::SingleStruct* ss = s->get(s->getIndex(index));
172     return (scilabVar)ss->get(field);
173 }
174
175 scilabStatus API_PROTO(setStructMatrixData)(scilabEnv env, scilabVar var, const wchar_t* field, const int* index, scilabVar data)
176 {
177     types::Struct* s = (types::Struct*)var;
178 #ifdef __API_SCILAB_SAFE__
179     if (s->isStruct() == false)
180     {
181         scilab_setInternalError(env, L"setStructMatrixData", _W("var must be a struct variable"));
182         return STATUS_ERROR;
183     }
184 #endif
185     types::SingleStruct* ss = s->get(s->getIndex(index));
186     return ss->set(field, (types::InternalType*)data) ? STATUS_OK : STATUS_ERROR;
187 }
188
189 scilabStatus API_PROTO(setStructMatrix2dData)(scilabEnv env, scilabVar var, const wchar_t* field, int row, int col, scilabVar data)
190 {
191     int index[2] = {row, col};
192     types::Struct* s = (types::Struct*)var;
193 #ifdef __API_SCILAB_SAFE__
194     if (s->isStruct() == false)
195     {
196         scilab_setInternalError(env, L"setStructMatrix2dData", _W("var must be a struct variable"));
197         return STATUS_ERROR;
198     }
199 #endif
200     types::SingleStruct* ss = s->get(s->getIndex(index));
201     return ss->set(field, (types::InternalType*)data) ? STATUS_OK : STATUS_ERROR;
202 }