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