cb546f591ceff1f9b8b95eaedfbbc4e51c215bad
[scilab.git] / scilab / modules / external_objects / src / cpp / doubleExclam_invoke.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
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-en.txt
10  *
11  */
12
13 #include "ScilabGateway.hxx"
14
15 /**
16  * The function !!_invoke_l is called by !_invoke_ which is called on object.method
17  */
18
19 namespace org_modules_external_objects
20 {
21
22 int ScilabGateway::doubleExclam_invoke(char * fname, const int envId, void * pvApiCtx)
23 {
24     SciErr err;
25     int * addr = 0;
26     int * tmpvar = 0;
27     int * args = 0;
28     int typ = 0;
29     int * child = 0;
30     int eId = OptionsHelper::getEnvId();
31     int ret = 0;
32     int * sret = 0;
33     int len = Rhs;
34
35     CheckOutputArgument(pvApiCtx, 1, 1);
36
37     ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(eId);
38     ScilabGatewayOptions & options = env.getGatewayOptions();
39     OptionsHelper & helper = env.getOptionsHelper();
40     ScilabObjects::initialization(env, pvApiCtx);
41
42     if (!OptionsHelper::getCopyOccured()) // if the function is called outside a method context, then return null
43     {
44         //TODO: get null for environment
45         ScilabObjects::unwrap(0, Rhs + 1, eId, pvApiCtx);
46
47         LhsVar(1) = Rhs + 1;
48         PutLhsVar();
49
50         return 0;
51     }
52
53     OptionsHelper::setCopyOccured(false);
54
55     if (!options.getMethodName())
56     {
57         LhsVar(1) = Rhs + 1;
58         PutLhsVar();
59
60         return 0;
61     }
62
63     if (Rhs == 1)
64     {
65         err = getVarAddressFromPosition(pvApiCtx, 1, &addr);
66         if (err.iErr)
67         {
68             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
69         }
70
71         if (ScilabObjects::isExternalVoid(addr, pvApiCtx))
72         {
73             len = 0;
74         }
75     }
76
77     tmpvar = new int[len + 1];
78     *tmpvar = 0;
79     args = new int[len];
80
81     for (int i = 0; i < len; i++)
82     {
83         err = getVarAddressFromPosition(pvApiCtx, i + 1, &addr);
84         if (err.iErr)
85         {
86             ScilabObjects::removeTemporaryVars(eId, tmpvar);
87             delete[] tmpvar;
88             delete[] args;
89             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
90         }
91
92         try
93         {
94             args[i] = ScilabObjects::getArgumentId(addr, tmpvar, false, false, eId, pvApiCtx);
95         }
96         catch (ScilabAbstractEnvironmentException & e)
97         {
98             delete[] tmpvar;
99             delete[] args;
100             throw;
101         }
102     }
103
104     if (options.getIsNew())
105     {
106         try
107         {
108             ret = env.newinstance(options.getObjId(), args, len);
109         }
110         catch (std::exception & e)
111         {
112             options.setIsNew(false);
113             ScilabObjects::removeTemporaryVars(eId, tmpvar);
114             delete[] tmpvar;
115             delete[] args;
116             throw;
117         }
118
119         options.setIsNew(false);
120         ScilabObjects::removeTemporaryVars(eId, tmpvar);
121         delete[] tmpvar;
122         delete[] args;
123         options.setMethodName(0);
124
125         if (ret == VOID_OBJECT)
126         {
127             PutLhsVar();
128
129             return 0;
130         }
131
132         try
133         {
134             ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + 1, ret, eId, pvApiCtx);
135         }
136         catch (ScilabAbstractEnvironmentException & e)
137         {
138             env.removeobject(ret);
139             throw;
140         }
141
142         LhsVar(1) = Rhs + 1;
143         PutLhsVar();
144
145         return 0;
146     }
147     else
148     {
149         try
150         {
151             sret = env.invoke(options.getObjId(), options.getMethodName(), args, len);
152         }
153         catch (std::exception & e)
154         {
155             ScilabObjects::removeTemporaryVars(eId, tmpvar);
156             delete[] tmpvar;
157             delete[] args;
158             options.setMethodName(0);
159             throw;
160         }
161     }
162
163     ScilabObjects::removeTemporaryVars(eId, tmpvar);
164     delete[] tmpvar;
165     delete[] args;
166     options.setMethodName(0);
167
168     if (!sret || *sret <= 0 || (*sret == 1 && sret[1] == VOID_OBJECT))
169     {
170         if (sret)
171         {
172             delete[] sret;
173         }
174
175         PutLhsVar();
176
177         return 0;
178     }
179
180     if (helper.getAutoUnwrap())
181     {
182         for (int i = 1; i <= *sret; i++)
183         {
184             if (!ScilabObjects::unwrap(sret[i], Rhs + i, eId, pvApiCtx))
185             {
186                 try
187                 {
188                     ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + i, sret[i], eId, pvApiCtx);
189                 }
190                 catch (ScilabAbstractEnvironmentException & e)
191                 {
192                     for (int j = 1; j <= *sret; j++)
193                     {
194                         env.removeobject(sret[j]);
195                     }
196                     delete[] sret;
197                     throw;
198                 }
199             }
200             else
201             {
202                 env.removeobject(sret[i]);
203             }
204
205             LhsVar(i) = Rhs + i;
206         }
207     }
208     else
209     {
210         for (int i = 1; i <= *sret; i++)
211         {
212             try
213             {
214                 ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + i, sret[i], eId, pvApiCtx);
215             }
216             catch (ScilabAbstractEnvironmentException & e)
217             {
218                 for (int j = 1; j <= *sret; j++)
219                 {
220                     env.removeobject(sret[j]);
221                 }
222                 delete[] sret;
223                 throw;
224             }
225
226             LhsVar(i) = Rhs + i;
227         }
228     }
229
230     delete[] sret;
231
232     PutLhsVar();
233
234     return 0;
235 }
236 }