diff options
-rw-r--r-- | portato/eix/__init__.py | 0 | ||||
-rw-r--r-- | portato/eix/eix_utils.pxd | 47 | ||||
-rw-r--r-- | portato/eix/eix_utils.pyx | 72 | ||||
-rw-r--r-- | portato/eix/libeix.pyx | 14 |
4 files changed, 133 insertions, 0 deletions
diff --git a/portato/eix/__init__.py b/portato/eix/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/portato/eix/__init__.py diff --git a/portato/eix/eix_utils.pxd b/portato/eix/eix_utils.pxd new file mode 100644 index 0000000..a85a65e --- /dev/null +++ b/portato/eix/eix_utils.pxd @@ -0,0 +1,47 @@ +cdef extern from *: + ctypedef int size_t + +cdef extern from "errno.h": + int errno + +cdef extern from "string.h": + char* strerror (int errno) + size_t strlen (char* s) + char* strcpy (char* dest, char* src) + +cdef extern from "stdio.h": + + ctypedef struct FILE: + pass + + FILE* c_fopen "fopen" (char* path, char* mode) + int c_fclose "fclose" (FILE* f) + int c_feof "feof" (FILE* f) + int fread (void* buf, size_t size, size_t n, FILE* f) + + enum WHENCE: + SEEK_SET + SEEK_CUR + SEEK_END + + int fseek (FILE* stream, long offset, WHENCE whence) + +cdef extern from "Python.h": + ctypedef struct PyObject: + pass + + void* PyMem_Malloc (size_t n) + void PyMem_Free (void* p) + +cdef: + struct File: + FILE* file + char* name + + File* fopen (char* path, char* mode) except NULL + void fclose (File* f) + + void ffree (void* p) + char* fget (File* f, size_t n) except NULL + + char* strdup (char* other) except NULL diff --git a/portato/eix/eix_utils.pyx b/portato/eix/eix_utils.pyx new file mode 100644 index 0000000..57fa5d7 --- /dev/null +++ b/portato/eix/eix_utils.pyx @@ -0,0 +1,72 @@ +class EndOfFileError (IOError): + + def __init__ (self, filename = None): + self.message = "End of file reached while not expecting it" + self.filename = filename + + def __str__ (self): + if self.filename is not None: + return "%s: %s" % (self.message, self.filename) + else: + return self.message + +cdef char* strdup (char * other) except NULL: + cdef size_t len + cdef char* new + + if other is NULL: + return NULL + + len = strlen(other) + new = <char*>PyMem_Malloc(len+1) + + if new is NULL: + raise MemoryError, "Malloc of new string copy" + return NULL + + return strcpy(new, other) + + +cdef File* fopen (char* path, char* mode) except NULL: + cdef File* f + + f = <File*> PyMem_Malloc(sizeof(File)) + + if f is NULL: + raise MemoryError, "Malloc of File" + return NULL + + f.file = c_fopen(path, mode) + + if f.file is NULL: + raise IOError, (errno, strerror(errno), path) + return NULL + + f.name = strdup(path) + + if f.name is NULL: + return NULL + + return f + +cdef void fclose (File* f): + c_fclose(f.file) + ffree(f.name) + PyMem_Free(f) + +cdef void ffree (void* p): + PyMem_Free(p) + +cdef char* fget (File* f, size_t n) except NULL: + cdef char* buf + buf = <char*> PyMem_Malloc(n) + + if buf is NULL: + raise MemoryError, "Malloc" + return NULL + + if (fread(buf, 1, n, f.file) != n): + PyMem_Free(buf) + raise EndOfFileError, f.name + + return buf diff --git a/portato/eix/libeix.pyx b/portato/eix/libeix.pyx new file mode 100644 index 0000000..2b3ebb0 --- /dev/null +++ b/portato/eix/libeix.pyx @@ -0,0 +1,14 @@ +from portato.eix.eix_utils cimport File, fopen, fclose, ffree, fget + +def test (f): + cdef File* cf + cdef char* buf + + print "Trying to open: ", f + cf = fopen(f, "r") + try: + buf = fget(cf, 20) + print "The first two chars:", buf[0], buf[1] + ffree(buf) + finally: + fclose(cf) |