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

Reply via email to