[pypy-svn] r34499 - in pypy/dist/pypy/rlib: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Nov 11 19:47:57 CET 2006
Author: arigo
Date: Sat Nov 11 19:47:57 2006
New Revision: 34499
Modified:
pypy/dist/pypy/rlib/rctypesobject.py
pypy/dist/pypy/rlib/test/test_rctypesobject.py
Log:
Some extra getters and setters for arrays of char.
Modified: pypy/dist/pypy/rlib/rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/rctypesobject.py Sat Nov 11 19:47:57 2006
@@ -94,6 +94,7 @@
return llmemory.cast_adr_to_ptr(self.addr, lltype.Ptr(CDATATYPE))
ll_ref._annspecialcase_ = 'specialize:arg(1)'
+# ____________________________________________________________
_primitive_cache = {}
def Primitive(TYPE):
@@ -121,16 +122,16 @@
rc_int = Primitive(lltype.Signed)
rc_char = Primitive(lltype.Char)
+# ____________________________________________________________
class _RCTypesStringData(object):
- ARRAYTYPE = lltype.Array(lltype.Char, hints={'nolength': True})
- FIRSTITEMOFS = llmemory.ArrayItemsOffset(ARRAYTYPE)
- ITEMOFS = llmemory.sizeof(lltype.Char)
+ ARRAYTYPE = lltype.FixedSizeArray(lltype.Char, 1)
+ ITEMOFS = llmemory.sizeof(lltype.Char)
def __init__(self, string):
- rawsize = self.FIRSTITEMOFS + self.ITEMOFS * (len(string) + 1)
+ rawsize = self.ITEMOFS * (len(string) + 1)
self.addr = llmemory.raw_malloc(rawsize)
- a = self.addr + self.FIRSTITEMOFS
+ a = self.addr
for i in range(len(string)):
a.char[0] = string[i]
a += self.ITEMOFS
@@ -138,25 +139,32 @@
def __del__(self):
llmemory.raw_free(self.addr)
+def strlen(p):
+ n = 0
+ while p[n] != '\x00':
+ n += 1
+ return n
+
+def strnlen(p, n_max):
+ n = 0
+ while n < n_max and p[n] != '\x00':
+ n += 1
+ return n
+
+def charp2string(p, length):
+ lst = ['\x00'] * length
+ for i in range(length):
+ lst[i] = p[i]
+ return ''.join(lst)
+
class RCTypesCharP(RCTypesObject):
LLTYPE = lltype.Ptr(_RCTypesStringData.ARRAYTYPE)
- def strlen(self):
- ptr = self.ll_ref(RCTypesCharP.CDATATYPE)
- a = ptr[0]
- n = 0
- while a[n] != '\x00':
- n += 1
- return n
-
def get_value(self):
- length = self.strlen()
ptr = self.ll_ref(RCTypesCharP.CDATATYPE)
- a = ptr[0]
- lst = ['\x00'] * length
- for i in range(length):
- lst[i] = a[i]
- return ''.join(lst)
+ p = ptr[0]
+ length = strlen(p)
+ return charp2string(p, length)
def set_value(self, string):
data = _RCTypesStringData(string)
@@ -166,6 +174,7 @@
rc_char_p = RCTypesCharP
+# ____________________________________________________________
def RPointer(contentscls):
"""Build and return a new RCTypesPointer class."""
@@ -209,6 +218,7 @@
return p
pointer._annspecialcase_ = 'specialize:argtype(0)'
+# ____________________________________________________________
def RStruct(c_name, fields, c_external=False):
"""Build and return a new RCTypesStruct class."""
@@ -249,6 +259,7 @@
make_accessors(name)
return RCTypesStruct
+# ____________________________________________________________
def RFixedArray(itemcls, fixedsize):
"""Build and return a new RCTypesFixedArray class."""
@@ -276,6 +287,30 @@
subblock = self.memblock.addoffset(itemcls.num_keepalives * n)
return itemcls(subaddr, subblock)
+ if itemcls is rc_char:
+ # special methods for arrays of chars
+ def _as_ll_charptr(self):
+ ptr = self.ll_ref(ARRAYTYPE)
+ return lltype.direct_arrayitems(ptr)
+
+ def get_value(self):
+ p = self._as_ll_charptr()
+ n = strnlen(p, fixedsize)
+ return charp2string(p, n)
+
+ def set_value(self, string):
+ p = self._as_ll_charptr()
+ for i in range(fixedsize):
+ if i < len(string):
+ p[i] = string[i]
+ else:
+ p[i] = '\x00'
+ break
+
+ def get_raw(self):
+ p = self._as_ll_charptr()
+ return charp2string(p, fixedsize)
+
setattr(itemcls, key, RCTypesFixedArray)
return RCTypesFixedArray
RFixedArray._annspecialcase_ = 'specialize:memo'
Modified: pypy/dist/pypy/rlib/test/test_rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/test/test_rctypesobject.py Sat Nov 11 19:47:57 2006
@@ -116,6 +116,24 @@
res = self.do(func)
assert res == 26
+ def test_char_array(self):
+ def func():
+ a = RFixedArray(rc_char, 10).allocate()
+ for i in range(6):
+ a.ref(i).set_value("hello!"[i])
+ assert a.get_value() == "hello!"
+ a.set_value("foo")
+ assert a.get_value() == "foo"
+ raw = ''.join([a.ref(i).get_value() for i in range(10)])
+ assert raw == "foo\x00o!\x00\x00\x00\x00"
+ assert raw == a.get_raw()
+ a.set_value("0123456789")
+ assert a.get_raw() == "0123456789"
+ assert a.get_value() == "0123456789"
+ return 1
+ res = self.do(func)
+ assert res == 1
+
class TestLLInterpreted(TestBasic):
POLICY = AnnotatorPolicy()
More information about the Pypy-commit
mailing list