Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r57823:52c909884ae5
Date: 2012-10-07 17:44 +0200
http://bitbucket.org/pypy/pypy/changeset/52c909884ae5/

Log:    Redo a solution that is very inefficient but maybe not as bad as
        before.

diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py
--- a/pypy/rlib/streamio.py
+++ b/pypy/rlib/streamio.py
@@ -41,6 +41,7 @@
 from pypy.rlib.objectmodel import specialize, we_are_translated
 from pypy.rlib.rarithmetic import r_longlong, intmask
 from pypy.rlib import rposix
+from pypy.rlib.rstring import StringBuilder
 
 from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC
 O_BINARY = getattr(os, "O_BINARY", 0)
@@ -141,11 +142,7 @@
 def construct_stream_tower(stream, buffering, universal, reading, writing,
                            binary):
     if buffering == 0:   # no buffering
-        # XXX we cannot really use ReadlineInputStream: see module/_file/
-        # test/test_file.py:test_readline_unbuffered_should_read_one_line_only
         pass
-        #if reading:      # force some minimal buffering for readline()
-        #    stream = ReadlineInputStream(stream)
     elif buffering == 1:   # line-buffering
         if writing:
             stream = LineBufferingOutputStream(stream)
@@ -306,6 +303,26 @@
                     raise
                 # else try again
 
+    def readline(self):
+        # mostly inefficient, but not as laughably bad as with the default
+        # readline() from Stream
+        result = StringBuilder()
+        while True:
+            try:
+                c = os.read(self.fd, 1)
+            except OSError, e:
+                if e.errno != errno.EINTR:
+                    raise
+                else:
+                    continue   # try again
+            if not c:
+                break
+            c = c[0]
+            result.append(c)
+            if c == '\n':
+                break
+        return result.build()
+
     def write(self, data):
         while data:
             try:
@@ -703,113 +720,6 @@
                                               flush_buffers=False)
 
 
-class ReadlineInputStream(Stream):
-
-    """Minimal buffering input stream.
-
-    Only does buffering for readline().  The other kinds of reads, and
-    all writes, are not buffered at all.
-    """
-
-    bufsize = 2**13 # 8 K
-
-    def __init__(self, base, bufsize=-1):
-        self.base = base
-        self.do_read = base.read   # function to fill buffer some more
-        self.do_seek = base.seek   # seek to a byte offset
-        if bufsize == -1:     # Get default from the class
-            bufsize = self.bufsize
-        self.bufsize = bufsize  # buffer size (hint only)
-        self.buf = None         # raw data (may contain "\n")
-        self.bufstart = 0
-
-    def flush_buffers(self):
-        if self.buf is not None:
-            try:
-                self.do_seek(self.bufstart-len(self.buf), 1)
-            except (MyNotImplementedError, OSError):
-                pass
-            else:
-                self.buf = None
-                self.bufstart = 0
-
-    def readline(self):
-        if self.buf is not None:
-            i = self.buf.find('\n', self.bufstart)
-        else:
-            self.buf = ''
-            i = -1
-        #
-        if i < 0:
-            self.buf = self.buf[self.bufstart:]
-            self.bufstart = 0
-            while True:
-                bufsize = max(self.bufsize, len(self.buf) >> 2)
-                data = self.do_read(bufsize)
-                if not data:
-                    result = self.buf              # end-of-file reached
-                    self.buf = None
-                    return result
-                startsearch = len(self.buf)   # there is no '\n' in buf so far
-                self.buf += data
-                i = self.buf.find('\n', startsearch)
-                if i >= 0:
-                    break
-        #
-        i += 1
-        result = self.buf[self.bufstart:i]
-        self.bufstart = i
-        return result
-
-    def peek(self):
-        if self.buf is None:
-            return ''
-        if self.bufstart > 0:
-            self.buf = self.buf[self.bufstart:]
-            self.bufstart = 0
-        return self.buf
-
-    def tell(self):
-        pos = self.base.tell()
-        if self.buf is not None:
-            pos -= (len(self.buf) - self.bufstart)
-        return pos
-
-    def readall(self):
-        result = self.base.readall()
-        if self.buf is not None:
-            result = self.buf[self.bufstart:] + result
-            self.buf = None
-            self.bufstart = 0
-        return result
-
-    def read(self, n):
-        if self.buf is None:
-            return self.do_read(n)
-        else:
-            m = n - (len(self.buf) - self.bufstart)
-            start = self.bufstart
-            if m > 0:
-                result = self.buf[start:] + self.do_read(m)
-                self.buf = None
-                self.bufstart = 0
-                return result
-            elif n >= 0:
-                self.bufstart = start + n
-                return self.buf[start : self.bufstart]
-            else:
-                return ''
-
-    seek       = PassThrough("seek",      flush_buffers=True)
-    write      = PassThrough("write",     flush_buffers=True)
-    truncate   = PassThrough("truncate",  flush_buffers=True)
-    flush      = PassThrough("flush",     flush_buffers=True)
-    flushable  = PassThrough("flushable", flush_buffers=False)
-    close      = PassThrough("close",     flush_buffers=False)
-    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
-                                              flush_buffers=False)
-
-
 class BufferingOutputStream(Stream):
 
     """Standard buffering output stream.
diff --git a/pypy/rlib/test/test_streamio.py b/pypy/rlib/test/test_streamio.py
--- a/pypy/rlib/test/test_streamio.py
+++ b/pypy/rlib/test/test_streamio.py
@@ -1026,7 +1026,7 @@
             base.tell = f
         if not seek:
             base.seek = f
-        return streamio.ReadlineInputStream(base, bufsize)
+        return base
 
     def test_readline(self):
         for file in [self.makeStream(), self.makeStream(bufsize=2)]:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to