diff options
Diffstat (limited to 'src/native_bus.pyx')
-rw-r--r-- | src/native_bus.pyx | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/native_bus.pyx b/src/native_bus.pyx new file mode 100644 index 0000000..016fa3c --- /dev/null +++ b/src/native_bus.pyx @@ -0,0 +1,221 @@ +# -*- python -*- +''' +MIT/X Consortium License + +Copyright © 2015 Mattias Andrée <maandree@member.fsf.org> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +''' + +cimport cython + +from libc.stdlib cimport malloc, free + + +cdef extern int bus_create(const char *, int, char **) +''' +Create a new bus + +@param file The pathname of the bus, `NULL` to create a random one +@param flags `BUS_EXCL` (if `file` is not `NULL`) to fail if the file + already exists, otherwise if the file exists, nothing + will happen; + `BUS_INTR` to fail if interrupted +@param out_file Output parameter for the pathname of the bus +@return 0 on success, -1 on error +''' + +cdef extern int bus_unlink(const char *) +''' +Remove a bus + +@param file The pathname of the bus +@return 0 on success, -1 on error +''' + +cdef extern int bus_open(long, const char *, int) +''' +Open an existing bus + +@param bus Bus information to fill +@param file The filename of the bus +@param flags `BUS_RDONLY`, `BUS_WRONLY` or `BUS_RDWR`, + the value must not be negative +@return 0 on success, -1 on error +''' + +cdef extern int bus_close(long) +''' +Close a bus + +@param bus Bus information +@return 0 on success, -1 on error +''' + +cdef extern int bus_write(long, const char *) +''' +Broadcast a message a bus + +@param bus Bus information +@param message The message to write, may not be longer than + `BUS_MEMORY_SIZE` including the NUL-termination +@return 0 on success, -1 on error +''' + +cdef extern int bus_read(long, int (*)(const char *, void *), void *) +''' +Listen (in a loop, forever) for new message on a bus + +@param bus Bus information +@param callback Function to call when a message is received, the + input parameters will be the read message and + `user_data` from `bus_read`'s parameter with the + same name. The message must have been parsed or + copied when `callback` returns as it may be over + overridden after that time. `callback` should + return either of the the values: + 0: stop listening + 1: continue listening + -1: an error has occurred +@return 0 on success, -1 on error +''' + + +def bus_allocate() -> int: + ''' + Allocate memory for a bus + + @return The address of the allocated memory + ''' + n = 2 * sizeof(long long) + sizeof(int) + sizeof(char *) + return <long>malloc(n) + + +def bus_deallocate(address : int): + ''' + Deallocate memory for a bus + + @param address The address of the allocated memory + ''' + free(<void *><long>address) + + +def bus_create_wrapped(file : str, flags : int) -> str: + ''' + Create a new bus + + @param file The pathname of the bus, `None` to create a random one + @param flags `BUS_EXCL` (if `file` is not `None`) to fail if the file + already exists, otherwise if the file exists, nothing + will happen; + `BUS_INTR` to fail if interrupted + @return The pathname of the bus, `None` on error; + `file` is returned unless `file` is `None` + ''' + cdef const char* cfile + cdef char* ofile + cdef bytes bs + if file is not None: + bs = file.encode('utf-8') + bytes([0]) + cfile = bs + r = bus_create(cfile, flags, <char **>NULL) + return file if r == 0 else None + r = bus_create(<char *>NULL, flags, &ofile) + if r == 0: + bs = ofile + return bs.encode('utf-8', 'strict') + return None + + +def bus_unlink_wrapped(file : str) -> int: + ''' + Remove a bus + + @param file The pathname of the bus + @return 0 on success, -1 on error + ''' + cdef const char* cfile + cdef bytes bs + bs = file.encode('utf-8') + bytes([0]) + cfile = bs + return bus_unlink(cfile) + + +def bus_open_wrapped(bus : int, file : str, flags : int) -> int: + ''' + Open an existing bus + + @param bus Bus information to fill + @param file The filename of the bus + @param flags `BUS_RDONLY`, `BUS_WRONLY` or `BUS_RDWR`, + the value must not be negative + @return 0 on success, -1 on error + ''' + cdef const char* cfile + cdef bytes bs + bs = file.encode('utf-8') + bytes([0]) + cfile = bs + return bus_open(<long>bus, cfile, <int>flags) + + +def bus_close_wrapped(bus : int) -> int: + ''' + Close a bus + + @param bus Bus information + @return 0 on success, -1 on error + ''' + return bus_close(<long>bus) + + +def bus_write_wrapped(bus : int, message : str) -> int: + ''' + Broadcast a message a bus + + @param bus Bus information + @param message The message to write, may not be longer than + `BUS_MEMORY_SIZE` including the NUL-termination + @return 0 on success, -1 on error + ''' + cdef const char* cmessage + cdef bytes bs + bs = message.encode('utf-8') + bytes([0]) + cmessage = bs + return bus_write(<long>bus, cmessage) + + +def bus_read_wrapped(bus : int, callback : callable, user_data) -> int: + ''' + Listen (in a loop, forever) for new message on a bus + + @param bus Bus information + @param callback Function to call when a message is received, the + input parameters will be the read message and + `user_data` from `bus_read`'s parameter with the + same name. The message must have been parsed or + copied when `callback` returns as it may be over + overridden after that time. `callback` should + return either of the the values: + 0: stop listening + 1: continue listening + -1: an error has occurred + @return 0 on success, -1 on error + ''' + return bus_read(<long>bus, <int (*)(const char *, void *)><void *>callback, <void *>user_data) + |