Python 3 port of PyME
[gpgme.git] / lang / py3-pyme / gpgme.i
1 /*
2 # $Id$
3 # Copyright (C) 2004,2008 Igor Belyi <belyi@users.sourceforge.net>
4 # Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
5 #
6 #    This library is free software; you can redistribute it and/or
7 #    modify it under the terms of the GNU Lesser General Public
8 #    License as published by the Free Software Foundation; either
9 #    version 2.1 of the License, or (at your option) any later version.
10 #
11 #    This library is distributed in the hope that it will be useful,
12 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 #    Lesser General Public License for more details.
15 #
16 #    You should have received a copy of the GNU Lesser General Public
17 #    License along with this library; if not, write to the Free Software
18 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19 */
20 %module pygpgme
21 %include "cpointer.i"
22 %include "cstring.i"
23
24 // Generate doc strings for all methods.
25 %feature("autodoc", "0");
26
27 // Allow use of None for strings.
28
29 %typemap(in) const char * {
30   if ($input == Py_None)
31     $1 = NULL;
32   else if (PyBytes_Check($input))
33     $1 = PyBytes_AsString($input);
34   else {
35     PyErr_Format(PyExc_TypeError,
36                  "arg %d: expected string or None, got %s",
37                  $argnum, $input->ob_type->tp_name);
38     return NULL;
39   }
40 }
41 %typemap(freearg) const char * "";
42
43 // Release returned buffers as necessary.
44 %typemap(newfree) char * "free($1);";
45 %newobject gpgme_data_release_and_get_mem;
46
47 %{
48 /* Convert object to a pointer to gpgme type */
49 PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) {
50   PyObject *pyname = NULL, *pypointer = NULL;
51   pyname = PyObject_CallMethod(input, "_getctype", NULL);
52   if (pyname == NULL) {
53     PyErr_Format(PyExc_TypeError,
54                  "arg %d: Expected an instance of type %s, but got %s",
55                  argnum, objtype,
56                  input == Py_None ? "None" : input->ob_type->tp_name);
57     return NULL;
58   }
59   if (strcmp(PyBytes_AsString(pyname), objtype) != 0) {
60     PyErr_Format(PyExc_TypeError,
61                  "arg %d: Expected value of type %s, but got %s",
62                  argnum, objtype, PyBytes_AsString(pyname));
63     Py_DECREF(pyname);
64     return NULL;
65   }
66   Py_DECREF(pyname);
67   pypointer = PyObject_GetAttrString(input, "wrapped");
68   if (pypointer == NULL) {
69     PyErr_Format(PyExc_TypeError,
70                  "arg %d: Use of uninitialized Python object %s",
71                  argnum, objtype);
72     return NULL;
73   }
74   return pypointer;
75 }
76 %}
77
78 %typemap(arginit) gpgme_key_t [] {
79   $1 = NULL;
80 }
81
82 %typemap(in) gpgme_key_t [] {
83   int i, numb = 0;
84   if (!PySequence_Check($input)) {
85     PyErr_Format(PyExc_ValueError, "arg %d: Expected a list of gpgme_key_t",
86                  $argnum);
87     return NULL;
88   }
89   if((numb = PySequence_Length($input)) != 0) {
90     $1 = (gpgme_key_t*)malloc((numb+1)*sizeof(gpgme_key_t));
91     for(i=0; i<numb; i++) {
92       PyObject *pypointer = PySequence_GetItem($input, i);
93
94       /* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
95       /* &1_descriptor = $&1_descriptor *1_descriptor = $*1_descriptor */
96
97       // Following code is from swig's python.swg
98       if ((SWIG_ConvertPtr(pypointer,(void **) &$1[i], $*1_descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) {
99         Py_DECREF(pypointer);
100         return NULL;
101       }
102       Py_DECREF(pypointer);
103     }
104     $1[numb] = NULL;
105   }
106 }
107 %typemap(freearg) gpgme_key_t [] {
108   if ($1) free($1);
109 }
110
111 // Special handling for references to our objects.
112 %typemap(in) gpgme_data_t DATAIN {
113   if ($input == Py_None)
114     $1 = NULL;
115   else {
116     PyObject *pypointer = NULL;
117
118     if((pypointer=object_to_gpgme_t($input, "$1_ltype", $argnum)) == NULL)
119       return NULL;
120
121     /* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
122
123     // Following code is from swig's python.swg
124
125     if ((SWIG_ConvertPtr(pypointer,(void **) &$1, $1_descriptor,
126          SWIG_POINTER_EXCEPTION | $disown )) == -1) {
127       Py_DECREF(pypointer);
128       return NULL;
129     }
130     Py_DECREF(pypointer);
131   }
132 }
133
134 %apply gpgme_data_t DATAIN {gpgme_data_t plain, gpgme_data_t cipher,
135                         gpgme_data_t sig, gpgme_data_t signed_text,
136                         gpgme_data_t plaintext, gpgme_data_t keydata,
137                         gpgme_data_t pubkey, gpgme_data_t seckey,
138                         gpgme_data_t out};
139
140 // SWIG has problem interpreting ssize_t, off_t or gpgme_error_t in gpgme.h
141 %typemap(out) ssize_t, off_t, gpgme_error_t, gpgme_err_code_t, gpgme_err_source_t, gpg_error_t {
142   $result = PyLong_FromLong($1);
143 }
144 %typemap(in) ssize_t, off_t, gpgme_error_t, gpgme_err_code_t, gpgme_err_source_t, gpg_error_t {
145   $1 = PyLong_AsLong($input);
146 }
147
148 // Those are for gpgme_data_read() and gpgme_strerror_r()
149 %typemap(in) (void *buffer, size_t size), (char *buf, size_t buflen) {
150    $2 = PyLong_AsLong($input);
151    if ($2 < 0) {
152      PyErr_SetString(PyExc_ValueError, "Positive integer expected");
153      return NULL;
154    }
155    $1 = ($1_ltype) malloc($2+1);
156 }
157 %typemap(argout) (void *buffer, size_t size), (char *buf, size_t buflen) {
158   Py_XDECREF($result);   /* Blow away any previous result */
159   if (result < 0) {      /* Check for I/O error */
160     free($1);
161     return NULL;
162   }
163   $result = PyBytes_FromStringAndSize($1,result);
164   free($1);
165 }
166
167 // Make types containing 'next' field to be lists
168 %ignore next;
169 %typemap(out) gpgme_sig_notation_t, gpgme_engine_info_t, gpgme_subkey_t, gpgme_key_sig_t,
170         gpgme_user_id_t, gpgme_invalid_key_t, gpgme_recipient_t, gpgme_new_signature_t,
171         gpgme_signature_t, gpgme_import_status_t, gpgme_conf_arg_t, gpgme_conf_opt_t,
172         gpgme_conf_comp_t {
173   int i;
174   int size = 0;
175   $1_ltype curr;
176   for (curr = $1; curr != NULL; curr = curr->next) {
177     size++;
178   }
179   $result = PyList_New(size);
180   for (i=0,curr=$1; i<size; i++,curr=curr->next) {
181     PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor, %newpointer_flags);
182     PyList_SetItem($result, i, o);
183   }
184 }
185
186 // Include mapper for edit callbacks
187 %typemap(in) (gpgme_edit_cb_t fnc, void *fnc_value) {
188   $1 = (gpgme_edit_cb_t) pyEditCb;
189   if ($input == Py_None)
190     $2 = NULL;
191   else
192     $2 = $input;
193 }
194
195 // Include the header file both for cc (first) and for swig (second)
196 // Include for swig locally since we need to fix 'class' usage there.
197 %{
198 #include <gpgme.h>
199 %}
200 %include "gpgme.h"
201
202 %constant long EOF = GPG_ERR_EOF;
203
204 // Generating and handling pointers-to-pointers.
205
206 %pointer_functions(gpgme_ctx_t, gpgme_ctx_t_p);
207 %pointer_functions(gpgme_data_t, gpgme_data_t_p);
208 %pointer_functions(gpgme_key_t, gpgme_key_t_p);
209 %pointer_functions(gpgme_error_t, gpgme_error_t_p);
210 %pointer_functions(gpgme_trust_item_t, gpgme_trust_item_t_p);
211 %pointer_functions(gpgme_engine_info_t, gpgme_engine_info_t_p);
212 %pointer_functions(PyObject *, PyObject_p_p);
213 %pointer_functions(void *, void_p_p);
214
215 // Helper functions.
216
217 %{
218 #include <stdio.h>
219 %}
220 FILE *fdopen(int fildes, const char *mode);
221
222 %{
223 #include "helpers.h"
224 %}
225 %include "helpers.h"
226
227 %{
228 gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status,
229                        const char *args, int fd) {
230   PyObject *func = NULL, *dataarg = NULL, *pyargs = NULL, *retval = NULL;
231   PyObject *pyopaque = (PyObject *) opaque;
232   gpgme_error_t err_status = 0;
233
234   pygpgme_exception_init();
235
236   if (PyTuple_Check(pyopaque)) {
237     func = PyTuple_GetItem(pyopaque, 0);
238     dataarg = PyTuple_GetItem(pyopaque, 1);
239     pyargs = PyTuple_New(3);
240   } else {
241     func = pyopaque;
242     pyargs = PyTuple_New(2);
243   }
244   
245   PyTuple_SetItem(pyargs, 0, PyLong_FromLong((long) status));
246   PyTuple_SetItem(pyargs, 1, PyBytes_FromString(args));
247   if (dataarg) {
248     Py_INCREF(dataarg);         /* Because GetItem doesn't give a ref but SetItem taketh away */
249     PyTuple_SetItem(pyargs, 2, dataarg);
250   }
251   
252   retval = PyObject_CallObject(func, pyargs);
253   Py_DECREF(pyargs);
254   if (PyErr_Occurred()) {
255     err_status = pygpgme_exception2code();
256   } else {
257     if (fd>=0 && retval) {
258       write(fd, PyBytes_AsString(retval), PyBytes_Size(retval));
259       write(fd, "\n", 1);
260     }
261   }
262
263   Py_XDECREF(retval);
264   return err_status;
265 }
266 %}
267