summaryrefslogtreecommitdiff
path: root/portato
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.net>2010-04-14 22:17:53 +0200
committerRené 'Necoro' Neumann <necoro@necoro.net>2010-04-14 22:17:53 +0200
commit208c4adfbdf7b82cc40da873ed185f3e29880cfa (patch)
tree6c374e4c7e7480496602e38a275bd42d70aa4fe7 /portato
parent0f19f73c55ea8c8188aec7426ea94bfb7a823720 (diff)
downloadportato-208c4adfbdf7b82cc40da873ed185f3e29880cfa.tar.gz
portato-208c4adfbdf7b82cc40da873ed185f3e29880cfa.tar.bz2
portato-208c4adfbdf7b82cc40da873ed185f3e29880cfa.zip
Improve the C modules
Diffstat (limited to 'portato')
-rw-r--r--portato/eix/parser.pyx50
-rw-r--r--portato/ipc.pxd3
-rw-r--r--portato/ipc.pyx36
3 files changed, 52 insertions, 37 deletions
diff --git a/portato/eix/parser.pyx b/portato/eix/parser.pyx
index 4315191..a6bcc96 100644
--- a/portato/eix/parser.pyx
+++ b/portato/eix/parser.pyx
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# File: portato/eix/_parser.pyx
+# File: portato/eix/parser.pyx
# This file is part of the Portato-Project, a graphical portage-frontend.
#
# Copyright (C) 2006-2010 René 'Necoro' Neumann
@@ -20,12 +20,12 @@ For the exact way all the functions work, have a look at the eix format descript
__docformat__ = "restructuredtext"
cdef extern from "stdio.h":
- ctypedef struct FILE:
- pass
+ ctypedef struct FILE
int fgetc(FILE* stream)
long ftell(FILE* stream)
int fseek(FILE* stream, long offset, int whence)
+ int fread(void* ptr, int size, int n, FILE* stream)
int EOF
int SEEK_CUR
@@ -33,11 +33,14 @@ cdef extern from "stdio.h":
cdef extern from "Python.h":
FILE* PyFile_AsFile(object)
-cimport python_unicode
-
ctypedef unsigned char UChar
ctypedef long long LLong
+from python_unicode cimport PyUnicode_DecodeUTF8
+from python_mem cimport PyMem_Malloc, PyMem_Free
+from python_exc cimport PyErr_NoMemory
+from python_string cimport PyString_FromStringAndSize
+
from portato.eix.exceptions import EndOfFileException
#
@@ -123,25 +126,38 @@ cpdef object vector (object file, object get_type, object nelems = None):
return [get_type(file) for i in range(n)]
-cpdef object string (object file, char u = 0):
+cpdef object string (object pfile, bint unicode = False):
"""
Returns a string.
- :param file: The file to read from
- :type file: file
- :rtype: str
+ :param pfile: The file to read from
+ :type pfile: file
+ :param unicode: Return unicode
+ :type unicode: bool
+ :rtype: str or unicode
"""
- cdef LLong nelems = number(file)
+ cdef LLong nelems = number(pfile)
+ cdef FILE* file = PyFile_AsFile(pfile)
+ cdef char* s
+
+ s = <char*>PyMem_Malloc((nelems + 1) * sizeof(char))
+
+ if s is NULL:
+ PyErr_NoMemory()
- s = file.read(nelems)
+ try:
+ if fread(s, sizeof(char), nelems, file) < nelems:
+ raise EndOfFileException, pfile.name
- if len(s) != nelems:
- raise EndOfFileException, file.name
+ s[nelems] = '\0'
- if u:
- return python_unicode.PyUnicode_DecodeUTF8(s, nelems, 'replace')
+ if unicode:
+ return PyUnicode_DecodeUTF8(s, nelems, 'replace')
+ else: # simple string, implicitly copied
+ return PyString_FromStringAndSize(s, nelems)
- return s
+ finally:
+ PyMem_Free(s)
#
# Complex Types
@@ -281,7 +297,7 @@ cdef class package:
after_offset = ftell(cfile)
self.name = string(file)
- self.description = string(file,1)
+ self.description = string(file, True)
# skip the rest, as it is currently unneeded
#self.provide = vector(file, number)
diff --git a/portato/ipc.pxd b/portato/ipc.pxd
index 38e6d30..5bcddd1 100644
--- a/portato/ipc.pxd
+++ b/portato/ipc.pxd
@@ -11,7 +11,8 @@
# Written by René 'Necoro' Neumann <necoro@necoro.net>
from python_string cimport *
-from python_mem cimport *
+from python_mem cimport PyMem_Malloc, PyMem_Free
+from python_exc cimport PyErr_NoMemory
cdef extern from "errno.h":
int errno
diff --git a/portato/ipc.pyx b/portato/ipc.pyx
index abb26fe..7dcf949 100644
--- a/portato/ipc.pyx
+++ b/portato/ipc.pyx
@@ -70,7 +70,7 @@ cdef class MessageQueue (object):
elif errno == ENOENT:
raise MessageQueueError("Queue does not exist and 'create' is not set.")
elif errno == ENOMEM or errno == ENOSPC:
- raise MemoryError("Insufficient ressources.")
+ PyErr_NoMemory()
else:
raise OSError(errno, strerror(errno))
@@ -111,7 +111,7 @@ cdef class MessageQueue (object):
msg = <msg_data*>PyMem_Malloc(sizeof(msg_data) + size)
if msg is NULL:
- raise MemoryError("Out of memory")
+ PyErr_NoMemory()
memcpy(msg.mtext, <char*>message, size)
msg.mtype = type
@@ -119,18 +119,17 @@ cdef class MessageQueue (object):
with nogil:
ret = msgsnd(self.msgid, msg, size, 0)
- try:
- if ret == -1:
- if errno == EIDRM or errno == EINVAL:
- raise MessageQueueRemovedError("Queue was removed.")
- elif errno == EINTR:
- raise MessageQueueError("Signaled while waiting.")
- elif errno == EACCES:
- raise MessageQueueError("Permission denied.")
- else:
- raise OSError(errno, strerror(errno))
- finally:
- PyMem_Free(msg)
+ PyMem_Free(msg)
+
+ if ret == -1:
+ if errno == EIDRM or errno == EINVAL:
+ raise MessageQueueRemovedError("Queue was removed.")
+ elif errno == EINTR:
+ raise MessageQueueError("Signaled while waiting.")
+ elif errno == EACCES:
+ raise MessageQueueError("Permission denied.")
+ else:
+ raise OSError(errno, strerror(errno))
def receive (self):
"""
@@ -145,7 +144,7 @@ cdef class MessageQueue (object):
msg = <msg_data*>PyMem_Malloc(sizeof(msg_data) + MAX_MESSAGE_SIZE)
if msg is NULL:
- raise MemoryError("Out of memory")
+ PyErr_NoMemory()
msg.mtype = 0
@@ -162,12 +161,11 @@ cdef class MessageQueue (object):
raise MessageQueueError("Permission denied.")
else:
raise OSError(errno, strerror(errno))
-
- retTuple = (PyString_FromStringAndSize(msg.mtext, ret), msg.mtype)
+ else:
+ return (PyString_FromStringAndSize(msg.mtext, ret), msg.mtype)
+
finally:
PyMem_Free(msg)
- return retTuple
-
cdef inline key_t random_key (self):
return <int>(<double>rand() / (<double>RAND_MAX + 1) * INT_MAX)