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 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "types-internal.h"
25 /* UTF-8 string representation ====================================== */
27 PyDoc_STRVAR(UTF8String_tp_doc
,
28 "A string represented using UTF-8 - a subtype of `str`.\n"
30 "All strings on D-Bus are required to be valid Unicode; in the \"wire\n"
31 "protocol\" they're transported as UTF-8.\n"
33 "By default, when byte arrays are converted from D-Bus to Python, they\n"
34 "come out as a `dbus.String`, which is a subtype of `unicode`.\n"
35 "If you prefer to get UTF-8 strings (as instances of this class) or you\n"
36 "want to avoid the conversion overhead of going from UTF-8 to Python's\n"
37 "internal Unicode representation, you can pass the ``utf8_strings=True``\n"
38 "keyword argument to any of these methods:\n"
40 "* any D-Bus method proxy, or ``connect_to_signal``, on the objects returned\n"
41 " by `Bus.get_object`\n"
42 "* any D-Bus method on a `dbus.Interface`\n"
43 "* `dbus.Interface.connect_to_signal`\n"
44 "* `Bus.add_signal_receiver`\n"
49 " dbus.UTF8String(value: str or unicode[, variant_level: int]) -> UTF8String\n"
51 "If value is a str object it must be valid UTF-8.\n"
53 "variant_level must be non-negative; the default is 0.\n"
56 " `variant_level` : int\n"
57 " Indicates how many nested Variant containers this object\n"
58 " is contained in: if a message's wire format has a variant containing a\n"
59 " variant containing a string, this is represented in Python by a\n"
60 " String or UTF8String with variant_level==2.\n"
61 ":Since: 0.80 (in older versions, use dbus.String)\n"
65 UTF8String_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
67 const char *str
= NULL
;
69 static char *argnames
[] = {"value", "variant_level", NULL
};
72 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|l:__new__", argnames
,
73 &str
, &variantness
)) return NULL
;
74 unicode
= PyUnicode_DecodeUTF8(str
, strlen(str
), NULL
);
75 if (!unicode
) return NULL
;
77 return (DBusPyStrBase_Type
.tp_new
)(cls
, args
, kwargs
);
80 PyTypeObject DBusPyUTF8String_Type
= {
81 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
93 0, /* tp_as_sequence */
94 0, /* tp_as_mapping */
100 0, /* tp_as_buffer */
101 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
102 UTF8String_tp_doc
, /* tp_doc */
105 0, /* tp_richcompare */
106 0, /* tp_weaklistoffset */
112 DEFERRED_ADDRESS(&DBusPyStrBase_Type
), /* tp_base */
114 0, /* tp_descr_get */
115 0, /* tp_descr_set */
116 0, /* tp_dictoffset */
119 UTF8String_tp_new
, /* tp_new */
122 /* Object path ====================================================== */
124 PyDoc_STRVAR(ObjectPath_tp_doc
,
125 "A D-Bus object path, such as '/com/example/MyApp/Documents/abc'.\n"
127 "ObjectPath is a subtype of str, and object-paths behave like strings.\n"
131 " dbus.ObjectPath(path: str, variant_level: int) -> ObjectPath\n"
133 "path must be an ASCII string following the syntax of object paths.\n"
134 "variant_level must be non-negative; the default is 0.\n"
137 " `variant_level` : int\n"
138 " Indicates how many nested Variant containers this object\n"
139 " is contained in: if a message's wire format has a variant containing a\n"
140 " variant containing an object path, this is represented in Python by an\n"
141 " ObjectPath with variant_level==2.\n"
145 ObjectPath_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
147 const char *str
= NULL
;
148 long variantness
= 0;
149 static char *argnames
[] = {"object_path", "variant_level", NULL
};
151 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|l:__new__", argnames
,
152 &str
, &variantness
)) return NULL
;
153 if (!dbus_py_validate_object_path(str
)) {
156 return (DBusPyStrBase_Type
.tp_new
)(cls
, args
, kwargs
);
159 PyTypeObject DBusPyObjectPath_Type
= {
160 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
171 0, /* tp_as_number */
172 0, /* tp_as_sequence */
173 0, /* tp_as_mapping */
179 0, /* tp_as_buffer */
180 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
181 ObjectPath_tp_doc
, /* tp_doc */
184 0, /* tp_richcompare */
185 0, /* tp_weaklistoffset */
191 DEFERRED_ADDRESS(&DBusPyStrBase_Type
), /* tp_base */
193 0, /* tp_descr_get */
194 0, /* tp_descr_set */
195 0, /* tp_dictoffset */
198 ObjectPath_tp_new
, /* tp_new */
201 /* Unicode string representation ==================================== */
203 PyDoc_STRVAR(String_tp_doc
,
204 "A string represented using Unicode - a subtype of `unicode`.\n"
206 "All strings on D-Bus are required to be valid Unicode; in the \"wire\n"
207 "protocol\" they're transported as UTF-8.\n"
209 "By default, when strings are converted from D-Bus to Python, they\n"
210 "come out as this class. If you prefer to get UTF-8 strings (as instances\n"
211 "of a subtype of `str`) or you want to avoid the conversion overhead of\n"
212 "going from UTF-8 to Python's internal Unicode representation, see the\n"
213 "documentation for `dbus.UTF8String`.\n"
217 " String(value: str or unicode[, variant_level: int]) -> String\n"
219 "variant_level must be non-negative; the default is 0.\n"
222 " `variant_level` : int\n"
223 " Indicates how many nested Variant containers this object\n"
224 " is contained in: if a message's wire format has a variant containing a\n"
225 " variant containing a string, this is represented in Python by a\n"
226 " String or UTF8String with variant_level==2.\n"
230 String_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
233 PyObject
*variantness
= NULL
;
234 static char *argnames
[] = {"variant_level", NULL
};
236 if (PyTuple_Size(args
) > 1) {
237 PyErr_SetString(PyExc_TypeError
,
238 "__new__ takes at most one positional parameter");
241 if (!PyArg_ParseTupleAndKeywords(dbus_py_empty_tuple
, kwargs
,
242 "|O!:__new__", argnames
,
243 &PyInt_Type
, &variantness
)) return NULL
;
245 variantness
= PyInt_FromLong(0);
246 if (!variantness
) return NULL
;
248 if (PyInt_AS_LONG(variantness
) < 0) {
249 PyErr_SetString(PyExc_ValueError
,
250 "variant_level must be non-negative");
254 self
= (PyUnicode_Type
.tp_new
)(cls
, args
, NULL
);
256 PyObject_GenericSetAttr(self
, dbus_py_variant_level_const
, variantness
);
262 String_tp_repr(PyObject
*self
)
264 PyObject
*parent_repr
= (PyUnicode_Type
.tp_repr
)(self
);
269 if (!parent_repr
) return NULL
;
270 vl_obj
= PyObject_GetAttr(self
, dbus_py_variant_level_const
);
271 if (!vl_obj
) return NULL
;
272 variant_level
= PyInt_AsLong(vl_obj
);
273 if (variant_level
> 0) {
274 my_repr
= PyString_FromFormat("%s(%s, variant_level=%ld)",
275 self
->ob_type
->tp_name
,
276 PyString_AS_STRING(parent_repr
),
280 my_repr
= PyString_FromFormat("%s(%s)", self
->ob_type
->tp_name
,
281 PyString_AS_STRING(parent_repr
));
283 /* whether my_repr is NULL or not: */
284 Py_DECREF(parent_repr
);
288 PyTypeObject DBusPyString_Type
= {
289 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
292 INT_MAX
, /* placeholder */
299 String_tp_repr
, /* tp_repr */
300 0, /* tp_as_number */
301 0, /* tp_as_sequence */
302 0, /* tp_as_mapping */
306 PyObject_GenericGetAttr
, /* tp_getattro */
307 dbus_py_immutable_setattro
, /* tp_setattro */
308 0, /* tp_as_buffer */
309 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
310 String_tp_doc
, /* tp_doc */
313 0, /* tp_richcompare */
314 0, /* tp_weaklistoffset */
320 DEFERRED_ADDRESS(&PyUnicode_Type
), /* tp_base */
322 0, /* tp_descr_get */
323 0, /* tp_descr_set */
324 -sizeof(void *), /* tp_dictoffset */
327 String_tp_new
, /* tp_new */
331 dbus_py_init_string_types(void)
333 DBusPyString_Type
.tp_basicsize
= PyUnicode_Type
.tp_basicsize
334 + 2*sizeof(PyObject
*) - 1;
335 DBusPyString_Type
.tp_basicsize
/= sizeof(PyObject
*);
336 DBusPyString_Type
.tp_basicsize
*= sizeof(PyObject
*);
337 DBusPyString_Type
.tp_base
= &PyUnicode_Type
;
338 if (PyType_Ready(&DBusPyString_Type
) < 0) return 0;
339 DBusPyString_Type
.tp_print
= NULL
;
341 DBusPyUTF8String_Type
.tp_basicsize
= PyUnicode_Type
.tp_basicsize
342 + 2*sizeof(PyObject
*) - 1;
343 DBusPyUTF8String_Type
.tp_basicsize
/= sizeof(PyObject
*);
344 DBusPyUTF8String_Type
.tp_basicsize
*= sizeof(PyObject
*);
345 DBusPyUTF8String_Type
.tp_base
= &DBusPyStrBase_Type
;
346 if (PyType_Ready(&DBusPyUTF8String_Type
) < 0) return 0;
347 DBusPyUTF8String_Type
.tp_print
= NULL
;
349 DBusPyObjectPath_Type
.tp_base
= &DBusPyStrBase_Type
;
350 if (PyType_Ready(&DBusPyObjectPath_Type
) < 0) return 0;
351 DBusPyObjectPath_Type
.tp_print
= NULL
;
353 DBusPyBoolean_Type
.tp_base
= &DBusPyIntBase_Type
;
354 if (PyType_Ready(&DBusPyBoolean_Type
) < 0) return 0;
355 DBusPyBoolean_Type
.tp_print
= NULL
;
361 dbus_py_insert_string_types(PyObject
*this_module
)
363 Py_INCREF(&DBusPyObjectPath_Type
);
364 Py_INCREF(&DBusPyUTF8String_Type
);
365 Py_INCREF(&DBusPyString_Type
);
366 if (PyModule_AddObject(this_module
, "ObjectPath",
367 (PyObject
*)&DBusPyObjectPath_Type
) < 0) return 0;
368 if (PyModule_AddObject(this_module
, "UTF8String",
369 (PyObject
*)&DBusPyUTF8String_Type
) < 0) return 0;
370 if (PyModule_AddObject(this_module
, "String",
371 (PyObject
*)&DBusPyString_Type
) < 0) return 0;
376 /* vim:set ft=c cino< sw=4 sts=4 et: */