summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--portato/eix/__init__.py0
-rw-r--r--portato/eix/eix_utils.pxd47
-rw-r--r--portato/eix/eix_utils.pyx72
-rw-r--r--portato/eix/libeix.pyx14
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)