summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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},