I've been working with Richard on a new (rpython) buffer class.
See attached for two approaches.
The richbuf seems much clearer, but i'm not sure how to get other
types out of it (like long long or short), or do byte swapping.
I don't understand this much, can someone point the right direction ?
Ie. which buf is the right direction to go.
(I would also like to re-visit the array type in pypy/rpython/numpy,
and perhaps think more generally about __getitem__ in rpython.)
The rffi buffer (buffers.py) fails on CPython:
$ python buffers.py
Traceback (most recent call last):
File "buffers.py", line 55, in <module>
test_run()
File "buffers.py", line 51, in test_run
assert demo(1234) == 1234
File "buffers.py", line 39, in demo
buf.put_int32(value)
File "buffers.py", line 31, in put_int32
intp = rffi.cast(INTP, buf)
File "/home/simon/site-packages/pypy/rpython/lltypesystem/ll2ctypes.py", line
491, in force_cast
cvalue = lltype2ctypes(value)
File "/home/simon/site-packages/pypy/rpython/lltypesystem/ll2ctypes.py", line
336, in lltype2ctypes
convert_struct(container)
File "/home/simon/site-packages/pypy/rpython/lltypesystem/ll2ctypes.py", line
161, in convert_struct
convert_struct(parent)
File "/home/simon/site-packages/pypy/rpython/lltypesystem/ll2ctypes.py", line
165, in convert_struct
cstruct = cls._malloc()
File "/home/simon/site-packages/pypy/rpython/lltypesystem/ll2ctypes.py", line
89, in _malloc
raise TypeError, "array length must be an int"
TypeError: array length must be an int
Simon.
from pypy.rpython.lltypesystem import rffi
from pypy.rpython.lltypesystem.rffi import INTP, LONG
from pypy.rpython.lltypesystem import lltype
from time import sleep
class Buffer(object):
MEM = lltype.Array(lltype.Char, hints={'nolength': True})
def __init__(self, capacity=4096):
self.data = lltype.malloc(self.MEM, capacity, flavor='raw')
self.pos = 0
self.markpos = -1
self.limit = capacity
self.capacity = capacity
def get_int32(self):
data = self.data
buf = lltype.direct_arrayitems(data)
buf = lltype.direct_ptradd(buf, self.pos)
intp = rffi.cast(INTP, buf)
value = intp[0]
return value
def put_int32(self, value):
data = self.data
buf = lltype.direct_arrayitems(data)
buf = lltype.direct_ptradd(buf, self.pos)
intp = rffi.cast(INTP, buf)
intp[0] = value
def __del__(self):
lltype.free(self.data, flavor='raw')
def demo(value):
buf = Buffer()
buf.put_int32(value)
x = buf.get_int32()
return x
def test_compile():
from pypy.translator.c.test.test_genc import compile
_demo = compile(demo, [rffi.INT])
assert _demo(1234) == 1234
def test_run():
assert demo(1234) == 1234
if __name__ == "__main__":
test_run()
# works against r44520
from pypy.rpython.memory.lladdress import raw_malloc, raw_free
class Buffer(object):
def __init__(self, capacity=4096):
self.mem = raw_malloc(capacity)
print dir(self.mem)
self.pos = 0
def rewind(self):
self.pos = 0
def get_int32(self):
addr = self.mem + self.pos
value = addr.signed[0]
self.pos += 4
return value
def put_int32(self, value):
addr = self.mem + self.pos
addr.signed[0] = value
self.pos += 4
def get_char(self):
addr = self.mem + self.pos
value = addr.char[0]
self.pos += 1
return value
def put_char(self, value):
addr = self.mem + self.pos
addr.char[0] = value
self.pos += 1
def __del__(self):
raw_free(self.mem)
def demo(value):
buf = Buffer()
buf.put_int32(value)
buf.rewind()
x = buf.get_int32()
buf.rewind()
#print "%s%s%s%s" % (buf.get_char(), buf.get_char(), buf.get_char(), buf.get_char())
#buf.rewind()
buf.put_char('X')
buf.rewind()
x += buf.get_char() == 'X'
return x
def test_1():
from pypy.translator.c.test.test_genc import compile
_demo = compile(demo, [int])
assert _demo(12345678) == 12345679
if __name__ == "__main__":
# test_1()
print demo(1234)
_______________________________________________
[email protected]
http://codespeak.net/mailman/listinfo/pypy-dev