From 8af4942857cb8eb906056df4c4ae7ffefe9e229c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Tue, 13 Apr 2010 21:21:56 +0200 Subject: Better eix error inheritance and handling --- portato/eix/exceptions.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'portato/eix') diff --git a/portato/eix/exceptions.py b/portato/eix/exceptions.py index 1ca05e1..cc4665d 100644 --- a/portato/eix/exceptions.py +++ b/portato/eix/exceptions.py @@ -23,7 +23,14 @@ class EixError (Exception): :ivar message: The error message """ + message = _("Unknown error.") + + def __init__ (self, msg = None): + Exception.__init__(self) + + if msg: + self.message = msg def __str__ (self): return self.message @@ -34,7 +41,7 @@ class EndOfFileException (EixError): """ def __init__ (self, filename): - self.message = _("End of file reached though it was not expected: '%s'") % filename + EixError.__init__(self, _("End of file reached though it was not expected: '%s'") % filename) class UnsupportedVersionError (EixError): """ @@ -42,4 +49,4 @@ class UnsupportedVersionError (EixError): """ def __init__ (self, version): - self.message = _("Version '%s' is not supported.") % version + EixError.__init__(self, _("Version '%s' is not supported.") % version) -- cgit v1.2.3 From efd5aa7d6e66cc1ab201d5fc5933787a7c8690b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Wed, 14 Apr 2010 04:42:56 +0200 Subject: Fixed the unicode support and stuff ... and also made eix faster :) --- portato/eix/parser.pyx | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'portato/eix') diff --git a/portato/eix/parser.pyx b/portato/eix/parser.pyx index 6363b37..4315191 100644 --- a/portato/eix/parser.pyx +++ b/portato/eix/parser.pyx @@ -33,6 +33,8 @@ 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 @@ -54,7 +56,15 @@ cdef int _get_byte (FILE* file) except -1: # Base Types # -cdef LLong _number (object pfile): +cpdef LLong number (object pfile): + """ + Returns a number. + + :param file: The file to read from + :type file: file + :rtype: int + """ + cdef UChar n cdef LLong value cdef int i @@ -84,18 +94,7 @@ cdef LLong _number (object pfile): return value -def number (file): - """ - Returns a number. - - :param file: The file to read from - :type file: file - :rtype: int - """ - - return _number(file) - -def vector (file, get_type, nelems = None): +cpdef object vector (object file, object get_type, object nelems = None): """ Returns a vector of elements. @@ -118,13 +117,13 @@ def vector (file, get_type, nelems = None): cdef LLong i if nelems is None: - n = _number(file) + n = number(file) else: n = nelems return [get_type(file) for i in range(n)] -def string (file): +cpdef object string (object file, char u = 0): """ Returns a string. @@ -132,13 +131,16 @@ def string (file): :type file: file :rtype: str """ - nelems = _number(file) + cdef LLong nelems = number(file) s = file.read(nelems) if len(s) != nelems: raise EndOfFileException, file.name + if u: + return python_unicode.PyUnicode_DecodeUTF8(s, nelems, 'replace') + return s # @@ -220,8 +222,8 @@ cdef class header: :param file: The file to read from :type file: file """ - self.version = _number(file) - self.ncats = _number(file) + self.version = number(file) + self.ncats = number(file) self.overlays = vector(file, overlay) self.provide = vector(file, string) self.licenses = vector(file, string) @@ -274,12 +276,12 @@ cdef class package: cdef FILE* cfile = PyFile_AsFile(file) cdef long after_offset - self._offset = _number(file) + self._offset = number(file) after_offset = ftell(cfile) self.name = string(file) - self.description = unicode(string(file)) + self.description = string(file,1) # skip the rest, as it is currently unneeded #self.provide = vector(file, number) -- cgit v1.2.3 From 208c4adfbdf7b82cc40da873ed185f3e29880cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Wed, 14 Apr 2010 22:17:53 +0200 Subject: Improve the C modules --- portato/eix/parser.pyx | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) (limited to 'portato/eix') 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 = 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) -- cgit v1.2.3