Separate out remaining types (abstract, bytes, containers, int, float, signature...
[dbus-python-phuang.git] / _dbus_bindings / string.c
blob6059595c13d9acd4cc5fc60b3542786f87041713
1 /* Simple D-Bus types: ObjectPath and other string types.
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 #include "types-internal.h"
27 /* UTF-8 string representation ====================================== */
29 PyDoc_STRVAR(UTF8String_tp_doc,
30 "A string represented using UTF-8 - a subtype of `str`.\n"
31 "\n"
32 ":Constructor:\n"
33 " UTF8String(value: str or unicode[, variant_level: int]) -> UTF8String\n"
34 " If value is a str object it must be valid UTF-8.\n"
35 "\n"
36 " variant_level must be non-negative; the default is 0.\n"
37 "\n"
38 ":IVariables:\n"
39 " `variant_level` : int\n"
40 " Indicates how many nested Variant containers this object\n"
41 " is contained in: if a message's wire format has a variant containing a\n"
42 " variant containing a string, this is represented in Python by a\n"
43 " String or UTF8String with variant_level==2.\n"
44 ":Since: 0.80 (in older versions, use dbus.String)\n"
47 static PyObject *
48 UTF8String_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
50 const char *str = NULL;
51 long variantness = 0;
52 static char *argnames[] = {"value", "variant_level", NULL};
53 PyObject *unicode;
55 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|l:__new__", argnames,
56 &str, &variantness)) return NULL;
57 unicode = PyUnicode_DecodeUTF8(str, strlen(str), NULL);
58 if (!unicode) return NULL;
59 Py_DECREF(unicode);
60 return (DBusPyStrBase_Type.tp_new)(cls, args, kwargs);
63 PyTypeObject DBusPyUTF8String_Type = {
64 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
66 "dbus.UTF8String",
69 0, /* tp_dealloc */
70 0, /* tp_print */
71 0, /* tp_getattr */
72 0, /* tp_setattr */
73 0, /* tp_compare */
74 0, /* tp_repr */
75 0, /* tp_as_number */
76 0, /* tp_as_sequence */
77 0, /* tp_as_mapping */
78 0, /* tp_hash */
79 0, /* tp_call */
80 0, /* tp_str */
81 0, /* tp_getattro */
82 0, /* tp_setattro */
83 0, /* tp_as_buffer */
84 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
85 UTF8String_tp_doc, /* tp_doc */
86 0, /* tp_traverse */
87 0, /* tp_clear */
88 0, /* tp_richcompare */
89 0, /* tp_weaklistoffset */
90 0, /* tp_iter */
91 0, /* tp_iternext */
92 0, /* tp_methods */
93 0, /* tp_members */
94 0, /* tp_getset */
95 DEFERRED_ADDRESS(&DBusPyStrBase_Type), /* tp_base */
96 0, /* tp_dict */
97 0, /* tp_descr_get */
98 0, /* tp_descr_set */
99 0, /* tp_dictoffset */
100 0, /* tp_init */
101 0, /* tp_alloc */
102 UTF8String_tp_new, /* tp_new */
105 /* Object path ====================================================== */
107 PyDoc_STRVAR(ObjectPath_tp_doc,
108 "A D-Bus object path, such as '/com/example/MyApp/Documents/abc'.\n"
109 "\n"
110 "ObjectPath is a subtype of str, and object-paths behave like strings.\n"
111 "\n"
112 ":Constructor:\n"
113 " ObjectPath(path: str[, variant_level: int]) -> ObjectPath\n"
114 " path must be an ASCII string following the syntax of object paths.\n"
115 " variant_level must be non-negative; the default is 0.\n"
116 "\n"
117 ":IVariables:\n"
118 " `variant_level` : int\n"
119 " Indicates how many nested Variant containers this object\n"
120 " is contained in: if a message's wire format has a variant containing a\n"
121 " variant containing an object path, this is represented in Python by an\n"
122 " ObjectPath with variant_level==2.\n"
125 static PyObject *
126 ObjectPath_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
128 const char *str = NULL;
129 long variantness = 0;
130 static char *argnames[] = {"object_path", "variant_level", NULL};
132 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|l:__new__", argnames,
133 &str, &variantness)) return NULL;
134 if (!dbus_py_validate_object_path(str)) {
135 return NULL;
137 return (DBusPyStrBase_Type.tp_new)(cls, args, kwargs);
140 PyTypeObject DBusPyObjectPath_Type = {
141 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
143 "dbus.ObjectPath",
146 0, /* tp_dealloc */
147 0, /* tp_print */
148 0, /* tp_getattr */
149 0, /* tp_setattr */
150 0, /* tp_compare */
151 0, /* tp_repr */
152 0, /* tp_as_number */
153 0, /* tp_as_sequence */
154 0, /* tp_as_mapping */
155 0, /* tp_hash */
156 0, /* tp_call */
157 0, /* tp_str */
158 0, /* tp_getattro */
159 0, /* tp_setattro */
160 0, /* tp_as_buffer */
161 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
162 ObjectPath_tp_doc, /* tp_doc */
163 0, /* tp_traverse */
164 0, /* tp_clear */
165 0, /* tp_richcompare */
166 0, /* tp_weaklistoffset */
167 0, /* tp_iter */
168 0, /* tp_iternext */
169 0, /* tp_methods */
170 0, /* tp_members */
171 0, /* tp_getset */
172 DEFERRED_ADDRESS(&DBusPyStrBase_Type), /* tp_base */
173 0, /* tp_dict */
174 0, /* tp_descr_get */
175 0, /* tp_descr_set */
176 0, /* tp_dictoffset */
177 0, /* tp_init */
178 0, /* tp_alloc */
179 ObjectPath_tp_new, /* tp_new */
182 /* Unicode string representation ==================================== */
184 PyDoc_STRVAR(String_tp_doc,
185 "A string represented using Unicode - a subtype of `unicode`.\n"
186 "\n"
187 ":Constructor:\n"
188 " String(value: str or unicode[, variant_level: int]) -> String\n"
189 "\n"
190 " variant_level must be non-negative; the default is 0.\n"
191 "\n"
192 ":IVariables:\n"
193 " `variant_level` : int\n"
194 " Indicates how many nested Variant containers this object\n"
195 " is contained in: if a message's wire format has a variant containing a\n"
196 " variant containing a string, this is represented in Python by a\n"
197 " String or UTF8String with variant_level==2.\n"
200 static PyObject *
201 String_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
203 PyObject *self;
204 PyObject *variantness = NULL;
205 static char *argnames[] = {"variant_level", NULL};
207 if (PyTuple_Size(args) > 1) {
208 PyErr_SetString(PyExc_TypeError,
209 "__new__ takes at most one positional parameter");
210 return NULL;
212 if (!PyArg_ParseTupleAndKeywords(dbus_py_empty_tuple, kwargs,
213 "|O!:__new__", argnames,
214 &PyInt_Type, &variantness)) return NULL;
215 if (!variantness) {
216 variantness = PyInt_FromLong(0);
217 if (!variantness) return NULL;
219 if (PyInt_AS_LONG(variantness) < 0) {
220 PyErr_SetString(PyExc_ValueError,
221 "variant_level must be non-negative");
222 return NULL;
225 self = (PyUnicode_Type.tp_new)(cls, args, NULL);
226 if (self) {
227 PyObject_GenericSetAttr(self, dbus_py_variant_level_const, variantness);
229 return self;
232 static PyObject *
233 String_tp_repr(PyObject *self)
235 PyObject *parent_repr = (PyUnicode_Type.tp_repr)(self);
236 PyObject *vl_obj;
237 PyObject *my_repr;
238 long variant_level;
240 if (!parent_repr) return NULL;
241 vl_obj = PyObject_GetAttr(self, dbus_py_variant_level_const);
242 if (!vl_obj) return NULL;
243 variant_level = PyInt_AsLong(vl_obj);
244 if (variant_level > 0) {
245 my_repr = PyString_FromFormat("%s(%s, variant_level=%ld)",
246 self->ob_type->tp_name,
247 PyString_AS_STRING(parent_repr),
248 variant_level);
250 else {
251 my_repr = PyString_FromFormat("%s(%s)", self->ob_type->tp_name,
252 PyString_AS_STRING(parent_repr));
254 /* whether my_repr is NULL or not: */
255 Py_DECREF(parent_repr);
256 return my_repr;
259 PyTypeObject DBusPyString_Type = {
260 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
262 "dbus.String",
263 INT_MAX, /* placeholder */
265 0, /* tp_dealloc */
266 0, /* tp_print */
267 0, /* tp_getattr */
268 0, /* tp_setattr */
269 0, /* tp_compare */
270 String_tp_repr, /* tp_repr */
271 0, /* tp_as_number */
272 0, /* tp_as_sequence */
273 0, /* tp_as_mapping */
274 0, /* tp_hash */
275 0, /* tp_call */
276 0, /* tp_str */
277 PyObject_GenericGetAttr, /* tp_getattro */
278 dbus_py_immutable_setattro, /* tp_setattro */
279 0, /* tp_as_buffer */
280 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
281 String_tp_doc, /* tp_doc */
282 0, /* tp_traverse */
283 0, /* tp_clear */
284 0, /* tp_richcompare */
285 0, /* tp_weaklistoffset */
286 0, /* tp_iter */
287 0, /* tp_iternext */
288 0, /* tp_methods */
289 0, /* tp_members */
290 0, /* tp_getset */
291 DEFERRED_ADDRESS(&PyUnicode_Type), /* tp_base */
292 0, /* tp_dict */
293 0, /* tp_descr_get */
294 0, /* tp_descr_set */
295 -sizeof(void *), /* tp_dictoffset */
296 0, /* tp_init */
297 0, /* tp_alloc */
298 String_tp_new, /* tp_new */
301 dbus_bool_t
302 dbus_py_init_string_types(void)
304 DBusPyString_Type.tp_basicsize = PyUnicode_Type.tp_basicsize
305 + 2*sizeof(PyObject *) - 1;
306 DBusPyString_Type.tp_basicsize /= sizeof(PyObject *);
307 DBusPyString_Type.tp_basicsize *= sizeof(PyObject *);
308 DBusPyString_Type.tp_base = &PyUnicode_Type;
309 if (PyType_Ready(&DBusPyString_Type) < 0) return 0;
310 DBusPyString_Type.tp_print = NULL;
312 DBusPyUTF8String_Type.tp_basicsize = PyUnicode_Type.tp_basicsize
313 + 2*sizeof(PyObject *) - 1;
314 DBusPyUTF8String_Type.tp_basicsize /= sizeof(PyObject *);
315 DBusPyUTF8String_Type.tp_basicsize *= sizeof(PyObject *);
316 DBusPyUTF8String_Type.tp_base = &DBusPyStrBase_Type;
317 if (PyType_Ready(&DBusPyUTF8String_Type) < 0) return 0;
318 DBusPyUTF8String_Type.tp_print = NULL;
320 DBusPyObjectPath_Type.tp_base = &DBusPyStrBase_Type;
321 if (PyType_Ready(&DBusPyObjectPath_Type) < 0) return 0;
322 DBusPyObjectPath_Type.tp_print = NULL;
324 DBusPyBoolean_Type.tp_base = &DBusPyIntBase_Type;
325 if (PyType_Ready(&DBusPyBoolean_Type) < 0) return 0;
326 DBusPyBoolean_Type.tp_print = NULL;
328 return 1;
331 dbus_bool_t
332 dbus_py_insert_string_types(PyObject *this_module)
334 Py_INCREF(&DBusPyObjectPath_Type);
335 Py_INCREF(&DBusPyUTF8String_Type);
336 Py_INCREF(&DBusPyString_Type);
337 if (PyModule_AddObject(this_module, "ObjectPath",
338 (PyObject *)&DBusPyObjectPath_Type) < 0) return 0;
339 if (PyModule_AddObject(this_module, "UTF8String",
340 (PyObject *)&DBusPyUTF8String_Type) < 0) return 0;
341 if (PyModule_AddObject(this_module, "String",
342 (PyObject *)&DBusPyString_Type) < 0) return 0;
344 return 1;
347 /* vim:set ft=c cino< sw=4 sts=4 et: */