In file: C:\Python22\trial.py
#
# Pyrex wrapper for the expat API
#
import __builtin__
import sys
cdef extern from "expat/expat.h":
cdef struct XML_ParserStruct
ctypedef XML_ParserStruct *XML_Parser
ctypedef char XML_Char
cdef int XML_Parse(XML_Parser p, char *data, int length, int isFinal)
cdef XML_Parser XML_ParserCreate(XML_Char *encodingName)
cdef int XML_GetErrorCode(XML_Parser p)
cdef int XML_GetErrorLineNumber(XML_Parser p)
cdef int XML_GetErrorColumnNumber(XML_Parser p)
cdef char *XML_ErrorString(int code)
cdef void XML_SetStartElementHandler(XML_Parser, void *)
cdef void XML_SetEndElementHandler(XML_Parser, void *)
cdef void XML_SetUserData(XML_Parser, void *)
cdef void *XML_GetBuffer(XML_Parser, int bufsize)
cdef int XML_ParseBuffer(XML_Parser, int bytes, int final)
cdef extern from "stdio.h":
cdef struct FILE
cdef int strlen(char *string)
cdef int fread(void *buf, int size, int length, FILE *)
cdef extern from "Python.h":
cdef object PyUnicode_DecodeUTF8(char *str, int l, char *strict)
cdef void *PyDict_GetItem(object intern_dict, object val)
cdef FILE *PyFile_AsFile(object file)
class ExpatError(Exception):
def __init__(self, char *msg, int code, int offset, int lineno):
Exception.__init__(self, msg)
self.message = msg
self.code = code
self.offset = offset
self.lineno = lineno
cdef class ExpatParser:
cdef XML_Parser _parser
cdef object exception_occurred
cdef char *encoding
cdef object intern_dict
cdef object StartElementHandler
cdef object EndElementHandler
def __init__(self, char *encoding):
self._parser = XML_ParserCreate(encoding)
XML_SetUserData(self._parser, <void *>self)
self.encoding = encoding
self.intern_dict = {}
def set_error(self, int code):
cdef int lineno, column
lineno = XML_GetErrorLineNumber(self._parser)
column = XML_GetErrorColumnNumber(self._parser)
message = "%s: line %d, column %d" % (
XML_ErrorString(code), lineno, column)
raise ExpatError(message, code, lineno, column)
cdef ParseFP(self, FILE *fp):
cdef int BUF_SIZE, rv, bytes_read
cdef void *buf
BUF_SIZE = 2048
rv = bytes_read = 1
while(rv and bytes_read and
(self.exception_occurred is None)):
buf = XML_GetBuffer(self._parser, BUF_SIZE)
if not buf:
raise MemoryError
bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp)
if bytes_read < 0:
raise IOError
rv = XML_ParseBuffer(self._parser, bytes_read, bytes_read == 0)
return rv
cdef ParseFileLike(self, readmethod):
cdef int BUF_SIZE, rv, bytes_read
BUF_SIZE = 2048
rv = bytes_read = 1
while(rv and data and
(self.exception_occurred is None)):
data = readmethod(BUF_SIZE)
if data:
rv = self.Parse(data, 0)
else:
rv = self.Parse(data, 1)
return rv
def ParseFile(self, object f):
cdef XML_Parser parser
cdef int rv
cdef FILE *fp
parser = self._parser
if isinstance(f, file):
fp = PyFile_AsFile(f)
rv = self.ParseFP(fp)
else:
# this branch hasn't been tested
readmethod = getattr(f, "read", None)
if not readmethod:
raise TypeError, \
"Argument should have 'read' attribute"
self.ParseFileLike(readmethod)
if self.exception_occurred is not None:
raise self.exception_occurred[0], \
self.exception_occurred[1], \
self.exception_occurred[2]
if not rv:
self.set_error(XML_GetErrorCode(parser))
else:
return rv
def Parse(self, char *data, int isFinal):
"""Parse(data[, isfinal])
Parse XML data. `isfinal` should be true at end of input."""
result = XML_Parse(self._parser, data, len(data), isFinal)
if not result:
self.set_error(XML_GetErrorCode(self._parser))
return result
def sethandler(self, name, function):
try:
handler = handlerInfo[name]
except KeyError:
raise AttributeError, "No such attribute %s" % name
handler(self, function)
def __setattr__(self, name, value):
self.sethandler(name, value)
cdef object string_intern(intern_dict, char *string):
if intern_dict is None:
return unicode(string)
cdef void *value
value = PyDict_GetItem(intern_dict, string)
if value != NULL:
return <object>value
result = unicode(string)
intern_dict[string] = result
return result
cdef do_StartElement( void *userData, XML_Char *name, XML_Char *attrs[]):
cdef int i, length, max
cdef ExpatParser parser
parser = <ExpatParser>userData
i = length = 0
while attrs[length]:
length = length + 2
max = length/2
pyattrs = []
for i from 0 <= i < max:
attr_name = string_intern(parser.intern_dict, attrs[i] )
attr_value = PyUnicode_DecodeUTF8(attrs[i+1],
strlen(attrs[i+1]),
"strict")
pyattrs.append((attr_name, attr_value))
try:
parser.StartElementHandler(name, pyattrs)
except:
print "EXCEPTION!!!"
parser.exception_occurred = sys.exc_info()
def setStartElementHandler(ExpatParser parser, object handler):
XML_SetStartElementHandler(parser._parser, <void *>do_StartElement)
parser.StartElementHandler = handler
cdef do_EndElement( void *userData, XML_Char *name):
cdef ExpatParser parser
parser = <ExpatParser> userData
parser.EndElementHandler(string_intern( parser.intern_dict, name))
def setEndElementHandler(ExpatParser parser, object handler):
XML_SetEndElementHandler(parser._parser, <void *>do_EndElement)
parser.EndElementHandler = handler
handlerInfo = {"StartElementHandler": setStartElementHandler,
"EndElementHandler" : setEndElementHandler }
def CreateParser(char *encodingName):
return ExpatParser(encodingName)
#def find(f):
# find_cheeses(callback, <void*>f)
#cdef void callback(char *name, void *f):
# (<object>f)(name)
# just a test
cdef int spam() except? -1: