aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcoopgamma.py98
-rw-r--r--src/libcoopgamma_native.pyx.gpp261
2 files changed, 343 insertions, 16 deletions
diff --git a/src/libcoopgamma.py b/src/libcoopgamma.py
index 16441d5..31f5aaa 100644
--- a/src/libcoopgamma.py
+++ b/src/libcoopgamma.py
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
'''
-import enum
+import enum, libcoopgamma_native
class Support(enum.IntEnum):
@@ -542,18 +542,45 @@ class Context:
@variable fd:int File descriptor for the socket
'''
- def __init__(self):
+ def __init__(self, fd : int = -1, buf : bytes = None):
'''
Constructor
+
+ @param fd:int File descriptor for the socket
+ @param buf:bytes? Buffer to unmarshal
'''
- self.fd = None
- self.address = None
+ self.fd = fd
+ if buf is None:
+ (successful, value) = libcoopgamma_native.libcoopgamma_native_context_create()
+ if not successful:
+ pass # TODO
+ else:
+ (error, value) = libcoopgamma_native.libcoopgamma_native_context_unmarshal(buf)
+ if error < 0:
+ pass # TODO
+ elif error == 1:
+ pass # TODO LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE
+ elif error == 2:
+ pass # TODO LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE
+ self.address = value
def __del__(self):
'''
Destructor
'''
- pass
+ libcoopgamma_native.libcoopgamma_native_context_free(self.address)
+
+ def __repr__(self) -> str:
+ '''
+ Create a parsable string representation of the instance
+
+ @return :str Parsable representation of the instance
+ '''
+ data = libcoopgamma_libcoopgamma_native_context_marshal(self.address)
+ if isinstance(data, int):
+ pass # TODO
+ params = (self.fd, data)
+ return 'libcoopgamma.Context(%s)' % ', '.join(repr(p) for p in params)
def connect(self, method, site : str):
'''
@@ -578,13 +605,13 @@ class Context:
closed and the when the instance is destroyed the
connection will remain
'''
- pass
+ libcoopgamma_native.libcoopgamma_native_context_set_fd(self.address, -1)
def attach(self):
'''
Undoes the action of `detach`
'''
- pass
+ libcoopgamma_native.libcoopgamma_native_context_set_fd(self.address, self.fd)
def set_nonbreaking(self, nonbreaking : bool):
'''
@@ -770,17 +797,42 @@ class AsyncContext:
'''
Information necessary to identify and parse a response from the server
'''
- def __init__(self):
+ def __init__(self, buf : bytes = None):
'''
Constructor
+
+ @param buf:bytes? Buffer to unmarshal
'''
- self.address = None
+ if buf is None:
+ (successful, value) = libcoopgamma_native.libcoopgamma_native_async_context_create()
+ if not successful:
+ pass # TODO
+ else:
+ (error, value) = libcoopgamma_native.libcoopgamma_native_async_context_unmarshal(buf)
+ if error < 0:
+ pass # TODO
+ elif error == 1:
+ pass # TODO LIBCOOPGAMMA_INCOMPATIBLE_DOWNGRADE
+ elif error == 2:
+ pass # TODO LIBCOOPGAMMA_INCOMPATIBLE_UPGRADE
+ self.address = value
def __del__(self):
'''
Destructor
'''
- pass
+ libcoopgamma_native.libcoopgamma_native_async_context_free(self.address)
+
+ def __repr__(self) -> str:
+ '''
+ Create a parsable string representation of the instance
+
+ @return :str Parsable representation of the instance
+ '''
+ data = libcoopgamma_libcoopgamma_native_async_context_marshal(self.address)
+ if isinstance(data, int):
+ pass # TODO
+ return 'libcoopgamma.AsyncContext(%s)' % repr(data)
def get_methods() -> list:
@@ -792,7 +844,10 @@ def get_methods() -> list:
@return :list<str> A list of names. You should only free the outer pointer, inner
pointers are subpointers of the outer pointer and cannot be freed.
'''
- pass
+ ret = libcoopgamma_native.libcoopgamma_native_get_methods()
+ if isinstance(ret, int):
+ pass # TODO
+ return ret
def get_method_and_site(method, site : str) -> tuple:
@@ -809,7 +864,12 @@ def get_method_and_site(method, site : str) -> tuple:
selected automatically, the selected site (the second
element in the returned tuple) will be `None`.
'''
- pass
+ if method is not None:
+ method = str(method)
+ ret = libcoopgamma_native.libcoopgamma_native_get_method_and_site(method, site)
+ if isinstance(ret, int):
+ pass # TODO
+ return ret
def get_pid_file(method, site : str) -> str:
@@ -823,7 +883,12 @@ def get_pid_file(method, site : str) -> str:
@return :str? The pathname of the server's PID file.
`None` if the server does not use PID files.
'''
- pass
+ if method is not None:
+ method = str(method)
+ ret = libcoopgamma_native.libcoopgamma_native_get_pid_file(method, site)
+ if ret is not None and isinstance(ret, int):
+ pass # TODO
+ return ret
def get_socket_file(method, site : str) -> str:
@@ -838,5 +903,10 @@ def get_socket_file(method, site : str) -> str:
its own socket, which is the case when communicating with a server
in a multi-server display server like mds
'''
- pass
+ if method is not None:
+ method = str(method)
+ ret = libcoopgamma_native.libcoopgamma_native_get_pid_file(method, site)
+ if ret is not None and isinstance(ret, int):
+ pass # TODO
+ return ret
diff --git a/src/libcoopgamma_native.pyx.gpp b/src/libcoopgamma_native.pyx.gpp
index bb835ec..73d8353 100644
--- a/src/libcoopgamma_native.pyx.gpp
+++ b/src/libcoopgamma_native.pyx.gpp
@@ -246,7 +246,7 @@ $$>
-cdef extern int libcoopgamma_ramps_initialise_(void* this, size_t width)
+cdef extern int libcoopgamma_ramps_initialise_(libcoopgamma_ramps_t* this, size_t width)
'''
Initialise a `libcoopgamma_ramps_t`
@@ -257,7 +257,7 @@ Initialise a `libcoopgamma_ramps_t`
@return Zero on success, -1 on error
'''
-cdef extern void libcoopgamma_ramps_destroy(void* this)
+cdef extern void libcoopgamma_ramps_destroy(libcoopgamma_ramps_t* this)
'''
Release all resources allocated to a `libcoopgamma_ramps_t`,
the allocation of the record itself is not freed
@@ -786,3 +786,260 @@ operation without disconnection from the server
(rather than `errno`) is read for information about the error
'''
+
+
+def libcoopgamma_native_get_methods():
+ '''
+ List all recognised adjustment method
+
+ SIGCHLD must not be ignored or blocked
+
+ @return :list<str>|int Either the value of `errno` (on failure), or (on success) a list
+ of names. You should only free the outer pointer, inner pointers
+ are subpointers of the outer pointer and cannot be freed.
+ '''
+ cdef char** methods = libcoopgamma_get_methods()
+ cdef bytes bs
+ if methods is NULL:
+ return int(errno)
+ ret = []
+ i = 0
+ while methods[i] is not NULL:
+ bs = methods[i]
+ ret.append(bs.decode('utf-8', 'strict'))
+ free(methods)
+
+
+def libcoopgamma_native_get_method_and_site(method : str, site : str):
+ '''
+ Get the adjustment method and site
+
+ SIGCHLD must not be ignored or blocked
+
+ @param method:str? The adjustment method, `None` for automatic
+ @param site:str? The site, `None` for automatic
+ @return :int|(:str, :str?) Either the value of `errno` (on failure), or (on success)
+ the selected adjustment method and the selected the
+ selected site. If the adjustment method only supports
+ one site or if `site` is `None` and no site can be
+ selected automatically, the selected site (the second
+ element in the returned tuple) will be `None`.
+ '''
+ cdef char* rcsmethod = NULL
+ cdef char* rcssite = NULL
+ cdef bytes rbsmethod
+ cdef bytes rbssite
+ rmethod, rsite = None, None
+ if libcoopgamma_get_method_and_site(method, site, &rbsmethod, &rbssite) < 0:
+ return int(errno)
+ rbsmethod = rcsmethod
+ rmethod = rbsmethod.decode('utf-8', 'strict')
+ if rcssite is not None:
+ rbssite = rcssite
+ rsite = rbssite.decode('utf-8', 'strict')
+ return (rmethod, rsite)
+
+
+def libcoopgamma_native_get_pid_file(method : str, site : str):
+ '''
+ Get the PID file of the coopgamma server
+
+ SIGCHLD must not be ignored or blocked
+
+ @param method:str? The adjustment method, `None` for automatic
+ @param site:str? The site, `None` for automatic
+ @return :int|str? Either the value of `errno` (on failure), or (on success)
+ the pathname of the server's PID file. `None` if the server
+ does not use PID files.
+ '''
+ cdef char* path
+ char bytes bs
+ path = libcoopgamma_native_get_pid_file(method, site)
+ if errno != 0 and path is NULL:
+ bs = path
+ return bs.decode('utf-8', 'strict')
+ return int(errno)
+
+
+def libcoopgamma_native_get_socket_file(method : str, site : str):
+ '''
+ Get the socket file of the coopgamma server
+
+ SIGCHLD must not be ignored or blocked
+
+ @param method:int|str? The adjustment method, `None` for automatic
+ @param site:str? The site, `None` for automatic
+ @return :int|str? Either the value of `errno` (on failure), or (on success)
+ the pathname of the server's socket, `None` if the server does have
+ its own socket, which is the case when communicating with a server
+ in a multi-server display server like mds
+ '''
+ cdef char* path
+ char bytes bs
+ path = libcoopgamma_native_get_socket_file(method, site)
+ if errno != 0 and path is NULL:
+ bs = path
+ return bs.decode('utf-8', 'strict')
+ return int(errno)
+
+
+def libcoopgamma_native_context_create():
+ '''
+ Create an instance of `libcoopgamma_context_t`
+
+ @return :(:bool, :int) Element 0: Whether the call was successful
+ Element 1: The value of `errno` on failure, and on
+ success, the address of the created instance
+ '''
+ cdef libcoopgamma_context_t* this
+ this = <libcoopgamma_context_t*>malloc(sizeof(*this))
+ if this is None:
+ return (False, int(errno))
+ if libcoopgamma_context_initialise(this) < 0:
+ saved_errno = int(errno)
+ libcoopgamma_context_destroy(this, <int>0)
+ free(this)
+ return (False, saved_errno)
+ return (True, int(<intptr_t><void*>this))
+
+
+def libcoopgamma_native_context_free(address : int):
+ '''
+ Disconnect and free an instance of a `libcoopgamma_context_t`
+
+ @param address:int The address of the `libcoopgamma_context_t` instance
+ '''
+ cdef libcoopgamma_context_t* this = <libcoopgamma_context_t*><void*><intptr_t>address
+ libcoopgamma_context_destroy(this, <int>1)
+ free(this)
+
+
+def libcoopgamma_native_context_marshal(address : int):
+ '''
+ Marshal a `libcoopgamma_context_t` into a buffer
+
+ @param address:int The address of the instance to marshal
+ @return :int|bytes Either the value of `errno` (on failure), or (on success)
+ a byte representation of the instance
+ '''
+ cdef libcoopgamma_context_t* this = <libcoopgamma_context_t*><void*><intptr_t>address
+ cdef size_t n = libcoopgamma_context_marshal(this, NULL)
+ cdef char* buf = <char*>malloc(n)
+ if buf is NULL:
+ return int(errno)
+ libcoopgamma_context_marshal(this, buf)
+ ret = bytes(<int>(char[i]) for i in range(int(n)))
+ free(buf)
+ return ret
+
+
+def libcoopgamma_native_context_unmarshal(buf : bytes):
+ '''
+ Unmarshal a `libcoopgamma_context_t` from a buffer
+
+ @param buf:bytes The buffer with the marshalled instance
+ @return :(:int, :int) Element 0: 0 = Success
+ 1 = Incompatible downgrade
+ 2 = Incompatible upgrade
+ -1 = `errno` is returned
+ Element 1: If [0] = 0: The address of the unmarshalled instance
+ If [0] = -1: The value of `errno`
+ '''
+ cdef size_t ret1 = 0
+ cdef libcoopgamma_context_t* this
+ this = <libcoopgamma_context_t*>malloc(sizeof(*this))
+ if this is None:
+ return (-1, int(errno))
+ if libcoopgamma_context_initialise(this) < 0:
+ saved_errno = int(errno)
+ libcoopgamma_context_destroy(this)
+ return (-1, int(errno))
+ ret0 = <int>libcoopgamma_context_unmarshal(this, <bytes>buf, &ret1)
+ return (ret0, <int>ret1)
+
+
+def libcoopgamma_native_context_set_fd(address : int, fd : int):
+ '''
+ Set the field for socket file descriptor in a `libcoopgamma_context_t`
+
+ @param address:int The address of the `libcoopgamma_context_t` instance
+ @param fd:int The file descriptor
+ '''
+ cdef libcoopgamma_context_t* this = <libcoopgamma_context_t*><void*><intptr_t>address
+ this->fd = fd
+
+
+def libcoopgamma_native_context_create():
+ '''
+ Create an instance of `libcoopgamma_context_t`
+
+ @return :(:bool, :int) Element 0: Whether the call was successful
+ Element 1: The value of `errno` on failure, and on
+ success, the address of the created instance
+ '''
+ cdef libcoopgamma_context_t* this
+ this = <libcoopgamma_context_t*>malloc(sizeof(*this))
+ if this is None:
+ return (False, int(errno))
+ if libcoopgamma_context_initialise(this) < 0:
+ saved_errno = int(errno)
+ libcoopgamma_context_destroy(this, <int>0)
+ free(this)
+ return (False, saved_errno)
+ return (True, int(<intptr_t><void*>this))
+
+
+def libcoopgamma_native_async_context_free(address : int):
+ '''
+ Free an instance of a `libcoopgamma_async_context_t`
+
+ @param address:int The address of the `libcoopgamma_async_context_t` instance
+ '''
+ cdef libcoopgamma_async_context_t* this = <libcoopgamma_async_context_t*><void*><intptr_t>address
+ libcoopgamma_async_context_destroy(this)
+ free(this)
+
+
+def libcoopgamma_native_async_context_marshal(address : int):
+ '''
+ Marshal a `libcoopgamma_async_context_t` into a buffer
+
+ @param address:int The address of the instance to marshal
+ @return :int|bytes Either the value of `errno` (on failure), or (on success)
+ a byte representation of the instance
+ '''
+ cdef libcoopgamma_async_context_t* this = <libcoopgamma_async_context_t*><void*><intptr_t>address
+ cdef size_t n = libcoopgamma_async_context_marshal(this, NULL)
+ cdef char* buf = <char*>malloc(n)
+ if buf is NULL:
+ return int(errno)
+ libcoopgamma_async_context_marshal(this, buf)
+ ret = bytes(<int>(char[i]) for i in range(int(n)))
+ free(buf)
+ return ret
+
+
+def libcoopgamma_native_async_context_unmarshal(buf : bytes):
+ '''
+ Unmarshal a `libcoopgamma_async_context_t` from a buffer
+
+ @param buf:bytes The buffer with the marshalled instance
+ @return :(:int, :int) Element 0: 0 = Success
+ 1 = Incompatible downgrade
+ 2 = Incompatible upgrade
+ -1 = `errno` is returned
+ Element 1: If [0] = 0: The address of the unmarshalled instance
+ If [0] = -1: The value of `errno`
+ '''
+ cdef size_t ret1 = 0
+ cdef libcoopgamma_async_context_t* this
+ this = <libcoopgamma_async_context_t*>malloc(sizeof(*this))
+ if this is None:
+ return (-1, int(errno))
+ if libcoopgamma_async_context_initialise(this) < 0:
+ saved_errno = int(errno)
+ libcoopgamma_async_context_destroy(this)
+ return (-1, int(errno))
+ ret0 = <int>libcoopgamma_async_context_unmarshal(this, <bytes>buf, &ret1)
+ return (ret0, <int>ret1)
+