|
Packit |
130fc8 |
/* D-Bus Message unserialization. This contains all the logic to map from
|
|
Packit |
130fc8 |
* D-Bus types to Python objects.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Copyright (C) 2006-2007 Collabora Ltd. <http://www.collabora.co.uk/>
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Permission is hereby granted, free of charge, to any person
|
|
Packit |
130fc8 |
* obtaining a copy of this software and associated documentation
|
|
Packit |
130fc8 |
* files (the "Software"), to deal in the Software without
|
|
Packit |
130fc8 |
* restriction, including without limitation the rights to use, copy,
|
|
Packit |
130fc8 |
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
130fc8 |
* of the Software, and to permit persons to whom the Software is
|
|
Packit |
130fc8 |
* furnished to do so, subject to the following conditions:
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* The above copyright notice and this permission notice shall be
|
|
Packit |
130fc8 |
* included in all copies or substantial portions of the Software.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
130fc8 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
130fc8 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
130fc8 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
130fc8 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
Packit |
130fc8 |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Packit |
130fc8 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Packit |
130fc8 |
* DEALINGS IN THE SOFTWARE.
|
|
Packit |
130fc8 |
*/
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#include "dbus_bindings-internal.h"
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#define DBG_IS_TOO_VERBOSE
|
|
Packit |
130fc8 |
#include "compat-internal.h"
|
|
Packit |
130fc8 |
#include "types-internal.h"
|
|
Packit |
130fc8 |
#include "message-internal.h"
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
char dbus_py_Message_get_args_list__doc__[] = (
|
|
Packit |
130fc8 |
"get_args_list(**kwargs) -> list\n\n"
|
|
Packit |
130fc8 |
"Return the message's arguments. Keyword arguments control the translation\n"
|
|
Packit |
130fc8 |
"of D-Bus types to Python:\n"
|
|
Packit |
130fc8 |
"\n"
|
|
Packit |
130fc8 |
":Keywords:\n"
|
|
Packit |
130fc8 |
" `byte_arrays` : bool\n"
|
|
Packit |
130fc8 |
" If true, convert arrays of byte (signature 'ay') into dbus.ByteArray,\n"
|
|
Packit |
130fc8 |
" a str subclass. In practice, this is usually what you want, but\n"
|
|
Packit |
130fc8 |
" it's off by default for consistency.\n"
|
|
Packit |
130fc8 |
"\n"
|
|
Packit |
130fc8 |
" If false (default), convert them into a dbus.Array of Bytes.\n"
|
|
Packit |
130fc8 |
#ifndef PY3
|
|
Packit |
130fc8 |
" `utf8_strings` : bool\n"
|
|
Packit |
130fc8 |
" If true, return D-Bus strings as Python 8-bit strings (of UTF-8).\n"
|
|
Packit |
130fc8 |
" If false (default), return D-Bus strings as Python unicode objects.\n"
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
"\n"
|
|
Packit |
130fc8 |
"Most of the type mappings should be fairly obvious:\n"
|
|
Packit |
130fc8 |
"\n"
|
|
Packit |
130fc8 |
"=============== ===================================================\n"
|
|
Packit |
130fc8 |
"D-Bus Python\n"
|
|
Packit |
130fc8 |
"=============== ===================================================\n"
|
|
Packit |
130fc8 |
"byte (y) dbus.Byte (int subclass)\n"
|
|
Packit |
130fc8 |
"bool (b) dbus.Boolean (int subclass)\n"
|
|
Packit |
130fc8 |
"Signature (g) dbus.Signature (str subclass)\n"
|
|
Packit |
130fc8 |
"intNN, uintNN dbus.IntNN, dbus.UIntNN (int or long subclasses)\n"
|
|
Packit |
130fc8 |
"double (d) dbus.Double\n"
|
|
Packit |
130fc8 |
"string (s) dbus.String (unicode subclass)\n"
|
|
Packit |
130fc8 |
" (or dbus.UTF8String, str subclass, if utf8_strings set)\n"
|
|
Packit |
130fc8 |
"Object path (o) dbus.ObjectPath (str subclass)\n"
|
|
Packit |
130fc8 |
"dict (a{...}) dbus.Dictionary\n"
|
|
Packit |
130fc8 |
"array (a...) dbus.Array (list subclass) containing appropriate types\n"
|
|
Packit |
130fc8 |
"byte array (ay) dbus.ByteArray (str subclass) if byte_arrays set; or\n"
|
|
Packit |
130fc8 |
" list of Byte\n"
|
|
Packit |
130fc8 |
"struct ((...)) dbus.Struct (tuple subclass) of appropriate types\n"
|
|
Packit |
130fc8 |
"variant (v) contained type, but with variant_level > 0\n"
|
|
Packit |
130fc8 |
"=============== ===================================================\n"
|
|
Packit |
130fc8 |
);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
typedef struct {
|
|
Packit |
130fc8 |
int byte_arrays;
|
|
Packit |
130fc8 |
#ifndef PY3
|
|
Packit |
130fc8 |
int utf8_strings;
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
} Message_get_args_options;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
static PyObject *_message_iter_get_pyobject(DBusMessageIter *iter,
|
|
Packit |
130fc8 |
Message_get_args_options *opts,
|
|
Packit |
130fc8 |
long extra_variants);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* Append all the items iterated over to the given Python list object.
|
|
Packit |
130fc8 |
* Return 0 on success/-1 with exception on failure. */
|
|
Packit |
130fc8 |
static int
|
|
Packit |
130fc8 |
_message_iter_append_all_to_list(DBusMessageIter *iter, PyObject *list,
|
|
Packit |
130fc8 |
Message_get_args_options *opts)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
int ret, type;
|
|
Packit |
130fc8 |
while ((type = dbus_message_iter_get_arg_type(iter))
|
|
Packit |
130fc8 |
!= DBUS_TYPE_INVALID) {
|
|
Packit |
130fc8 |
PyObject *item;
|
|
Packit |
130fc8 |
DBG("type == %d '%c'", type, type);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
item = _message_iter_get_pyobject(iter, opts, 0);
|
|
Packit |
130fc8 |
if (!item) return -1;
|
|
Packit |
130fc8 |
#ifdef USING_DBG
|
|
Packit |
130fc8 |
fprintf(stderr, "DBG/%ld: appending to list: %p == ", (long)getpid(), item);
|
|
Packit |
130fc8 |
PyObject_Print(item, stderr, 0);
|
|
Packit |
130fc8 |
fprintf(stderr, " of type %p\n", Py_TYPE(item));
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
ret = PyList_Append(list, item);
|
|
Packit |
130fc8 |
Py_CLEAR(item);
|
|
Packit |
130fc8 |
if (ret < 0) return -1;
|
|
Packit |
130fc8 |
#ifdef USING_DBG
|
|
Packit |
130fc8 |
fprintf(stderr, "DBG/%ld: list now contains: ", (long)getpid());
|
|
Packit |
130fc8 |
PyObject_Print(list, stderr, 0);
|
|
Packit |
130fc8 |
fprintf(stderr, "\n");
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
dbus_message_iter_next(iter);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return 0;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
static inline PyObject *
|
|
Packit |
130fc8 |
_message_iter_get_dict(DBusMessageIter *iter,
|
|
Packit |
130fc8 |
Message_get_args_options *opts,
|
|
Packit |
130fc8 |
PyObject *kwargs)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
DBusMessageIter entries;
|
|
Packit |
130fc8 |
char *sig_str = dbus_message_iter_get_signature(iter);
|
|
Packit |
130fc8 |
PyObject *sig;
|
|
Packit |
130fc8 |
PyObject *ret;
|
|
Packit |
130fc8 |
int status;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!sig_str) {
|
|
Packit |
130fc8 |
PyErr_NoMemory();
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
sig = PyObject_CallFunction((PyObject *)&DBusPySignature_Type,
|
|
Packit |
130fc8 |
"(s#)", sig_str+2,
|
|
Packit |
130fc8 |
(Py_ssize_t)strlen(sig_str)-3);
|
|
Packit |
130fc8 |
dbus_free(sig_str);
|
|
Packit |
130fc8 |
if (!sig) {
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
status = PyDict_SetItem(kwargs, dbus_py_signature_const, sig);
|
|
Packit |
130fc8 |
Py_CLEAR(sig);
|
|
Packit |
130fc8 |
if (status < 0) {
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyDict_Type, dbus_py_empty_tuple, kwargs);
|
|
Packit |
130fc8 |
if (!ret) {
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_message_iter_recurse(iter, &entries);
|
|
Packit |
130fc8 |
while (dbus_message_iter_get_arg_type(&entries) == DBUS_TYPE_DICT_ENTRY) {
|
|
Packit |
130fc8 |
PyObject *key = NULL;
|
|
Packit |
130fc8 |
PyObject *value = NULL;
|
|
Packit |
130fc8 |
DBusMessageIter kv;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
DBG("%s", "dict entry...");
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_message_iter_recurse(&entries, &kv;;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
key = _message_iter_get_pyobject(&kv, opts, 0);
|
|
Packit |
130fc8 |
if (!key) {
|
|
Packit |
130fc8 |
Py_CLEAR(ret);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
dbus_message_iter_next(&kv;;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
value = _message_iter_get_pyobject(&kv, opts, 0);
|
|
Packit |
130fc8 |
if (!value) {
|
|
Packit |
130fc8 |
Py_CLEAR(key);
|
|
Packit |
130fc8 |
Py_CLEAR(ret);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
status = PyDict_SetItem(ret, key, value);
|
|
Packit |
130fc8 |
Py_CLEAR(key);
|
|
Packit |
130fc8 |
Py_CLEAR(value);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (status < 0) {
|
|
Packit |
130fc8 |
Py_CLEAR(ret);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
dbus_message_iter_next(&entries);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
return ret;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* Returns a new reference. */
|
|
Packit |
130fc8 |
static PyObject *
|
|
Packit |
130fc8 |
_message_iter_get_pyobject(DBusMessageIter *iter,
|
|
Packit |
130fc8 |
Message_get_args_options *opts,
|
|
Packit |
130fc8 |
long variant_level)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
DBusBasicValue u;
|
|
Packit |
130fc8 |
int type = dbus_message_iter_get_arg_type(iter);
|
|
Packit |
130fc8 |
PyObject *args = NULL;
|
|
Packit |
130fc8 |
PyObject *kwargs = NULL;
|
|
Packit |
130fc8 |
PyObject *ret = NULL;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* If the variant-level is >0, prepare a dict for the kwargs.
|
|
Packit |
130fc8 |
* For variant wrappers optimize slightly by skipping this.
|
|
Packit |
130fc8 |
*/
|
|
Packit |
130fc8 |
if (variant_level > 0 && type != DBUS_TYPE_VARIANT) {
|
|
Packit |
130fc8 |
PyObject *variant_level_int;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
variant_level_int = NATIVEINT_FROMLONG(variant_level);
|
|
Packit |
130fc8 |
if (!variant_level_int) {
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
kwargs = PyDict_New();
|
|
Packit |
130fc8 |
if (!kwargs) {
|
|
Packit |
130fc8 |
Py_CLEAR(variant_level_int);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (PyDict_SetItem(kwargs, dbus_py_variant_level_const,
|
|
Packit |
130fc8 |
variant_level_int) < 0) {
|
|
Packit |
130fc8 |
Py_CLEAR(variant_level_int);
|
|
Packit |
130fc8 |
Py_CLEAR(kwargs);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
Py_CLEAR(variant_level_int);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
/* From here down you need to break from the switch to exit, so the
|
|
Packit |
130fc8 |
* dict is freed if necessary
|
|
Packit |
130fc8 |
*/
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
switch (type) {
|
|
Packit |
130fc8 |
PyObject *unicode;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_STRING:
|
|
Packit |
130fc8 |
DBG("%s", "found a string");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.str);
|
|
Packit |
130fc8 |
#ifndef PY3
|
|
Packit |
130fc8 |
if (opts->utf8_strings) {
|
|
Packit |
130fc8 |
args = Py_BuildValue("(s)", u.str);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyUTF8String_Type,
|
|
Packit |
130fc8 |
args, kwargs);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else {
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
unicode = PyUnicode_DecodeUTF8(u.str, strlen(u.str), NULL);
|
|
Packit |
130fc8 |
if (!unicode) {
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
args = Py_BuildValue("(N)", unicode);
|
|
Packit |
130fc8 |
if (!args) {
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyString_Type,
|
|
Packit |
130fc8 |
args, kwargs);
|
|
Packit |
130fc8 |
#ifndef PY3
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_SIGNATURE:
|
|
Packit |
130fc8 |
DBG("%s", "found a signature");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.str);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(s)", u.str);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPySignature_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_OBJECT_PATH:
|
|
Packit |
130fc8 |
DBG("%s", "found an object path");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.str);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(s)", u.str);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyObjectPath_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_DOUBLE:
|
|
Packit |
130fc8 |
DBG("%s", "found a double");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.dbl);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(f)", u.dbl);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyDouble_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#ifdef WITH_DBUS_FLOAT32
|
|
Packit |
130fc8 |
case DBUS_TYPE_FLOAT:
|
|
Packit |
130fc8 |
DBG("%s", "found a float");
|
|
Packit |
130fc8 |
/* FIXME: DBusBasicValue will need to grow a float member if
|
|
Packit |
130fc8 |
* float32 becomes supported */
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.f);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(f)", (double)u.f);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyFloat_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_INT16:
|
|
Packit |
130fc8 |
DBG("%s", "found an int16");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.i16);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(i)", (int)u.i16);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyInt16_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_UINT16:
|
|
Packit |
130fc8 |
DBG("%s", "found a uint16");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.u16);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(i)", (int)u.u16);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyUInt16_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_INT32:
|
|
Packit |
130fc8 |
DBG("%s", "found an int32");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.i32);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(l)", (long)u.i32);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyInt32_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_UINT32:
|
|
Packit |
130fc8 |
DBG("%s", "found a uint32");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.u32);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(k)", (unsigned long)u.u32);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyUInt32_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#ifdef DBUS_TYPE_UNIX_FD
|
|
Packit |
130fc8 |
case DBUS_TYPE_UNIX_FD:
|
|
Packit |
130fc8 |
DBG("%s", "found an unix fd");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.fd);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(i)", u.fd);
|
|
Packit |
130fc8 |
if (args) {
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyUnixFd_Type, args,
|
|
Packit |
130fc8 |
kwargs);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (u.fd >= 0) {
|
|
Packit |
130fc8 |
close(u.fd);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG)
|
|
Packit |
130fc8 |
case DBUS_TYPE_INT64:
|
|
Packit |
130fc8 |
DBG("%s", "found an int64");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.i64);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(L)", (PY_LONG_LONG)u.i64);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyInt64_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_UINT64:
|
|
Packit |
130fc8 |
DBG("%s", "found a uint64");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.u64);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(K)", (unsigned PY_LONG_LONG)u.u64);
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyUInt64_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
#else
|
|
Packit |
130fc8 |
case DBUS_TYPE_INT64:
|
|
Packit |
130fc8 |
case DBUS_TYPE_UINT64:
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_NotImplementedError,
|
|
Packit |
130fc8 |
"64-bit integer types are not supported on "
|
|
Packit |
130fc8 |
"this platform");
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_BYTE:
|
|
Packit |
130fc8 |
DBG("%s", "found a byte");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.byt);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(l)", (long)u.byt);
|
|
Packit |
130fc8 |
if (!args)
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyByte_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_BOOLEAN:
|
|
Packit |
130fc8 |
DBG("%s", "found a bool");
|
|
Packit |
130fc8 |
dbus_message_iter_get_basic(iter, &u.bool_val);
|
|
Packit |
130fc8 |
args = Py_BuildValue("(l)", (long)u.bool_val);
|
|
Packit |
130fc8 |
if (!args)
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyBoolean_Type, args, kwargs);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_ARRAY:
|
|
Packit |
130fc8 |
DBG("%s", "found an array...");
|
|
Packit |
130fc8 |
/* Dicts are arrays of DBUS_TYPE_DICT_ENTRY on the wire.
|
|
Packit |
130fc8 |
Also, we special-case arrays of DBUS_TYPE_BYTE sometimes. */
|
|
Packit |
130fc8 |
type = dbus_message_iter_get_element_type(iter);
|
|
Packit |
130fc8 |
if (type == DBUS_TYPE_DICT_ENTRY) {
|
|
Packit |
130fc8 |
DBG("%s", "no, actually it's a dict...");
|
|
Packit |
130fc8 |
if (!kwargs) {
|
|
Packit |
130fc8 |
kwargs = PyDict_New();
|
|
Packit |
130fc8 |
if (!kwargs) break;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
ret = _message_iter_get_dict(iter, opts, kwargs);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (opts->byte_arrays && type == DBUS_TYPE_BYTE) {
|
|
Packit |
130fc8 |
DBusMessageIter sub;
|
|
Packit |
130fc8 |
int n;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
DBG("%s", "actually, a byte array...");
|
|
Packit |
130fc8 |
dbus_message_iter_recurse(iter, &sub);
|
|
Packit |
130fc8 |
dbus_message_iter_get_fixed_array(&sub,
|
|
Packit |
130fc8 |
(const unsigned char **)&u.str,
|
|
Packit |
130fc8 |
&n);
|
|
Packit |
130fc8 |
if (n == 0 && u.str == NULL) {
|
|
Packit |
130fc8 |
/* fd.o #21831: s# turns (NULL, 0) into None, but
|
|
Packit |
130fc8 |
* dbus_message_iter_get_fixed_array produces (NULL, 0)
|
|
Packit |
130fc8 |
* for an empty byte-blob... */
|
|
Packit |
130fc8 |
u.str = "";
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
#ifdef PY3
|
|
Packit |
130fc8 |
args = Py_BuildValue("(y#)", u.str, (Py_ssize_t)n);
|
|
Packit |
130fc8 |
#else
|
|
Packit |
130fc8 |
args = Py_BuildValue("(s#)", u.str, (Py_ssize_t)n);
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
if (!args) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyByteArray_Type,
|
|
Packit |
130fc8 |
args, kwargs);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else {
|
|
Packit |
130fc8 |
DBusMessageIter sub;
|
|
Packit |
130fc8 |
char *sig;
|
|
Packit |
130fc8 |
PyObject *sig_obj;
|
|
Packit |
130fc8 |
int status;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
DBG("%s", "a normal array...");
|
|
Packit |
130fc8 |
if (!kwargs) {
|
|
Packit |
130fc8 |
kwargs = PyDict_New();
|
|
Packit |
130fc8 |
if (!kwargs) break;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
dbus_message_iter_recurse(iter, &sub);
|
|
Packit |
130fc8 |
sig = dbus_message_iter_get_signature(&sub);
|
|
Packit |
130fc8 |
if (!sig) break;
|
|
Packit |
130fc8 |
sig_obj = PyObject_CallFunction((PyObject *)&DBusPySignature_Type,
|
|
Packit |
130fc8 |
"(s)", sig);
|
|
Packit |
130fc8 |
dbus_free(sig);
|
|
Packit |
130fc8 |
if (!sig_obj) break;
|
|
Packit |
130fc8 |
status = PyDict_SetItem(kwargs, dbus_py_signature_const, sig_obj);
|
|
Packit |
130fc8 |
Py_CLEAR(sig_obj);
|
|
Packit |
130fc8 |
if (status < 0) break;
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyArray_Type,
|
|
Packit |
130fc8 |
dbus_py_empty_tuple, kwargs);
|
|
Packit |
130fc8 |
if (!ret) break;
|
|
Packit |
130fc8 |
if (_message_iter_append_all_to_list(&sub, ret, opts) < 0) {
|
|
Packit |
130fc8 |
Py_CLEAR(ret);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_STRUCT:
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
DBusMessageIter sub;
|
|
Packit |
130fc8 |
PyObject *list = PyList_New(0);
|
|
Packit |
130fc8 |
PyObject *tuple;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
DBG("%s", "found a struct...");
|
|
Packit |
130fc8 |
if (!list) break;
|
|
Packit |
130fc8 |
dbus_message_iter_recurse(iter, &sub);
|
|
Packit |
130fc8 |
if (_message_iter_append_all_to_list(&sub, list, opts) < 0) {
|
|
Packit |
130fc8 |
Py_CLEAR(list);
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
tuple = Py_BuildValue("(O)", list);
|
|
Packit |
130fc8 |
if (tuple) {
|
|
Packit |
130fc8 |
ret = PyObject_Call((PyObject *)&DBusPyStruct_Type, tuple, kwargs);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else {
|
|
Packit |
130fc8 |
ret = NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
/* whether successful or not, we take the same action: */
|
|
Packit |
130fc8 |
Py_CLEAR(list);
|
|
Packit |
130fc8 |
Py_CLEAR(tuple);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
case DBUS_TYPE_VARIANT:
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
DBusMessageIter sub;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
DBG("%s", "found a variant...");
|
|
Packit |
130fc8 |
dbus_message_iter_recurse(iter, &sub);
|
|
Packit |
130fc8 |
ret = _message_iter_get_pyobject(&sub, opts, variant_level+1);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
break;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
default:
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_TypeError, "Unknown type '\\%x' in D-Bus "
|
|
Packit |
130fc8 |
"message", type);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
Py_CLEAR(args);
|
|
Packit |
130fc8 |
Py_CLEAR(kwargs);
|
|
Packit |
130fc8 |
return ret;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
PyObject *
|
|
Packit |
130fc8 |
dbus_py_Message_get_args_list(Message *self, PyObject *args, PyObject *kwargs)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
#ifdef PY3
|
|
Packit |
130fc8 |
Message_get_args_options opts = { 0 };
|
|
Packit |
130fc8 |
static char *argnames[] = { "byte_arrays", NULL };
|
|
Packit |
130fc8 |
#else
|
|
Packit |
130fc8 |
Message_get_args_options opts = { 0, 0 };
|
|
Packit |
130fc8 |
static char *argnames[] = { "byte_arrays", "utf8_strings", NULL };
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
PyObject *list;
|
|
Packit |
130fc8 |
DBusMessageIter iter;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#ifdef USING_DBG
|
|
Packit |
130fc8 |
fprintf(stderr, "DBG/%ld: called Message_get_args_list(self, *",
|
|
Packit |
130fc8 |
(long)getpid());
|
|
Packit |
130fc8 |
PyObject_Print(args, stderr, 0);
|
|
Packit |
130fc8 |
if (kwargs) {
|
|
Packit |
130fc8 |
fprintf(stderr, ", **");
|
|
Packit |
130fc8 |
PyObject_Print(kwargs, stderr, 0);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
fprintf(stderr, ")\n");
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (PyTuple_Size(args) != 0) {
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_TypeError, "get_args_list takes no positional "
|
|
Packit |
130fc8 |
"arguments");
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
#ifdef PY3
|
|
Packit |
130fc8 |
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:get_args_list",
|
|
Packit |
130fc8 |
argnames,
|
|
Packit |
130fc8 |
&(opts.byte_arrays))) return NULL;
|
|
Packit |
130fc8 |
#else
|
|
Packit |
130fc8 |
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:get_args_list",
|
|
Packit |
130fc8 |
argnames,
|
|
Packit |
130fc8 |
&(opts.byte_arrays),
|
|
Packit |
130fc8 |
&(opts.utf8_strings))) return NULL;
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
if (!self->msg) return DBusPy_RaiseUnusableMessage();
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
list = PyList_New(0);
|
|
Packit |
130fc8 |
if (!list) return NULL;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* Iterate over args, if any, appending to list */
|
|
Packit |
130fc8 |
if (dbus_message_iter_init(self->msg, &iter)) {
|
|
Packit |
130fc8 |
if (_message_iter_append_all_to_list(&iter, list, &opts) < 0) {
|
|
Packit |
130fc8 |
Py_CLEAR(list);
|
|
Packit |
130fc8 |
DBG_EXC("%s", "Message_get_args: appending all to list failed:");
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#ifdef USING_DBG
|
|
Packit |
130fc8 |
fprintf(stderr, "DBG/%ld: message has args list ", (long)getpid());
|
|
Packit |
130fc8 |
PyObject_Print(list, stderr, 0);
|
|
Packit |
130fc8 |
fprintf(stderr, "\n");
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
return list;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* vim:set ft=c cino< sw=4 sts=4 et: */
|