Author: Richard Plangger <[email protected]>
Branch: strbuf-as-buffer
Changeset: r88969:003194aeab2e
Date: 2016-12-08 15:05 +0100
http://bitbucket.org/pypy/pypy/changeset/003194aeab2e/

Log:    add rffi.str2charp_gc to implement StringBuffer.get_raw_address

diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -76,12 +76,13 @@
         return [1]
 
 class StringBuffer(Buffer):
-    __slots__ = ['value']
+    __slots__ = ['value', '_charp']
     _immutable_ = True
 
     def __init__(self, value):
         self.value = value
         self.readonly = True
+        self._charp = 0
 
     def getlength(self):
         return len(self.value)
@@ -105,6 +106,13 @@
             return self.value[start:stop]
         return Buffer.getslice(self, start, stop, step, size)
 
+    def get_raw_address(self):
+        from rpython.rtyper.lltypesystem import rffi
+        if self._charp == 0:
+            self._charp = rffi.str2charp_gc(self.value)
+        return self._charp
+
+
 
 class SubBuffer(Buffer):
     __slots__ = ['buffer', 'offset', 'size']
diff --git a/rpython/rlib/test/test_buffer.py b/rpython/rlib/test/test_buffer.py
--- a/rpython/rlib/test/test_buffer.py
+++ b/rpython/rlib/test/test_buffer.py
@@ -1,4 +1,4 @@
-from rpython.rlib.buffer import *
+from rpython.rlib.buffer import StringBuffer, SubBuffer, Buffer
 from rpython.annotator.annrpython import RPythonAnnotator
 from rpython.annotator.model import SomeInteger
 
@@ -64,3 +64,11 @@
     for i in range(9999, 9, -1):
         buf = SubBuffer(buf, 1, i)
     assert buf.getlength() == 10
+
+def test_string_buffer_as_buffer():
+    buf = StringBuffer(b'hello world')
+    addr = buf.get_raw_address()
+    assert addr[0] == b'h'
+    assert addr[4] == b'o'
+    assert addr[6] == b'w'
+    assert addr[len(b'hello world')] == b'\x00'
diff --git a/rpython/rtyper/lltypesystem/rffi.py 
b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -805,6 +805,19 @@
         else:
             lltype.free(cp, flavor='raw', track_allocation=False)
 
+    # str -> char*
+    def str2charp_gc(s):
+        """ str -> char* but collected by the gc
+        """
+        array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='gc', immortal=True)
+        i = len(s)
+        ll_s = llstrtype(s)
+        copy_string_to_raw(ll_s, array, 0, i)
+        array[i] = lastchar
+        return array
+    str2charp_gc._annenforceargs_ = [strtype, bool]
+
+
     # str -> already-existing char[maxsize]
     def str2chararray(s, array, maxsize):
         length = min(len(s), maxsize)
@@ -984,20 +997,20 @@
         return result
     charpsize2str._annenforceargs_ = [None, int]
 
-    return (str2charp, free_charp, charp2str,
+    return (str2charp, free_charp, str2charp_gc, charp2str,
             get_nonmovingbuffer, free_nonmovingbuffer,
             get_nonmovingbuffer_final_null,
             alloc_buffer, str_from_buffer, keep_buffer_alive_until_here,
             charp2strn, charpsize2str, str2chararray, str2rawmem,
             )
 
-(str2charp, free_charp, charp2str,
+(str2charp, free_charp, str2charp_gc, charp2str,
  get_nonmovingbuffer, free_nonmovingbuffer, get_nonmovingbuffer_final_null,
  alloc_buffer, str_from_buffer, keep_buffer_alive_until_here,
  charp2strn, charpsize2str, str2chararray, str2rawmem,
  ) = make_string_mappings(str)
 
-(unicode2wcharp, free_wcharp, wcharp2unicode,
+(unicode2wcharp, free_wcharp, _, wcharp2unicode,
  get_nonmoving_unicodebuffer, free_nonmoving_unicodebuffer, __not_usable,
  alloc_unicodebuffer, unicode_from_buffer, keep_unicodebuffer_alive_until_here,
  wcharp2unicoden, wcharpsize2unicode, unicode2wchararray, unicode2rawmem,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to