aboutsummaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorRob Taylor <rob.taylor@codethink.co.uk>2009-02-03 21:28:02 +0000
committerRob Taylor <rob.taylor@codethink.co.uk>2009-02-03 21:28:02 +0000
commitc7cb2cd35bf772c7ab8ba8ceea350aad8bd9cc8f (patch)
treeb05f009bf2d319fc2b0219cba24cf9d3d42d35ea /python
parent21b7342a347dc9d7c1b44cca4c259f0e38ce11e4 (diff)
Start of ctypes-based python bindings for libcontextprovider.
Diffstat (limited to 'python')
-rw-r--r--python/CTypesHelpers.py65
-rw-r--r--python/ContextProvider.py40
2 files changed, 105 insertions, 0 deletions
diff --git a/python/CTypesHelpers.py b/python/CTypesHelpers.py
new file mode 100644
index 00000000..bada4e0d
--- /dev/null
+++ b/python/CTypesHelpers.py
@@ -0,0 +1,65 @@
+# From http://wwwx.cs.unc.edu/~gb/wp/blog/2007/02/11/ctypes-tricks/
+
+from ctypes import *
+
+def cfunc(name, dll, result, *args):
+ '''build and apply a ctypes prototype complete with parameter flags'''
+ atypes = []
+ aflags = []
+ for arg in args:
+ atypes.append(arg[1])
+ aflags.append((arg[2], arg[0]) + arg[3:])
+ return CFUNCTYPE(result, *atypes)((name, dll), tuple(aflags))
+
+class ListPOINTER(object):
+ '''Just like a POINTER but accept a list of ctype as an argument'''
+ def __init__(self, etype):
+ self.etype = etype
+
+ def from_param(self, param):
+ if isinstance(param, (list,tuple)):
+ return (self.etype * len(param))(*param)
+
+class ListPOINTER2(object):
+ '''Just like POINTER(POINTER(ctype)) but accept a list of lists of ctype'''
+ def __init__(self, etype):
+ self.etype = etype
+
+ def from_param(self, param):
+ if isinstance(param, (list,tuple)):
+ val = (POINTER(self.etype) * len(param))()
+ for i,v in enumerate(param):
+ if isinstance(v, (list,tuple)):
+ val[i] = (self.etype * len(v))(*v)
+ else:
+ raise TypeError, 'nested list or tuple required at %d' % i
+ return val
+ else:
+ raise TypeError, 'list or tuple required'
+
+
+class ByRefArg(object):
+ '''Just like a POINTER but accept an argument and pass it byref'''
+ def __init__(self, atype):
+ self.atype = atype
+
+ def from_param(self, param):
+ return byref(self.atype(param))
+
+# hack the ctypes.Structure class to include printing the fields
+class _Structure(Structure):
+ def __repr__(self):
+ '''Print the fields'''
+ res = []
+ for field in self._fields_:
+ res.append('%s=%s' % (field[0], repr(getattr(self, field[0]))))
+ return self.__class__.__name__ + '(' + ','.join(res) + ')'
+ @classmethod
+ def from_param(cls, obj):
+ '''Magically construct from a tuple'''
+ if isinstance(obj, cls):
+ return obj
+ if isinstance(obj, tuple):
+ return cls(*obj)
+ raise TypeError
+
diff --git a/python/ContextProvider.py b/python/ContextProvider.py
new file mode 100644
index 00000000..4048fc16
--- /dev/null
+++ b/python/ContextProvider.py
@@ -0,0 +1,40 @@
+from ctypes import *
+from CTypesHelpers import *
+
+
+class STRING_SET(c_void_p):
+ pass
+
+class CHANGE_SET(c_void_p):
+ pass
+
+class ContextProvider:
+ def __init__(self):
+ self.define_types()
+ self.define_functions()
+
+ def define_types(self):
+ self.dll = CDLL("libcontextprovider.so")
+ self.STRING_ARRAY = POINTER(c_char_p)
+ self.GET_CALLBACK = CFUNCTYPE(STRING_SET, CHANGE_SET, c_void_p)
+ self.SUBSCRIBE_CALLBACK = CFUNCTYPE(STRING_SET, c_void_p)
+
+ def define_functions(self):
+ self.init = cfunc('context_provider_init', self.dll, None,
+ ('provided_keys', ListPOINTER (c_char_p), 1),
+ ('useSessionBus', c_int, 1),
+ ('get_cb', self.GET_CALLBACK, 1),
+ ('get_cb_target', c_void_p, 1),
+ ('first_cb', self.SUBSCRIBE_CALLBACK, 1),
+ ('first_cb_target', c_void_p, 1),
+ ('last_cb', self.SUBSCRIBE_CALLBACK, 1),
+ ('last_cb_target', c_void_p, 1))
+ self.no_of_subscribers = cfunc('context_provider_no_of_subscribers', self.dll, c_int,
+ ('key', c_char_p, 1))
+
+ self.change_set_create = ('context_provider_change_set_create', self.dll, CHANGE_SET,
+ None);
+
+
+if __name__ == "__main__":
+ cp = ContextProvider()