summaryrefslogtreecommitdiff
path: root/portato/eix/parser.pyx
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/eix/parser.pyx
parent0f19f73c55ea8c8188aec7426ea94bfb7a823720 (diff)
downloadportato-208c4adfbdf7b82cc40da873ed185f3e29880cfa.tar.gz
portato-208c4adfbdf7b82cc40da873ed185f3e29880cfa.tar.bz2
portato-208c4adfbdf7b82cc40da873ed185f3e29880cfa.zip
Improve the C modules
Diffstat (limited to 'portato/eix/parser.pyx')
-rw-r--r--portato/eix/parser.pyx50
1 files changed, 33 insertions, 17 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)