Author: Brian Kearns <[email protected]>
Branch:
Changeset: r63261:4da612f571cc
Date: 2013-04-12 01:08 -0400
http://bitbucket.org/pypy/pypy/changeset/4da612f571cc/
Log: change BytesIO to use RStringIO
diff --git a/pypy/module/_io/interp_bytesio.py
b/pypy/module/_io/interp_bytesio.py
--- a/pypy/module/_io/interp_bytesio.py
+++ b/pypy/module/_io/interp_bytesio.py
@@ -2,37 +2,25 @@
TypeDef, generic_new_descr, GetSetProperty)
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.error import OperationError, operationerrfmt
+from rpython.rlib.rStringIO import RStringIO
from rpython.rlib.rarithmetic import r_longlong
from pypy.module._io.interp_bufferedio import W_BufferedIOBase
from pypy.module._io.interp_iobase import convert_size
import sys
-def buffer2string(buffer, start, end):
- from rpython.rlib.rstring import StringBuilder
- builder = StringBuilder(end - start)
- for i in range(start, end):
- builder.append(buffer[i])
- return builder.build()
-class W_BytesIO(W_BufferedIOBase):
+class W_BytesIO(RStringIO, W_BufferedIOBase):
def __init__(self, space):
W_BufferedIOBase.__init__(self, space)
- self.pos = 0
- self.string_size = 0
- self.buf = None
+ RStringIO.__init__(self)
def descr_init(self, space, w_initial_bytes=None):
- # In case __init__ is called multiple times
- self.buf = []
- self.string_size = 0
- self.pos = 0
-
if not space.is_none(w_initial_bytes):
self.write_w(space, w_initial_bytes)
- self.pos = 0
+ self.seek(0)
def _check_closed(self, space, message=None):
- if self.buf is None:
+ if self.is_closed():
if message is None:
message = "I/O operation on closed file"
raise OperationError(space.w_ValueError, space.wrap(message))
@@ -40,36 +28,12 @@
def read_w(self, space, w_size=None):
self._check_closed(space)
size = convert_size(space, w_size)
-
- # adjust invalid sizes
- available = self.string_size - self.pos
- if not 0 <= size <= available:
- size = available
- if size < 0:
- size = 0
-
- output = buffer2string(self.buf, self.pos, self.pos + size)
- self.pos += size
- return space.wrap(output)
+ return space.wrap(self.read(size))
def readline_w(self, space, w_limit=None):
self._check_closed(space)
limit = convert_size(space, w_limit)
-
- cur_pos = self.pos
- if limit < 0:
- end_pos = self.string_size
- else:
- end_pos = min(cur_pos + limit, self.string_size)
- while cur_pos != end_pos:
- if self.buf[cur_pos] == '\n':
- cur_pos += 1
- break
- cur_pos += 1
-
- output = buffer2string(self.buf, self.pos, cur_pos)
- self.pos = cur_pos
- return space.wrap(output)
+ return space.wrap(self.readline(limit))
def read1_w(self, space, w_size):
return self.read_w(space, w_size)
@@ -79,56 +43,27 @@
rwbuffer = space.rwbuffer_w(w_buffer)
size = rwbuffer.getlength()
- if self.pos + size > self.string_size:
- size = self.string_size - self.pos
-
- output = buffer2string(self.buf, self.pos, self.pos + size)
- length = len(output)
+ output = self.read(size)
rwbuffer.setslice(0, output)
- self.pos += length
- return space.wrap(length)
+ return space.wrap(len(output))
def write_w(self, space, w_data):
self._check_closed(space)
if space.isinstance_w(w_data, space.w_unicode):
raise OperationError(space.w_TypeError, space.wrap(
"bytes string of buffer expected"))
- buf = space.buffer_w(w_data)
- length = buf.getlength()
+ buf = space.bufferstr_w(w_data)
+ length = len(buf)
if length <= 0:
return space.wrap(0)
-
- if self.pos + length > len(self.buf):
- self.buf.extend(['\0'] * (self.pos + length - len(self.buf)))
-
- if self.pos > self.string_size:
- # In case of overseek, pad with null bytes the buffer region
- # between the end of stream and the current position.
- #
- # 0 lo string_size hi
- # | |<---used--->|<----------available----------->|
- # | | <--to pad-->|<---to write---> |
- # 0 buf position
- for i in range(self.string_size, self.pos):
- self.buf[i] = '\0'
-
- # Copy the data to the internal buffer, overwriting some of the
- # existing data if self->pos < self->string_size.
- for i in range(length):
- self.buf[self.pos + i] = buf.getitem(i)
- self.pos += length
-
- # Set the new length of the internal string if it has changed
- if self.string_size < self.pos:
- self.string_size = self.pos
-
+ self.write(buf)
return space.wrap(length)
def truncate_w(self, space, w_size=None):
self._check_closed(space)
if space.is_none(w_size):
- size = self.pos
+ size = self.tell()
else:
size = space.r_longlong_w(w_size)
@@ -136,19 +71,16 @@
raise OperationError(space.w_ValueError, space.wrap(
"negative size value"))
- if size < self.string_size:
- self.string_size = size
- del self.buf[size:]
-
+ self.truncate(size)
return space.wrap(size)
def getvalue_w(self, space):
self._check_closed(space)
- return space.wrap(buffer2string(self.buf, 0, self.string_size))
+ return space.wrap(self.getvalue())
def tell_w(self, space):
self._check_closed(space)
- return space.wrap(self.pos)
+ return space.wrap(self.tell())
@unwrap_spec(pos=r_longlong, whence=int)
def seek_w(self, space, pos, whence=0):
@@ -159,24 +91,19 @@
raise OperationError(space.w_ValueError, space.wrap(
"negative seek value"))
elif whence == 1:
- if pos > sys.maxint - self.pos:
+ if pos > sys.maxint - self.tell():
raise OperationError(space.w_OverflowError, space.wrap(
"new position too large"))
- pos += self.pos
elif whence == 2:
- if pos > sys.maxint - self.string_size:
+ if pos > sys.maxint - self.getsize():
raise OperationError(space.w_OverflowError, space.wrap(
"new position too large"))
- pos += self.string_size
else:
raise operationerrfmt(space.w_ValueError,
"whence must be between 0 and 2, not %d", whence)
- if pos >= 0:
- self.pos = pos
- else:
- self.pos = 0
- return space.wrap(self.pos)
+ self.seek(pos, whence)
+ return space.wrap(self.tell())
def readable_w(self, space):
return space.w_True
@@ -188,17 +115,16 @@
return space.w_True
def close_w(self, space):
- self.buf = None
+ self.close()
def closed_get_w(self, space):
- return space.wrap(self.buf is None)
+ return space.wrap(self.is_closed())
def getstate_w(self, space):
self._check_closed(space)
- w_content = space.wrap(buffer2string(self.buf, 0, self.string_size))
return space.newtuple([
- w_content,
- space.wrap(self.pos),
+ space.wrap(self.getvalue()),
+ space.wrap(self.tell()),
self.getdict(space)])
def setstate_w(self, space, w_state):
@@ -211,13 +137,13 @@
space.type(w_state).getname(space)
)
w_content, w_pos, w_dict = space.unpackiterable(w_state, 3)
+ self.truncate(0)
+ self.write_w(space, w_content)
pos = space.int_w(w_pos)
- self.buf = []
- self.write_w(space, w_content)
if pos < 0:
raise OperationError(space.w_ValueError, space.wrap(
"position value cannot be negative"))
- self.pos = pos
+ self.seek(pos)
if not space.is_w(w_dict, space.w_None):
space.call_method(self.getdict(space), "update", w_dict)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit