Author: Antonio Cuni <anto.c...@gmail.com>
Branch: faster-rstruct-2
Changeset: r91217:1bb9b4819612
Date: 2017-05-09 23:38 +0200
http://bitbucket.org/pypy/pypy/changeset/1bb9b4819612/

Log:    add rlib.Buffer.typed_read, and implement it for RawBuffer

diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -18,6 +18,12 @@
     specific type of buffer, or because of alignment issues.
     """
 
+class CannotWrite(Exception):
+    """
+    Raised by Buffer.typed_write in case it is not possible to accomplish the
+    request
+    """
+
 class Buffer(object):
     """Abstract base class for buffers."""
     _attrs_ = ['readonly']
@@ -91,6 +97,13 @@
         """
         raise CannotRead
 
+    @specialize.ll_and_arg(1)
+    def typed_write(self, TP, byte_offset, value):
+        """
+        Write the value of type TP at byte_offset. No bounds checks
+        """
+        raise CannotWrite
+
 
 class RawBuffer(Buffer):
     """
@@ -111,6 +124,17 @@
         ptr = self.get_raw_address()
         return llop.raw_load(TP, ptr, byte_offset)
 
+    @specialize.ll_and_arg(1)
+    def typed_write(self, TP, byte_offset, value):
+        """
+        Write the value of type TP at byte_offset. No bounds checks
+        """
+        if self.readonly:
+            raise CannotWrite
+        ptr = self.get_raw_address()
+        value = lltype.cast_primitive(TP, value)
+        return llop.raw_store(lltype.Void, ptr, byte_offset, value)
+
 
 class StringBuffer(Buffer):
     _attrs_ = ['readonly', 'value']
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
@@ -8,14 +8,19 @@
 
 class MyRawBuffer(RawBuffer):
 
-    def __init__(self, data):
-        self._buf = lltype.malloc(rffi.CCHARP.TO, len(data), flavor='raw')
+    def __init__(self, data, readonly):
+        self.readonly = readonly
+        self._n = len(data)
+        self._buf = lltype.malloc(rffi.CCHARP.TO, self._n, flavor='raw')
         for i, ch in enumerate(data):
             self._buf[i] = ch
 
     def get_raw_address(self):
         return self._buf
 
+    def as_str(self):
+        return rffi.charpsize2str(self._buf, self._n)
+
     def __del__(self):
         lltype.free(self._buf, flavor='raw')
         self._buf = None
@@ -119,6 +124,14 @@
         return buf.typed_read(TYPE, offset)
     
 
+class TestRawBufferTypedWrite(object):
+
+    def test_typed_write(self):
+        buf = MyRawBuffer('\xff' * 8, readonly=False)
+        buf.typed_write(rffi.USHORT, 0, 0xABCD)
+        assert buf.as_str() == '\xcd\xab\xff\xff\xff\xff\xff\xff'
+        assert buf.typed_read(rffi.USHORT, 0) == 0xABCD
+    
 
 class TestCompiled(BaseTypedReadTest):
     cache = {}
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to