[pypy-commit] pypy faster-rstruct-2: add MutableStringBuffer, which will be used by struct.pack to incrementally build the desired string
antocuni
pypy.commits at gmail.com
Tue May 9 19:29:08 EDT 2017
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct-2
Changeset: r91218:ac79316e004f
Date: 2017-05-10 01:28 +0200
http://bitbucket.org/pypy/pypy/changeset/ac79316e004f/
Log: add MutableStringBuffer, which will be used by struct.pack to
incrementally build the desired string
diff --git a/rpython/rlib/mutbuffer.py b/rpython/rlib/mutbuffer.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/mutbuffer.py
@@ -0,0 +1,40 @@
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rtyper.lltypesystem.rstr import STR
+from rpython.rtyper.annlowlevel import llstr, hlstr
+from rpython.rlib.buffer import Buffer
+
+class MutableStringBuffer(Buffer):
+ """
+ A writeable buffer to incrementally fill a string of a fixed size.
+
+ You can fill the string by calling setitem, setslice and typed_write, and
+ get the result by calling finish().
+
+ After you call finish(), you can no longer modify the buffer. There is no
+ check, you will probably get a segfault after translation.
+
+ You can call finish() only once.
+ """
+ _attrs_ = ['readonly', 'll_val']
+ _immutable_ = True
+
+ def __init__(self, size):
+ self.readonly = False
+ # rstr.mallocstr does not pass zero=True, so we call lltype.malloc
+ # directly
+ self.ll_val = lltype.malloc(STR, size, zero=True)
+
+ def finish(self):
+ if not self.ll_val:
+ raise ValueError("Cannot call finish() twice")
+ result = hlstr(self.ll_val)
+ self.ll_val = lltype.nullptr(STR)
+ self.readonly = True
+ return result
+
+ def as_str(self):
+ raise ValueError('as_str() is not supported. Use finish() instead')
+
+ def setitem(self, index, char):
+ self.ll_val.chars[index] = char
diff --git a/rpython/rlib/rstruct/formatiterator.py b/rpython/rlib/rstruct/formatiterator.py
--- a/rpython/rlib/rstruct/formatiterator.py
+++ b/rpython/rlib/rstruct/formatiterator.py
@@ -116,6 +116,7 @@
def table2desclist(table):
items = table.items()
items.sort()
+ import pdb;pdb.set_trace()
lst = [FmtDesc(key, attrs) for key, attrs in items]
return unrolling_iterable(lst)
diff --git a/rpython/rlib/test/test_mutbuffer.py b/rpython/rlib/test/test_mutbuffer.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/test/test_mutbuffer.py
@@ -0,0 +1,24 @@
+import pytest
+from rpython.rlib.mutbuffer import MutableStringBuffer
+
+class TestMutableStringBuffer(object):
+
+ def test_finish(self):
+ buf = MutableStringBuffer(4)
+ pytest.raises(ValueError, "buf.as_str()")
+ s = buf.finish()
+ assert s == '\x00' * 4
+ pytest.raises(ValueError, "buf.finish()")
+
+ def test_setitem(self):
+ buf = MutableStringBuffer(4)
+ buf.setitem(0, 'A')
+ buf.setitem(1, 'B')
+ buf.setitem(2, 'C')
+ buf.setitem(3, 'D')
+ assert buf.finish() == 'ABCD'
+
+ def test_setslice(self):
+ buf = MutableStringBuffer(6)
+ buf.setslice(2, 'ABCD')
+ assert buf.finish() == '\x00\x00ABCD'
More information about the pypy-commit
mailing list