Mention relicensing in NEWS
[dbus-python-phuang.git] / _dbus_bindings / signature.c
blob6b31ab403c988acaccb6be59f144f57728cfff71
1 /* Implementation of Signature type for D-Bus bindings.
3 * Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use, copy,
9 * modify, merge, publish, distribute, sublicense, and/or sell copies
10 * of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 #include <Python.h>
27 #include <structmember.h>
29 #include <stdint.h>
31 #include "dbus_bindings-internal.h"
32 #include "types-internal.h"
34 PyDoc_STRVAR(Signature_tp_doc,
35 "A string subclass whose values are restricted to valid D-Bus\n"
36 "signatures. When iterated over, instead of individual characters it\n"
37 "produces Signature instances representing single complete types.\n"
38 "\n"
39 "Constructor::\n"
40 "\n"
41 " ``Signature(value: str or unicode[, variant_level: int]) -> Signature``\n"
42 "\n"
43 "``value`` must be a valid D-Bus signature (zero or more single complete\n"
44 "types).\n"
45 "\n"
46 "``variant_level`` must be non-negative; the default is 0.\n"
47 "\n"
48 ":IVariables:\n"
49 " `variant_level` : int\n"
50 " Indicates how many nested Variant containers this object\n"
51 " is contained in: if a message's wire format has a variant containing a\n"
52 " variant containing a signature, this is represented in Python by a\n"
53 " Signature with variant_level==2.\n"
56 typedef struct {
57 PyObject_HEAD
58 PyObject *string;
59 DBusSignatureIter iter;
60 } SignatureIter;
62 static void
63 SignatureIter_tp_dealloc (SignatureIter *self)
65 Py_XDECREF(self->string);
66 self->string = NULL;
67 PyObject_Del(self);
70 static PyObject *
71 SignatureIter_tp_iternext (SignatureIter *self)
73 char *sig;
74 PyObject *obj;
76 /* Stop immediately if finished or not correctly initialized */
77 if (!self->string) return NULL;
79 sig = dbus_signature_iter_get_signature(&(self->iter));
80 if (!sig) return PyErr_NoMemory();
81 obj = PyObject_CallFunction((PyObject *)&DBusPySignature_Type, "s", sig);
82 dbus_free(sig);
83 if (!obj) return NULL;
85 if (!dbus_signature_iter_next(&(self->iter))) {
86 /* mark object as having been finished with */
87 Py_DECREF(self->string);
88 self->string = NULL;
91 return obj;
94 static PyObject *
95 SignatureIter_tp_iter(PyObject *self)
97 Py_INCREF(self);
98 return self;
101 static PyTypeObject SignatureIterType = {
102 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
104 "_dbus_bindings._SignatureIter",
105 sizeof(SignatureIter),
107 (destructor)SignatureIter_tp_dealloc, /* tp_dealloc */
108 0, /* tp_print */
109 0, /* tp_getattr */
110 0, /* tp_setattr */
111 0, /* tp_compare */
112 0, /* tp_repr */
113 0, /* tp_as_number */
114 0, /* tp_as_sequence */
115 0, /* tp_as_mapping */
116 0, /* tp_hash */
117 0, /* tp_call */
118 0, /* tp_str */
119 0, /* tp_getattro */
120 0, /* tp_setattro */
121 0, /* tp_as_buffer */
122 Py_TPFLAGS_DEFAULT, /* tp_flags */
123 0, /* tp_doc */
124 0, /* tp_traverse */
125 0, /* tp_clear */
126 0, /* tp_richcompare */
127 0, /* tp_weaklistoffset */
128 SignatureIter_tp_iter, /* tp_iter */
129 (iternextfunc)SignatureIter_tp_iternext, /* tp_iternext */
130 0, /* tp_methods */
131 0, /* tp_members */
132 0, /* tp_getset */
133 0, /* tp_base */
134 0, /* tp_dict */
135 0, /* tp_descr_get */
136 0, /* tp_descr_set */
137 0, /* tp_dictoffset */
138 0, /* tp_init */
139 0, /* tp_alloc */
140 /* deliberately not callable! Use iter(Signature) instead */
141 0, /* tp_new */
142 0, /* tp_free */
145 static PyObject *
146 Signature_tp_iter (PyObject *self)
148 SignatureIter *iter = PyObject_New(SignatureIter, &SignatureIterType);
149 if (!iter) return NULL;
151 if (PyString_AS_STRING (self)[0]) {
152 Py_INCREF(self);
153 iter->string = self;
154 dbus_signature_iter_init(&(iter->iter), PyString_AS_STRING(self));
156 else {
157 /* this is a null string, make a null iterator */
158 iter->string = NULL;
160 return (PyObject *)iter;
163 static PyObject *
164 Signature_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
166 const char *str = NULL;
167 PyObject *ignored;
168 static char *argnames[] = {"object_path", "variant_level", NULL};
170 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:__new__", argnames,
171 &str, &ignored)) return NULL;
172 if (!dbus_signature_validate(str, NULL)) {
173 PyErr_SetString(PyExc_ValueError, "Corrupt type signature");
174 return NULL;
176 return (DBusPyStrBase_Type.tp_new)(cls, args, kwargs);
179 PyTypeObject DBusPySignature_Type = {
180 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
182 "dbus.Signature",
185 0, /* tp_dealloc */
186 0, /* tp_print */
187 0, /* tp_getattr */
188 0, /* tp_setattr */
189 0, /* tp_compare */
190 0, /* tp_repr */
191 0, /* tp_as_number */
192 0, /* tp_as_sequence */
193 0, /* tp_as_mapping */
194 0, /* tp_hash */
195 0, /* tp_call */
196 0, /* tp_str */
197 0, /* tp_getattro */
198 0, /* tp_setattro */
199 0, /* tp_as_buffer */
200 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
201 Signature_tp_doc, /* tp_doc */
202 0, /* tp_traverse */
203 0, /* tp_clear */
204 0, /* tp_richcompare */
205 0, /* tp_weaklistoffset */
206 Signature_tp_iter, /* tp_iter */
207 0, /* tp_iternext */
208 0, /* tp_methods */
209 0, /* tp_members */
210 0, /* tp_getset */
211 DEFERRED_ADDRESS(&DBusPythonStringType), /* tp_base */
212 0, /* tp_dict */
213 0, /* tp_descr_get */
214 0, /* tp_descr_set */
215 0, /* tp_dictoffset */
216 0, /* tp_init */
217 0, /* tp_alloc */
218 Signature_tp_new, /* tp_new */
219 0, /* tp_free */
222 dbus_bool_t
223 dbus_py_init_signature(void)
225 if (PyType_Ready(&SignatureIterType) < 0) return 0;
227 DBusPySignature_Type.tp_base = &DBusPyStrBase_Type;
228 if (PyType_Ready(&DBusPySignature_Type) < 0) return 0;
229 DBusPySignature_Type.tp_print = NULL;
231 return 1;
234 dbus_bool_t
235 dbus_py_insert_signature(PyObject *this_module)
237 Py_INCREF(&DBusPySignature_Type);
238 if (PyModule_AddObject(this_module, "Signature",
239 (PyObject *)&DBusPySignature_Type) < 0) return 0;
240 Py_INCREF(&SignatureIterType);
241 if (PyModule_AddObject(this_module, "_SignatureIter",
242 (PyObject *)&SignatureIterType) < 0) return 0;
244 return 1;
247 /* vim:set ft=c cino< sw=4 sts=4 et: */