Library of Assembled Shared Sources
overload_link.cpp
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#include "python_common.h"
46#include "overload_link.h"
47#include "py_tuple.h"
48
49namespace lass
50{
51namespace python
52{
53namespace impl
54{
55
56OverloadLink::OverloadLink()
57{
58 setNull();
59}
60
61void OverloadLink::setNull()
62{
63 signature_ = sNull;
64}
65
66void OverloadLink::setPyCFunction(PyCFunction iOverload)
67{
68 signature_ = iOverload ? sPyCFunction : sNull;
69 pyCFunction_ = iOverload;
70}
71
72void OverloadLink::setBinaryfunc(binaryfunc iOverload)
73{
74 signature_ = iOverload ? sBinary : sNull;
75 binaryfunc_ = iOverload;
76}
77
78void OverloadLink::setTernaryfunc(ternaryfunc iOverload)
79{
80 signature_ = iOverload ? sTernary : sNull;
81 ternaryfunc_ = iOverload;
82}
83void OverloadLink::setSsizeArgfunc(ssizeargfunc iOverload)
84{
85 signature_ = iOverload ? sSsizeArg : sNull;
86 ssizeargfunc_ = iOverload;
87}
88void OverloadLink::setSsizeSsizeArgfunc(ssizessizeargfunc iOverload)
89{
90 signature_ = iOverload ? sSsizeSsizeArg : sNull;
91 ssizessizeargfunc_ = iOverload;
92}
93
94void OverloadLink::setSsizeObjArgProcfunc(ssizeobjargproc iOverload)
95{
96 signature_ = iOverload ? sSsizeObjArg : sNull;
97 ssizeobjargproc_ = iOverload;
98}
99void OverloadLink::setSsizeSsizeObjArgProcfunc(ssizessizeobjargproc iOverload)
100{
101 signature_ = iOverload ? sSsizeSsizeObjArg : sNull;
102 ssizessizeobjargproc_ = iOverload;
103}
104void OverloadLink::setObjObjProcfunc(objobjproc iOverload)
105{
106 signature_ = iOverload ? sObjObjArg : sNull;
107 objobjproc_ = iOverload;
108}
109void OverloadLink::setObjObjArgProcfunc(objobjargproc iOverload)
110{
111 signature_ = iOverload ? sObjObjArg : sNull;
112 objobjargproc_ = iOverload;
113}
114void OverloadLink::setGetIterFunc(getiterfunc iOverload)
115{
116 signature_ = iOverload ? sGetIterFunc : sNull;
117 getiterfunc_ = iOverload;
118}
119void OverloadLink::setIterNextFunc(iternextfunc iOverload)
120{
121 signature_ = iOverload ? sIterNextFunc : sNull;
122 iternextfunc_ = iOverload;
123}
124void OverloadLink::setArgKwfunc(ternaryfunc iOverload)
125{
126 signature_ = iOverload ? sArgKw : sNull;
127 ternaryfunc_ = iOverload;
128}
129
130bool OverloadLink::operator ()(PyObject* iSelf, PyObject* iArgs, PyObject*& oResult) const
131{
132 if (signature_ == sNull)
133 {
134 return false;
135 }
136 PyObject* temp = call(iSelf, iArgs);
137 if (PyErr_Occurred() && (PyErr_ExceptionMatches(PyExc_TypeError) || PyErr_ExceptionMatches(PyExc_NotImplementedError)))
138 {
139 PyErr_Clear();
140 Py_XDECREF(temp);
141 return false;
142 }
143 oResult = temp;
144 return true;
145}
146
147PyObject* OverloadLink::call(PyObject* iSelf, PyObject* iArgs) const
148{
149 switch (signature_)
150 {
151 case sNull:
152 return 0;
153
154 case sPyCFunction:
155 return pyCFunction_(iSelf, iArgs);
156
157 case sBinary:
158 {
159 TPyObjPtr arg;
160 if (decodeTuple(iArgs, arg) != 0)
161 {
162 return 0;
163 }
164 return binaryfunc_(iSelf, arg.get());
165 }
166
167 case sTernary:
168 {
169 TPyObjPtr arg1, arg2;
170 if (decodeTuple(iArgs, arg1, arg2) != 0)
171 {
172 return 0;
173 }
174 return ternaryfunc_(iSelf, arg1.get(), arg2.get());
175 }
176
177 case sSsizeArg:
178 {
179 Py_ssize_t size1;
180 if (decodeTuple(iArgs, size1) != 0)
181 {
182 return 0;
183 }
184 return ssizeargfunc_(iSelf, size1 );
185 }
186
187 case sSsizeSsizeArg:
188 {
189 Py_ssize_t size1;
190 Py_ssize_t size2;
191 if (decodeTuple(iArgs, size1, size2) != 0)
192 {
193 return 0;
194 }
195 return ssizessizeargfunc_(iSelf, size1, size2 );
196 }
197
198 case sSsizeObjArg:
199 {
200 Py_ssize_t size1;
201 TPyObjPtr obj1;
202 if (decodeTuple(iArgs, size1, obj1) != 0)
203 {
204 return 0;
205 }
206 return pyBuildSimpleObject(ssizeobjargproc_(iSelf,size1,obj1.get()));
207 }
208
209 case sSsizeSsizeObjArg:
210 {
211 Py_ssize_t size1;
212 Py_ssize_t size2;
213 TPyObjPtr obj1;
214 if (decodeTuple(iArgs, size1, size2, obj1) != 0)
215 {
216 return 0;
217 }
218 return pyBuildSimpleObject(ssizessizeobjargproc_(iSelf,size1,size2,obj1.get()));
219 }
220
221 case sObjObj:
222 {
223 TPyObjPtr obj1;
224 if (decodeTuple(iArgs, obj1) != 0)
225 {
226 return 0;
227 }
228 return pyBuildSimpleObject(objobjproc_(iSelf,obj1.get()));
229 }
230
231 case sObjObjArg:
232 {
233 // iArgs can be a tuple of one or two elements.
234 // If it's two elements, it's key and value for __setitem__.
235 // If it's one element, we are infact the slot as __delitem__,
236 // and value is implicitly NULL.
237 //
238 const TPyObjPtr args = impl::checkedFastSequence(iArgs, 1, 2);
239 if (!args)
240 {
241 return 0;
242 }
243 const Py_ssize_t argc = PySequence_Fast_GET_SIZE(args.get());
244 PyObject** const argv = PySequence_Fast_ITEMS(args.get());
245 PyObject* const key = argv[0];
246 PyObject* const value = argc == 2 ? argv[1] : 0;
247 const int ret = objobjargproc_(iSelf, key, value);
248 switch (ret)
249 {
250 case -1:
251 return 0;
252 case 0:
253 Py_RETURN_NONE; // success
254 default:
255 PyErr_SetString(PyExc_AssertionError, "OverloadChain: invalid return code.");
256 return 0;
257 }
258 }
259
260 case sGetIterFunc:
261 if (decodeTuple(iArgs) != 0)
262 {
263 return 0;
264 }
265 return getiterfunc_(iSelf);
266
267 case sIterNextFunc:
268 if (decodeTuple(iArgs) != 0)
269 {
270 return 0;
271 }
272 return iternextfunc_(iSelf);
273
274 case sArgKw:
275 return ternaryfunc_(iSelf, iArgs, 0);
276
277 default:
278 PyErr_SetString(PyExc_AssertionError, "OverloadChain: invalid signature type");
279 return 0;
280 };
281}
282
283}
284}
285}
286
287// EOF
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
Comprehensive C++ to Python binding library.
Library for Assembled Shared Sources.
Definition config.h:53