summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-05-10 22:33:55 (GMT)
committerGuido van Rossum <guido@python.org>1997-05-10 22:33:55 (GMT)
commit789a1613a08d6d6891a40ca1800eaba217eea6bf (patch)
treee99793dc64d5f5d88f0643c13543b209effe06b3 /Objects
parent6263d5451cd874edc05ef87c9d978a3190e65b28 (diff)
downloadcpython-789a1613a08d6d6891a40ca1800eaba217eea6bf.zip
cpython-789a1613a08d6d6891a40ca1800eaba217eea6bf.tar.gz
cpython-789a1613a08d6d6891a40ca1800eaba217eea6bf.tar.bz2
Add optional 'sizehint' argument to readlines(). After approximately
this many bytes have been read, readlines stops. Because of buffering, the amount of bytes read is usually at least 8K more than the hint. Also changed read() and readline() to use PyArg_ParseTuple(). (Note that the *previous* checkin also fixed error handling and narrowed the range of thread unblocking for all methods using fread().)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/fileobject.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 3215c6e..257702f 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -431,18 +431,14 @@ file_read(f, args)
PyFileObject *f;
PyObject *args;
{
- long bytesrequested;
+ long bytesrequested = -1;
size_t bytesread, buffersize, chunksize;
PyObject *v;
if (f->f_fp == NULL)
return err_closed();
- if (args == NULL)
- bytesrequested = -1;
- else {
- if (!PyArg_Parse(args, "l", &bytesrequested))
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
+ return NULL;
if (bytesrequested < 0)
buffersize = new_buffersize(f, 0);
else
@@ -651,21 +647,16 @@ file_readline(f, args)
PyFileObject *f;
PyObject *args;
{
- int n;
+ int n = -1;
if (f->f_fp == NULL)
return err_closed();
- if (args == NULL)
- n = 0; /* Unlimited */
- else {
- if (!PyArg_Parse(args, "i", &n))
- return NULL;
- if (n == 0)
- return PyString_FromString("");
- if (n < 0)
- n = 0;
- }
-
+ if (!PyArg_ParseTuple(args, "|i", &n))
+ return NULL;
+ if (n == 0)
+ return PyString_FromString("");
+ if (n < 0)
+ n = 0;
return getline(f, n);
}
@@ -674,6 +665,7 @@ file_readlines(f, args)
PyFileObject *f;
PyObject *args;
{
+ long sizehint = 0;
PyObject *list;
PyObject *line;
char small_buffer[SMALLCHUNK];
@@ -682,12 +674,13 @@ file_readlines(f, args)
PyObject *big_buffer = NULL;
size_t nfilled = 0;
size_t nread;
+ size_t totalread = 0;
char *p, *q, *end;
int err;
if (f->f_fp == NULL)
return err_closed();
- if (!PyArg_NoArgs(args))
+ if (!PyArg_ParseTuple(args, "|l", &sizehint))
return NULL;
if ((list = PyList_New(0)) == NULL)
return NULL;
@@ -697,6 +690,7 @@ file_readlines(f, args)
nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
Py_END_ALLOW_THREADS
if (nread == 0) {
+ sizehint = 0;
if (nread == 0)
break;
PyErr_SetFromErrno(PyExc_IOError);
@@ -706,6 +700,7 @@ file_readlines(f, args)
list = NULL;
goto cleanup;
}
+ totalread += nread;
p = memchr(buffer+nfilled, '\n', nread);
if (p == NULL) {
/* Need a larger buffer to fit this line */
@@ -745,12 +740,27 @@ file_readlines(f, args)
/* Move the remaining incomplete line to the start */
nfilled = end-q;
memmove(buffer, q, nfilled);
+ if (sizehint > 0)
+ if (totalread >= (size_t)sizehint)
+ break;
}
if (nfilled != 0) {
/* Partial last line */
line = PyString_FromStringAndSize(buffer, nfilled);
if (line == NULL)
goto error;
+ if (sizehint > 0) {
+ /* Need to complete the last line */
+ PyObject *rest = getline(f, 0);
+ if (rest == NULL) {
+ Py_DECREF(line);
+ goto error;
+ }
+ PyString_Concat(&line, rest);
+ Py_DECREF(rest);
+ if (line == NULL)
+ goto error;
+ }
err = PyList_Append(list, line);
Py_DECREF(line);
if (err != 0)
@@ -833,9 +843,9 @@ static PyMethodDef file_methods[] = {
{"flush", (PyCFunction)file_flush, 0},
{"fileno", (PyCFunction)file_fileno, 0},
{"isatty", (PyCFunction)file_isatty, 0},
- {"read", (PyCFunction)file_read, 0},
- {"readline", (PyCFunction)file_readline, 0},
- {"readlines", (PyCFunction)file_readlines, 0},
+ {"read", (PyCFunction)file_read, 1},
+ {"readline", (PyCFunction)file_readline, 1},
+ {"readlines", (PyCFunction)file_readlines, 1},
{"seek", (PyCFunction)file_seek, 0},
#ifdef HAVE_FTRUNCATE
{"truncate", (PyCFunction)file_truncate, 0},