[Python-checkins] r68531 - in sandbox/trunk/io-c: _iomodule.h _textio.c io.c
antoine.pitrou
python-checkins at python.org
Sun Jan 11 14:53:36 CET 2009
Author: antoine.pitrou
Date: Sun Jan 11 14:53:36 2009
New Revision: 68531
Log:
Use joining instead of appending in TextIOWrapper.read(), and a few
micro-optimizations.
Modified:
sandbox/trunk/io-c/_iomodule.h
sandbox/trunk/io-c/_textio.c
sandbox/trunk/io-c/io.c
Modified: sandbox/trunk/io-c/_iomodule.h
==============================================================================
--- sandbox/trunk/io-c/_iomodule.h (original)
+++ sandbox/trunk/io-c/_iomodule.h Sun Jan 11 14:53:36 2009
@@ -64,6 +64,7 @@
extern PyObject *_PyIO_str_isatty;
extern PyObject *_PyIO_str_newlines;
extern PyObject *_PyIO_str_read;
+extern PyObject *_PyIO_str_read1;
extern PyObject *_PyIO_str_readable;
extern PyObject *_PyIO_str_readinto;
extern PyObject *_PyIO_str_readline;
Modified: sandbox/trunk/io-c/_textio.c
==============================================================================
--- sandbox/trunk/io-c/_textio.c (original)
+++ sandbox/trunk/io-c/_textio.c Sun Jan 11 14:53:36 2009
@@ -106,18 +106,12 @@
#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF)
static PyObject *
-IncrementalNewlineDecoder_decode(PyNewLineDecoderObject *self,
- PyObject *args, PyObject *kwds)
+_IncrementalNewlineDecoder_decode(PyNewLineDecoderObject *self,
+ PyObject *input, int final)
{
- char *kwlist[] = {"input", "final", NULL};
- PyObject *input, *output;
- int final = 0;
+ PyObject *output;
Py_ssize_t output_len;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder",
- kwlist, &input, &final))
- return NULL;
-
if (self->decoder == NULL) {
PyErr_SetString(PyExc_ValueError,
"IncrementalNewlineDecoder.__init__ not called");
@@ -296,6 +290,20 @@
}
static PyObject *
+IncrementalNewlineDecoder_decode(PyNewLineDecoderObject *self,
+ PyObject *args, PyObject *kwds)
+{
+ char *kwlist[] = {"input", "final", NULL};
+ PyObject *input;
+ int final = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder",
+ kwlist, &input, &final))
+ return NULL;
+ return _IncrementalNewlineDecoder_decode(self, input, final);
+}
+
+static PyObject *
IncrementalNewlineDecoder_getstate(PyNewLineDecoderObject *self, PyObject *args)
{
PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
@@ -800,11 +808,17 @@
if (n < 0 || n > avail)
n = avail;
- chars = PyUnicode_FromUnicode(
- PyUnicode_AS_UNICODE(self->decoded_chars)
- + self->decoded_chars_used, n);
- if (chars == NULL)
- return NULL;
+ if (self->decoded_chars_used > 0 || n < avail) {
+ chars = PyUnicode_FromUnicode(
+ PyUnicode_AS_UNICODE(self->decoded_chars)
+ + self->decoded_chars_used, n);
+ if (chars == NULL)
+ return NULL;
+ }
+ else {
+ chars = self->decoded_chars;
+ Py_INCREF(chars);
+ }
self->decoded_chars_used += n;
return chars;
@@ -839,7 +853,8 @@
{
PyObject *dec_buffer = NULL;
PyObject *dec_flags = NULL;
- PyObject *input_chunk, *decoded_chars;
+ PyObject *input_chunk = NULL;
+ PyObject *decoded_chars, *chunk_size;
int eof;
/* The return value is True unless EOF was reached. The decoded string is
@@ -875,16 +890,26 @@
}
/* Read a chunk, decode it, and put the result in self._decoded_chars. */
- input_chunk = PyObject_CallMethod(self->buffer, "read1",
- "n", self->chunk_size);
+ chunk_size = PyLong_FromSsize_t(self->chunk_size);
+ if (chunk_size == NULL)
+ goto fail;
+ input_chunk = PyObject_CallMethodObjArgs(self->buffer,
+ _PyIO_str_read1, chunk_size, NULL);
+ Py_DECREF(chunk_size);
if (input_chunk == NULL)
goto fail;
assert(PyBytes_Check(input_chunk));
eof = (PyBytes_Size(input_chunk) == 0);
- decoded_chars = PyObject_CallMethod(self->decoder, "decode",
- "Oi", input_chunk, eof);
+ if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
+ decoded_chars = _IncrementalNewlineDecoder_decode(
+ (PyNewLineDecoderObject *) self->decoder, input_chunk, eof);
+ }
+ else {
+ decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
+ _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
+ }
/* TODO sanity check: isinstance(decoded_chars, unicode) */
if (decoded_chars == NULL)
@@ -914,15 +939,13 @@
Py_XDECREF(dec_flags);
Py_XDECREF(input_chunk);
return -1;
-
}
-
static PyObject *
TextIOWrapper_read(PyTextIOWrapperObject *self, PyObject *args)
{
Py_ssize_t n = -1;
- PyObject *result;
+ PyObject *result = NULL, *chunks = NULL;
CHECK_INITIALIZED(self);
@@ -937,8 +960,8 @@
PyObject *decoded;
if (bytes == NULL)
goto fail;
- decoded = PyObject_CallMethod(self->decoder, "decode",
- "Oi", bytes, /*final=*/1);
+ decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode,
+ bytes, Py_True, NULL);
Py_DECREF(bytes);
if (decoded == NULL)
goto fail;
@@ -959,28 +982,48 @@
}
else {
int res = 1;
+ Py_ssize_t remaining = n;
+
result = TextIOWrapper_get_decoded_chars(self, n);
+ if (result == NULL)
+ goto fail;
+ remaining -= PyUnicode_GET_SIZE(result);
/* Keep reading chunks until we have n characters to return */
- while (res == 1) {
- if (result == NULL || Py_SIZE(result) >= n) {
- break;
- }
+ while (remaining > 0) {
res = TextIOWrapper_read_chunk(self);
- if (res < 0) {
- Py_DECREF(result);
+ if (res < 0)
goto fail;
+ if (res == 0) /* EOF */
+ break;
+ if (chunks == NULL) {
+ chunks = PyList_New(0);
+ if (chunks == NULL)
+ goto fail;
}
-
- PyUnicode_AppendAndDel(&result,
- TextIOWrapper_get_decoded_chars(
- self, n - Py_SIZE(result)));
+ if (PyList_Append(chunks, result) < 0)
+ goto fail;
+ Py_DECREF(result);
+ result = TextIOWrapper_get_decoded_chars(self, remaining);
+ if (result == NULL)
+ goto fail;
+ remaining -= PyUnicode_GET_SIZE(result);
+ }
+ if (chunks != NULL) {
+ if (result != NULL && PyList_Append(chunks, result) < 0)
+ goto fail;
+ Py_CLEAR(result);
+ result = PyUnicode_Join(PyUnicode_FromStringAndSize(NULL, 0),
+ chunks);
if (result == NULL)
goto fail;
+ Py_CLEAR(chunks);
}
return result;
}
fail:
+ Py_XDECREF(result);
+ Py_XDECREF(chunks);
return NULL;
}
Modified: sandbox/trunk/io-c/io.c
==============================================================================
--- sandbox/trunk/io-c/io.c (original)
+++ sandbox/trunk/io-c/io.c Sun Jan 11 14:53:36 2009
@@ -24,6 +24,7 @@
PyObject *_PyIO_str_isatty;
PyObject *_PyIO_str_newlines;
PyObject *_PyIO_str_read;
+PyObject *_PyIO_str_read1;
PyObject *_PyIO_str_readable;
PyObject *_PyIO_str_readinto;
PyObject *_PyIO_str_readline;
@@ -649,6 +650,8 @@
goto fail;
if (!(_PyIO_str_read = PyUnicode_InternFromString("read")))
goto fail;
+ if (!(_PyIO_str_read1 = PyUnicode_InternFromString("read1")))
+ goto fail;
if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable")))
goto fail;
if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto")))
More information about the Python-checkins
mailing list