Add a test case for the various options to get_args_list.
[dbus-python-phuang.git] / _dbus_bindings / signature-impl.h
blobeda317732f9b58d7e59e67faf7514cada230067c
1 /* Implementation of Signature type for D-Bus bindings.
3 * Copyright (C) 2006 Collabora Ltd.
5 * Licensed under the Academic Free License version 2.1
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 PyDoc_STRVAR(Signature_tp_doc,
26 "Signature(str) -> Signature\n"
27 "\n"
28 "Signature is a string subclass whose values are restricted to valid D-Bus\n"
29 "signatures. When iterated over, instead of individual characters it\n"
30 "produces Signature instances representing single complete types.\n"
33 static PyTypeObject SignatureType;
35 static inline int Signature_Check(PyObject *o)
37 return (o->ob_type == &SignatureType)
38 || PyObject_IsInstance(o, (PyObject *)&SignatureType);
41 typedef struct {
42 PyObject_HEAD
43 PyObject *string;
44 DBusSignatureIter iter;
45 } SignatureIter;
47 static void
48 SignatureIter_tp_dealloc (SignatureIter *self)
50 Py_XDECREF(self->string);
51 self->string = NULL;
52 PyObject_Del(self);
55 static PyObject *
56 SignatureIter_tp_iternext (SignatureIter *self)
58 char *sig;
59 PyObject *obj;
61 /* Stop immediately if finished or not correctly initialized */
62 if (!self->string) return NULL;
64 sig = dbus_signature_iter_get_signature(&(self->iter));
65 if (!sig) return PyErr_NoMemory();
66 obj = PyObject_CallFunction((PyObject *)&SignatureType, "s", sig);
67 dbus_free(sig);
68 if (!obj) return NULL;
70 if (!dbus_signature_iter_next(&(self->iter))) {
71 /* mark object as having been finished with */
72 Py_DECREF(self->string);
73 self->string = NULL;
76 return obj;
79 static PyObject *
80 SignatureIter_tp_iter(PyObject *self)
82 Py_INCREF(self);
83 return self;
86 static PyTypeObject SignatureIterType = {
87 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
89 "_dbus_bindings._SignatureIter",
90 sizeof(SignatureIter),
92 (destructor)SignatureIter_tp_dealloc, /* tp_dealloc */
93 0, /* tp_print */
94 0, /* tp_getattr */
95 0, /* tp_setattr */
96 0, /* tp_compare */
97 0, /* tp_repr */
98 0, /* tp_as_number */
99 0, /* tp_as_sequence */
100 0, /* tp_as_mapping */
101 0, /* tp_hash */
102 0, /* tp_call */
103 0, /* tp_str */
104 0, /* tp_getattro */
105 0, /* tp_setattro */
106 0, /* tp_as_buffer */
107 Py_TPFLAGS_DEFAULT, /* tp_flags */
108 0, /* tp_doc */
109 0, /* tp_traverse */
110 0, /* tp_clear */
111 0, /* tp_richcompare */
112 0, /* tp_weaklistoffset */
113 SignatureIter_tp_iter, /* tp_iter */
114 (iternextfunc)SignatureIter_tp_iternext, /* tp_iternext */
115 0, /* tp_methods */
116 0, /* tp_members */
117 0, /* tp_getset */
118 0, /* tp_base */
119 0, /* tp_dict */
120 0, /* tp_descr_get */
121 0, /* tp_descr_set */
122 0, /* tp_dictoffset */
123 0, /* tp_init */
124 0, /* tp_alloc */
125 /* deliberately not callable! Use iter(Signature) instead */
126 0, /* tp_new */
127 0, /* tp_free */
130 static PyObject *
131 Signature_tp_iter (PyObject *self)
133 SignatureIter *iter = PyObject_New(SignatureIter, &SignatureIterType);
134 if (!iter) return NULL;
136 if (PyString_AS_STRING (self)[0]) {
137 Py_INCREF(self);
138 iter->string = self;
139 dbus_signature_iter_init(&(iter->iter), PyString_AS_STRING(self));
141 else {
142 /* this is a null string, make a null iterator */
143 iter->string = NULL;
145 return (PyObject *)iter;
148 static PyObject *
149 Signature_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
151 PyObject *tuple, *self;
152 const char *str = NULL;
153 static char *argnames[] = {"object_path", NULL};
155 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:__new__", argnames,
156 &str)) return NULL;
157 if (!dbus_signature_validate(str, NULL)) {
158 PyErr_SetString(PyExc_ValueError, "Corrupt type signature");
159 return NULL;
161 tuple = Py_BuildValue("(s)", str);
162 if (!tuple) return NULL;
163 self = PyString_Type.tp_new(cls, tuple, NULL);
164 Py_DECREF(tuple);
165 return self;
168 static PyTypeObject SignatureType = {
169 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
171 "dbus.Signature",
174 0, /* tp_dealloc */
175 0, /* tp_print */
176 0, /* tp_getattr */
177 0, /* tp_setattr */
178 0, /* tp_compare */
179 str_subclass_tp_repr, /* tp_repr */
180 0, /* tp_as_number */
181 0, /* tp_as_sequence */
182 0, /* tp_as_mapping */
183 0, /* tp_hash */
184 0, /* tp_call */
185 0, /* tp_str */
186 0, /* tp_getattro */
187 0, /* tp_setattro */
188 0, /* tp_as_buffer */
189 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
190 Signature_tp_doc, /* tp_doc */
191 0, /* tp_traverse */
192 0, /* tp_clear */
193 0, /* tp_richcompare */
194 0, /* tp_weaklistoffset */
195 Signature_tp_iter, /* tp_iter */
196 0, /* tp_iternext */
197 0, /* tp_methods */
198 0, /* tp_members */
199 0, /* tp_getset */
200 DEFERRED_ADDRESS(&PyString_Type), /* tp_base */
201 0, /* tp_dict */
202 0, /* tp_descr_get */
203 0, /* tp_descr_set */
204 0, /* tp_dictoffset */
205 0, /* tp_init */
206 0, /* tp_alloc */
207 Signature_tp_new, /* tp_new */
208 0, /* tp_free */
211 static inline int
212 init_signature(void)
214 if (PyType_Ready(&SignatureIterType) < 0) return 0;
216 SignatureType.tp_base = &PyString_Type;
217 if (PyType_Ready(&SignatureType) < 0) return 0;
218 /* disable the tp_print copied from PyString_Type, so tp_repr gets called as
219 desired */
220 SignatureType.tp_print = NULL;
222 return 1;
225 static inline int
226 insert_signature (PyObject *this_module)
228 Py_INCREF(&SignatureType);
229 if (PyModule_AddObject(this_module, "Signature",
230 (PyObject *)&SignatureType) < 0) return 0;
231 Py_INCREF(&SignatureIterType);
232 if (PyModule_AddObject(this_module, "_SignatureIter",
233 (PyObject *)&SignatureIterType) < 0) return 0;
235 return 1;
238 /* vim:set ft=c cino< sw=4 sts=4 et: */