summaryrefslogtreecommitdiff
path: root/Modules/cStringIO.c
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2010-10-11 19:13:04 +0000
committerFred Drake <fdrake@acm.org>2010-10-11 19:13:04 +0000
commit577acb4e30f272db9a255bbbce0a4351a1698710 (patch)
tree952223988dbc05e48bced4c34314de1e695f678f /Modules/cStringIO.c
parent5e8349e5cc42f0cbae1706cd9b6317e8dd406ee6 (diff)
downloadcpython-git-577acb4e30f272db9a255bbbce0a4351a1698710.tar.gz
improve performance of writing past the end of the file for cStringIO
(http://bugs.python.org/issue10045)
Diffstat (limited to 'Modules/cStringIO.c')
-rw-r--r--Modules/cStringIO.c58
1 files changed, 18 insertions, 40 deletions
diff --git a/Modules/cStringIO.c b/Modules/cStringIO.c
index 6aa3d5d861..be9ad50ab6 100644
--- a/Modules/cStringIO.c
+++ b/Modules/cStringIO.c
@@ -339,12 +339,12 @@ IO_iternext(Iobject *self)
/* Read-write object methods */
-PyDoc_STRVAR(O_seek__doc__,
+PyDoc_STRVAR(IO_seek__doc__,
"seek(position) -- set the current position\n"
"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
static PyObject *
-O_seek(Oobject *self, PyObject *args) {
+IO_seek(Iobject *self, PyObject *args) {
Py_ssize_t position;
int mode = 0;
@@ -359,25 +359,10 @@ O_seek(Oobject *self, PyObject *args) {
position += self->pos;
}
- if (position > self->buf_size) {
- char *newbuf;
- self->buf_size*=2;
- if (self->buf_size <= position) self->buf_size=position+1;
- newbuf = (char*) realloc(self->buf,self->buf_size);
- if (!newbuf) {
- free(self->buf);
- self->buf = 0;
- self->buf_size=self->pos=0;
- return PyErr_NoMemory();
- }
- self->buf = newbuf;
- }
- else if (position < 0) position=0;
+ if (position < 0) position=0;
self->pos=position;
- while (--position >= self->string_size) self->buf[position]=0;
-
Py_INCREF(Py_None);
return Py_None;
}
@@ -414,6 +399,19 @@ O_cwrite(PyObject *self, const char *c, Py_ssize_t l) {
oself->buf = newbuf;
}
+ if (oself->string_size < oself->pos) {
+ /* 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
+ */
+ memset(oself->buf + oself->string_size, '\0',
+ (oself->pos - oself->string_size) * sizeof(char));
+ }
+
memcpy(oself->buf+oself->pos,c,l);
assert(oself->pos + l < INT_MAX);
@@ -497,12 +495,12 @@ static struct PyMethodDef O_methods[] = {
{"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
{"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
{"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
+ {"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
{"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
{"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
/* Read-write StringIO specific methods: */
{"close", (PyCFunction)O_close, METH_NOARGS, O_close__doc__},
- {"seek", (PyCFunction)O_seek, METH_VARARGS, O_seek__doc__},
{"write", (PyCFunction)O_write, METH_VARARGS, O_write__doc__},
{"writelines", (PyCFunction)O_writelines, METH_O, O_writelines__doc__},
{NULL, NULL} /* sentinel */
@@ -595,26 +593,6 @@ I_close(Iobject *self, PyObject *unused) {
return Py_None;
}
-static PyObject *
-I_seek(Iobject *self, PyObject *args) {
- Py_ssize_t position;
- int mode = 0;
-
- if (!IO__opencheck(IOOOBJECT(self))) return NULL;
- if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode))
- return NULL;
-
- if (mode == 2) position += self->string_size;
- else if (mode == 1) position += self->pos;
-
- if (position < 0) position=0;
-
- self->pos=position;
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
static struct PyMethodDef I_methods[] = {
/* Common methods: */
{"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__},
@@ -624,12 +602,12 @@ static struct PyMethodDef I_methods[] = {
{"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
{"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
{"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
+ {"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
{"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
{"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
/* Read-only StringIO specific methods: */
{"close", (PyCFunction)I_close, METH_NOARGS, O_close__doc__},
- {"seek", (PyCFunction)I_seek, METH_VARARGS, O_seek__doc__},
{NULL, NULL}
};