]> granicus.if.org Git - python/commitdiff
SF patch #100740: Add optional size arguments to .readline() and
authorAndrew M. Kuchling <amk@amk.ca>
Sat, 29 Jul 2000 20:15:26 +0000 (20:15 +0000)
committerAndrew M. Kuchling <amk@amk.ca>
Sat, 29 Jul 2000 20:15:26 +0000 (20:15 +0000)
.readlines() methods.  Inspired by a patch from Wolfgang Grafen,
though this version of the patch was completely rewritten from his
code.

Lib/gzip.py

index 43501d40a7a8ff65670e64da5b534008140681a2..0c9642bcd62bd09c1f194db7febd447e162340e9 100644 (file)
@@ -5,10 +5,8 @@ but random access is not allowed."""
 
 # based on Andrew Kuchling's minigzip.py distributed with the zlib module
 
-import time
-import string
+import string, struct, sys, time
 import zlib
-import struct
 import __builtin__
 
 FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
@@ -175,7 +173,8 @@ class GzipFile:
         if self.fileobj is None: raise EOFError, "Reached EOF"
        
         if self._new_member:
-            # If the _new_member flag is set, we have to 
+            # If the _new_member flag is set, we have to
+            # jump to the next member, if there is one.
             # 
             # First, check if we're at the end of the file;
             # if so, it's time to stop; no more members to read.
@@ -273,27 +272,46 @@ class GzipFile:
     def isatty(self):
         return 0
 
-    def readline(self):
+    def readline(self, size=-1):
+        if size < 0: size = sys.maxint
         bufs = []
-        readsize = 100
+        orig_size = size
+        readsize = min(100, size)    # Read from the file in small chunks
         while 1:
+            if size == 0:
+                return string.join(bufs, '') # Return resulting line
+
             c = self.read(readsize)
             i = string.find(c, '\n')
+            if size is not None:
+                # We set i=size to break out of the loop under two
+                # conditions: 1) there's no newline, and the chunk is 
+                # larger than size, or 2) there is a newline, but the
+                # resulting line would be longer than 'size'.
+                if i==-1 and len(c) > size: i=size-1
+                elif size <= i: i = size -1
+
             if i >= 0 or c == '':
-                bufs.append(c[:i+1])
-                self._unread(c[i+1:])
-                return string.join(bufs, '')
+                bufs.append(c[:i+1])    # Add portion of last chunk
+                self._unread(c[i+1:])   # Push back rest of chunk
+                return string.join(bufs, '') # Return resulting line
+
+            # Append chunk to list, decrease 'size',
             bufs.append(c)
-            readsize = readsize * 2
-
-    def readlines(self, ignored=None):
-        buf = self.read()
-        lines = string.split(buf, '\n')
-        for i in range(len(lines)-1):
-            lines[i] = lines[i] + '\n'
-        if lines and not lines[-1]:
-            del lines[-1]
-        return lines
+            size = size - len(c)
+            readsize = min(size, readsize * 2)
+            
+    def readlines(self, sizehint=0):
+        # Negative numbers result in reading all the lines
+        if sizehint <= 0: sizehint = sys.maxint
+        L = []
+        while sizehint > 0:
+            line = self.readline()
+            if line == "": break
+            L.append( line )
+            sizehint = sizehint - len(line)
+
+        return L
 
     def writelines(self, L):
         for line in L: