JIMS: add jvoid
[scilab.git] / scilab / modules / external_objects / src / cpp / 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 namespace org_modules_external_objects
16 {
17
18 int ScilabGateway::invoke(char * fname, const int envId, void * pvApiCtx)
19 {
20     SciErr err;
21     int * tmpvar = 0;
22     int * addr = 0;
23     int * args = 0;
24     int idObj = 0;
25     int * ret = 0;
26     char * methName = 0;
27     int nbArgs = Rhs - 2;
28
29     if (Rhs < 2)
30     {
31         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Wrong number of arguments : more than 2 arguments expected"));
32     }
33
34     ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(envId);
35     ScilabGatewayOptions & options = env.getGatewayOptions();
36     OptionsHelper & helper = env.getOptionsHelper();
37     OptionsHelper::setCopyOccurred(false);
38     ScilabObjects::initialization(env, pvApiCtx);
39     options.setIsNew(false);
40
41     err = getVarAddressFromPosition(pvApiCtx, 1, &addr);
42     if (err.iErr)
43     {
44         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
45     }
46
47     tmpvar = new int[Rhs - 1];
48     *tmpvar = 0;
49
50     try
51     {
52         idObj = ScilabObjects::getArgumentId(addr, tmpvar, false, false, envId, pvApiCtx);
53     }
54     catch (ScilabAbstractEnvironmentException & e)
55     {
56         delete[] tmpvar;
57         throw;
58     }
59
60     if (idObj == 0)
61     {
62         delete[] tmpvar;
63         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot invoke on null object"));
64     }
65
66     args = new int[Rhs - 2];
67
68     for (int i = 0; i < Rhs - 2; i++)
69     {
70         err = getVarAddressFromPosition(pvApiCtx, i + 3, &addr);
71         if (err.iErr)
72         {
73             delete[] args;
74             ScilabObjects::removeTemporaryVars(envId, tmpvar);
75             delete[] tmpvar;
76             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
77         }
78
79         try
80         {
81             args[i] = ScilabObjects::getArgumentId(addr, tmpvar, false, false, envId, pvApiCtx);
82         }
83         catch (ScilabAbstractEnvironmentException & e)
84         {
85             delete[] args;
86             ScilabObjects::removeTemporaryVars(envId, tmpvar);
87             delete[] tmpvar;
88             throw;
89         }
90
91         if (args[i] == VOID_OBJECT)
92         {
93             nbArgs = 0;
94         }
95     }
96
97     try
98     {
99         methName = ScilabObjects::getSingleString(2, pvApiCtx);
100     }
101     catch (ScilabAbstractEnvironmentException & e)
102     {
103         delete[] args;
104         ScilabObjects::removeTemporaryVars(envId, tmpvar);
105         delete[] tmpvar;
106         throw;
107     }
108
109     try
110     {
111         ret = env.invoke(idObj, methName, args, nbArgs);
112     }
113     catch (std::exception & e)
114     {
115         delete[] args;
116         ScilabObjects::removeTemporaryVars(envId, tmpvar);
117         delete[] tmpvar;
118         env.removeobject(idObj);
119         freeAllocatedSingleString(methName);
120         throw;
121     }
122
123     delete[] args;
124     ScilabObjects::removeTemporaryVars(envId, tmpvar);
125     delete[] tmpvar;
126     freeAllocatedSingleString(methName);
127
128     if (!ret || *ret <= 0 || (*ret == 1 && ret[1] == VOID_OBJECT))
129     {
130         if (ret)
131         {
132             delete[] ret;
133         }
134
135         PutLhsVar();
136
137         return 0;
138     }
139
140     if (helper.getAutoUnwrap())
141     {
142         for (int i = 1; i <= *ret; i++)
143         {
144             if (!ScilabObjects::unwrap(ret[i], Rhs + i, envId, pvApiCtx))
145             {
146                 try
147                 {
148                     ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + i, ret[i], envId, pvApiCtx);
149                 }
150                 catch (ScilabAbstractEnvironmentException & e)
151                 {
152                     for (int j = 1; j <= *ret; j++)
153                     {
154                         env.removeobject(ret[j]);
155                     }
156                     delete[] ret;
157                     throw;
158                 }
159             }
160             else
161             {
162                 env.removeobject(ret[i]);
163             }
164
165             LhsVar(i) = Rhs + i;
166         }
167     }
168     else
169     {
170         for (int i = 1; i <= *ret; i++)
171         {
172             try
173             {
174                 ScilabObjects::createEnvironmentObjectAtPos(EXTERNAL_OBJECT, Rhs + i, ret[i], envId, pvApiCtx);
175             }
176             catch (ScilabAbstractEnvironmentException & e)
177             {
178                 for (int j = 1; j <= *ret; j++)
179                 {
180                     env.removeobject(ret[j]);
181                 }
182                 delete[] ret;
183                 throw;
184             }
185
186             LhsVar(i) = Rhs + i;
187         }
188     }
189
190     delete[] ret;
191
192     PutLhsVar();
193
194     return 0;
195 }
196 }