1/* Implementing buffer protocol typemaps */
2
3/* %pybuffer_mutable_binary(TYPEMAP, SIZE)
4 *
5 * Macro for functions accept mutable buffer pointer with a size.
6 * This can be used for both input and output. For example:
7 *
8 *      %pybuffer_mutable_binary(char *buff, int size);
9 *      void foo(char *buff, int size) {
10 *        for(int i=0; i<size; ++i)
11 *          buff[i]++;
12 *      }
13 */
14
15%define %pybuffer_mutable_binary(TYPEMAP, SIZE)
16%typemap(in) (TYPEMAP, SIZE)
17  (int res, Py_ssize_t size = 0, void *buf = 0) {
18  res = PyObject_AsWriteBuffer($input, &buf, &size);
19  if (res<0) {
20    PyErr_Clear();
21    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
22  }
23  $1 = ($1_ltype) buf;
24  $2 = ($2_ltype) (size/sizeof($*1_type));
25}
26%enddef
27
28/* %pybuffer_mutable_string(TYPEMAP, SIZE)
29 *
30 * Macro for functions accept mutable zero terminated string pointer.
31 * This can be used for both input and output. For example:
32 *
33 *      %pybuffer_mutable_string(char *str);
34 *      void foo(char *str) {
35 *        while(*str) {
36 *          *str = toupper(*str);
37 *          str++;
38 *      }
39 */
40
41%define %pybuffer_mutable_string(TYPEMAP)
42%typemap(in) (TYPEMAP)
43  (int res, Py_ssize_t size = 0, void *buf = 0) {
44  res = PyObject_AsWriteBuffer($input, &buf, &size);
45  if (res<0) {
46    PyErr_Clear();
47    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
48  }
49  $1 = ($1_ltype) buf;
50}
51%enddef
52
53/* pybuffer_binary(TYPEMAP, SIZE)
54 *
55 * Macro for functions accept read only buffer pointer with a size.
56 * This must be used for input. For example:
57 *
58 *      %pybuffer_binary(char *buff, int size);
59 *      int foo(char *buff, int size) {
60 *        int count = 0;
61 *        for(int i=0; i<size; ++i)
62 *          if (0==buff[i]) count++;
63 *        return count;
64 *      }
65 */
66
67%define %pybuffer_binary(TYPEMAP, SIZE)
68%typemap(in) (TYPEMAP, SIZE)
69  (int res, Py_ssize_t size = 0, const void *buf = 0) {
70  res = PyObject_AsReadBuffer($input, &buf, &size);
71  if (res<0) {
72    PyErr_Clear();
73    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
74  }
75  $1 = ($1_ltype) buf;
76  $2 = ($2_ltype) (size / sizeof($*1_type));
77}
78%enddef
79
80/* %pybuffer_string(TYPEMAP, SIZE)
81 *
82 * Macro for functions accept read only zero terminated string pointer.
83 * This can be used for input. For example:
84 *
85 *      %pybuffer_string(char *str);
86 *      int foo(char *str) {
87 *        int count = 0;
88 *        while(*str) {
89 *          if (isalnum(*str))
90 *            count++;
91 *          str++;
92 *      }
93 */
94
95%define %pybuffer_string(TYPEMAP)
96%typemap(in) (TYPEMAP)
97  (int res, Py_ssize_t size = 0, const void *buf = 0) {
98  res = PyObject_AsReadBuffer($input, &buf, &size);
99  if (res<0) {
100    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
101  }
102  $1 = ($1_ltype) buf;
103}
104%enddef
105
106
107
108