summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Peters <fpeters@entrouvert.com>2008-04-29 12:04:20 +0000
committerFrederic Peters <fpeters@entrouvert.com>2008-04-29 12:04:20 +0000
commit5d3228f77205dfb2a0e9f28f88f67602e2c37ee9 (patch)
tree7d458f025322e38ad5ad1daa9571388ef9499b4f
parent08ce85ccd01a5c7431e4e69d8db7ae26f9b935c4 (diff)
downloadlasso-5d3228f77205dfb2a0e9f28f88f67602e2c37ee9.tar.gz
lasso-5d3228f77205dfb2a0e9f28f88f67602e2c37ee9.tar.xz
lasso-5d3228f77205dfb2a0e9f28f88f67602e2c37ee9.zip
[project @ fpeters@0d.be-20071101170655-2qi60xpa42u7g310]
added (get) wrapper for GHashTable members Original author: Frederic Peters <fpeters@0d.be> Date: 2007-11-01 18:06:55.994000+01:00
-rw-r--r--bindings/lang_python.py59
-rw-r--r--bindings/lang_python_wrapper_top.c98
2 files changed, 156 insertions, 1 deletions
diff --git a/bindings/lang_python.py b/bindings/lang_python.py
index 5144bc5c..b97de2d8 100644
--- a/bindings/lang_python.py
+++ b/bindings/lang_python.py
@@ -30,7 +30,8 @@ class PythonBinding:
self.binding_data = binding_data
def is_pygobject(self, t):
- return t not in ['char*', 'const char*', 'gchar*', 'const gchar*', 'GList*',
+ return t not in ['char*', 'const char*', 'gchar*', 'const gchar*',
+ 'GList*', 'GHashTable*',
'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums
def generate(self):
@@ -60,6 +61,35 @@ def cptrToPy( cptr):
o = klass.__new__(klass)
o._cptr = cptr
return o
+
+class frozendict(dict):
+ \'\'\'Immutable dict\'\'\'
+ # from Python Cookbook:
+ # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/414283
+ def _blocked_attribute(obj):
+ raise AttributeError('A frozendict cannot be modified.')
+ _blocked_attribute = property(_blocked_attribute)
+
+ __delitem__ = __setitem__ = clear = _blocked_attribute
+ pop = popitem = setdefault = update = _blocked_attribute
+
+ def __new__(cls, *args):
+ new = dict.__new__(cls)
+ dict.__init__(new, *args)
+ return new
+
+ def __init__(self, *args):
+ pass
+
+ def __hash__(self):
+ try:
+ return self._cached_hash
+ except AttributeError:
+ h = self._cached_hash = hash(tuple(sorted(self.items())))
+ return h
+
+ def __repr__(self):
+ return 'frozendict(%s)' % dict.__repr__(self)
'''
def generate_exceptions(self, fd):
@@ -211,6 +241,17 @@ import lasso
klassname, mname)
print >> fd, ' if not l: return l'
print >> fd, ' return tuple([cptrToPy(x) for x in l])'
+ elif m[0] == 'GHashTable*':
+ print >> fd, ' d = _lasso.%s_%s_get(self._cptr)' % (
+ klassname, mname)
+ print >> fd, ' if not d: return d'
+ if options.get('elem_type') != 'char*':
+ print >> fd, ' d2 = {}'
+ print >> fd, ' for k, v in d.items():'
+ print >> fd, ' d2[k] = cptrToPy(v)'
+ print >> fd, ' return frozendict(d2)'
+ else:
+ print >> fd, ' return frozendict(d)'
else:
print >> fd, ' return _lasso.%s_%s_get(self._cptr)' % (
klassname, mname)
@@ -572,6 +613,22 @@ register_constants(PyObject *d)
print >> fd, '''\
return return_pyvalue;
}'''
+ elif vtype in ('GHashTable*',):
+ print >> fd, '''\
+ if (return_value == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ } else {'''
+ elem_type = options.get('elem_type')
+ if elem_type == 'char*':
+ print >> fd, '''\
+ return_pyvalue = get_dict_from_hashtable_of_strings(return_value);'''
+ else:
+ print >> fd, '''\
+ return_pyvalue = get_dict_from_hashtable_of_objects(return_value);'''
+ print >> fd, '''\
+ return return_pyvalue;
+ }'''
elif vtype == 'xmlNode*':
# convert xmlNode* to strings
print >> fd, ' if (return_value) {'
diff --git a/bindings/lang_python_wrapper_top.c b/bindings/lang_python_wrapper_top.c
index bcf670ec..1f70ecea 100644
--- a/bindings/lang_python_wrapper_top.c
+++ b/bindings/lang_python_wrapper_top.c
@@ -6,9 +6,107 @@ GQuark lasso_wrapper_key;
PyMODINIT_FUNC init_lasso(void);
static PyObject* get_pystring_from_xml_node(xmlNode *xmlnode);
+static PyObject* get_dict_from_hashtable_of_strings(GHashTable *value);
+static PyObject* get_dict_from_hashtable_of_objects(GHashTable *value);
+static PyObject* PyGObjectPtr_New(GObject *obj);
/* utility functions */
+#if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14)
+ /* copy of private struct and g_hash_table_get_keys from GLib internals
+ * (as this function is useful but new in 2.14) */
+
+typedef struct _GHashNode GHashNode;
+
+struct _GHashNode
+{
+ gpointer key;
+ gpointer value;
+ GHashNode *next;
+ guint key_hash;
+};
+
+struct _GHashTable
+{
+ gint size;
+ gint nnodes;
+ GHashNode **nodes;
+ GHashFunc hash_func;
+ GEqualFunc key_equal_func;
+ volatile gint ref_count;
+ GDestroyNotify key_destroy_func;
+ GDestroyNotify value_destroy_func;
+};
+
+GList *
+g_hash_table_get_keys (GHashTable *hash_table)
+{
+ GHashNode *node;
+ gint i;
+ GList *retval;
+
+ g_return_val_if_fail (hash_table != NULL, NULL);
+
+ retval = NULL;
+ for (i = 0; i < hash_table->size; i++)
+ for (node = hash_table->nodes[i]; node; node = node->next)
+ retval = g_list_prepend (retval, node->key);
+
+ return retval;
+}
+
+#endif
+
+static PyObject*
+get_dict_from_hashtable_of_strings(GHashTable *value)
+{
+ GList *keys;
+ PyObject *dict;
+ char *item_value;
+ PyObject *item;
+
+ dict = PyDict_New();
+
+ keys = g_hash_table_get_keys(value);
+ for (; keys; keys = g_list_next(keys)) {
+ item_value = g_hash_table_lookup(value, keys->data);
+ if (item_value) {
+ item = PyString_FromString(item_value);
+ PyDict_SetItemString(dict, (char*)keys->data, item);
+ } else {
+ PyDict_SetItemString(dict, (char*)keys->data, Py_None);
+ }
+ }
+ g_list_free(keys);
+
+ return PyDictProxy_New(dict);
+}
+
+static PyObject*
+get_dict_from_hashtable_of_objects(GHashTable *value)
+{
+ GList *keys;
+ PyObject *dict;
+ char *item_value;
+ PyObject *item;
+
+ dict = PyDict_New();
+
+ keys = g_hash_table_get_keys(value);
+ for (; keys; keys = g_list_next(keys)) {
+ item_value = g_hash_table_lookup(value, keys->data);
+ if (item_value) {
+ item = PyGObjectPtr_New(G_OBJECT(item_value));
+ PyDict_SetItemString(dict, (char*)keys->data, item);
+ } else {
+ PyDict_SetItemString(dict, (char*)keys->data, Py_None);
+ }
+ }
+ g_list_free(keys);
+
+ return PyDictProxy_New(dict);
+}
+
static PyObject*
get_pystring_from_xml_node(xmlNode *xmlnode)
{