[Python-checkins] r68028 - sandbox/trunk/io-c/_textio.c
amaury.forgeotdarc
python-checkins at python.org
Mon Dec 29 22:15:04 CET 2008
Author: amaury.forgeotdarc
Date: Mon Dec 29 22:15:03 2008
New Revision: 68028
Log:
implement TextIOWrapper.seek.
This one was almost fun to translate.
Modified:
sandbox/trunk/io-c/_textio.c
Modified: sandbox/trunk/io-c/_textio.c
==============================================================================
--- sandbox/trunk/io-c/_textio.c (original)
+++ sandbox/trunk/io-c/_textio.c Mon Dec 29 22:15:03 2008
@@ -1050,7 +1050,7 @@
return 0;
}
-static int
+static PyObject *
TextIOWrapper_buildCookie(CookieStruct *cookie, PyObject *cookieObj)
{
char buffer[sizeof(CookieStruct)];
@@ -1088,7 +1088,7 @@
static PyObject *
TextIOWrapper_seek(PyTextIOWrapperObject *self, PyObject *args)
{
- PyObject *cookie;
+ PyObject *cookieObj;
int whence = 0;
static PyObject *zero = NULL;
PyObject *res;
@@ -1100,53 +1100,55 @@
return NULL;
}
- if (!PyArg_ParseTuple(args, "O|i:seek", &cookie, &whence))
+ if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
return NULL;
+ Py_INCREF(cookieObj);
if (_PyIOBase_checkClosed((PyObject *)self, NULL) == NULL)
- return NULL;
+ goto fail;
if (!self->seekable) {
- PyErr_SetString(PyExc_IOError,
+ PyErr_SetString(PyExc_IOError,
"underlying stream is not seekable");
- return NULL;
+ goto fail;
}
if (whence == 1) {
/* seek relative to current position */
- cmp = PyObject_RichCompareBool(cookie, zero, Py_EQ);
+ cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ);
if (cmp < 0)
- return NULL;
+ goto fail;
if (cmp == 0) {
- PyErr_SetString(PyExc_IOError,
+ PyErr_SetString(PyExc_IOError,
"can't do nonzero cur-relative seeks");
- return NULL;
+ goto fail;
}
/* Seeking to the current position should attempt to
* sync the underlying buffer with the current position.
*/
- whence = 0;
- Py_DECREF(cookie);
- cookie = PyObject_CallMethod((PyObject *)self, "tell", NULL);
+ Py_DECREF(cookieObj);
+ cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL);
+ if (cookieObj == NULL)
+ goto fail;
}
else if (whence == 2) {
/* seek relative to end of file */
- cmp = PyObject_RichCompareBool(cookie, zero, Py_EQ);
+ cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ);
if (cmp < 0)
- return NULL;
+ goto fail;
if (cmp == 0) {
- PyErr_SetString(PyExc_IOError,
+ PyErr_SetString(PyExc_IOError,
"can't do nonzero end-relative seeks");
- return NULL;
+ goto fail;
}
res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
if (res == NULL)
- return NULL;
+ goto fail;
Py_DECREF(res);
TextIOWrapper_set_decoded_chars(self, NULL);
@@ -1154,7 +1156,7 @@
if (self->decoder) {
res = PyObject_CallMethod(self->decoder, "reset", NULL);
if (res == NULL)
- return NULL;
+ goto fail;
Py_DECREF(res);
}
@@ -1164,58 +1166,93 @@
else if (whence != 0) {
PyErr_Format(PyExc_ValueError,
"invalid whence (%d, should be 0, 1 or 2)", whence);
- return NULL;
+ goto fail;
}
- cmp = PyObject_RichCompareBool(cookie, zero, Py_LT);
+ cmp = PyObject_RichCompareBool(cookieObj, zero, Py_LT);
if (cmp < 0)
- return NULL;
-
+ goto fail;
+
if (cmp == 1) {
PyErr_Format(PyExc_ValueError,
- "negative seek position %R", cookie);
- return NULL;
+ "negative seek position %R", cookieObj);
+ goto fail;
}
res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
if (res == NULL)
- return NULL;
+ goto fail;
Py_DECREF(res);
/* The strategy of seek() is to go back to the safe start point
* and replay the effect of read(chars_to_skip) from there.
*/
-/*
- start_pos, dec_flags, bytes_to_feed, need_eof, chars_to_skip = \
- self._unpack_cookie(cookie)
-
- # Seek back to the safe start point.
- self.buffer.seek(start_pos)
- self._set_decoded_chars('')
- self._snapshot = None
-
- # Restore the decoder to its state from the safe start point.
- if self._decoder or dec_flags or chars_to_skip:
- self._decoder = self._decoder or self._get_decoder()
- self._decoder.setstate((b'', dec_flags))
- self._snapshot = (dec_flags, b'')
-
- if chars_to_skip:
- # Just like _read_chunk, feed the decoder and save a snapshot.
- input_chunk = self.buffer.read(bytes_to_feed)
- self._set_decoded_chars(
- self._decoder.decode(input_chunk, need_eof))
- self._snapshot = (dec_flags, input_chunk)
-
- # Skip chars_to_skip of the decoded characters.
- if len(self._decoded_chars) < chars_to_skip:
- raise IOError("can't restore logical file position")
- self._decoded_chars_used = chars_to_skip
+ {
+ CookieStruct cookie;
+
+ if (TextIOWrapper_parseCookie(&cookie, cookieObj) < 0)
+ goto fail;
+
+ /* Seek back to the safe start point. */
+ res = PyObject_CallMethod(self->buffer, "seek",
+ "L", (PY_LONG_LONG)cookie.start_pos);
+ if (res == NULL)
+ goto fail;
+ Py_DECREF(res);
+
+ TextIOWrapper_set_decoded_chars(self, NULL);
+ Py_CLEAR(self->snapshot);
+
+ /* Restore the decoder to its state from the safe start point. */
+ if (self->decoder || cookie.dec_flags || cookie.chars_to_skip) {
+ res = PyObject_CallMethod(self->decoder, "setstate",
+ "((yi))", "", cookie.dec_flags);
+ if (res == NULL)
+ goto fail;
+ Py_DECREF(res);
+
+ self->snapshot = Py_BuildValue("((iy))", cookie.dec_flags, "");
+ if (self->snapshot == NULL)
+ goto fail;
+ }
+
+ if (cookie.chars_to_skip) {
+ /* Just like _read_chunk, feed the decoder and save a snapshot. */
+ PyObject *input_chunk = PyObject_CallMethod(
+ self->buffer, "read", "i", cookie.bytes_to_feed);
+ PyObject *decoded;
+
+ if (input_chunk == NULL)
+ goto fail;
+
+ self->snapshot = Py_BuildValue("((iO))", cookie.dec_flags, input_chunk);
+ if (self->snapshot == NULL) {
+ Py_DECREF(input_chunk);
+ goto fail;
+ }
+
+ decoded = PyObject_CallMethod(self->decoder, "decode",
+ "Ni", input_chunk, (int)cookie.need_eof);
+
+ if (decoded == NULL)
+ goto fail;
+
+ TextIOWrapper_set_decoded_chars(self, decoded);
+
+ /* Skip chars_to_skip of the decoded characters. */
+ if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) {
+ PyErr_SetString(PyExc_IOError, "can't restore logical file position");
+ goto fail;
+ }
+ self->decoded_chars_used = cookie.chars_to_skip;
+ }
+ }
+
+ return cookieObj;
+ fail:
+ Py_XDECREF(cookieObj);
+ return NULL;
- return cookie
-*/
-
- Py_RETURN_NONE;
}
@@ -1321,7 +1358,7 @@
{"writable", (PyCFunction)TextIOWrapper_writable, METH_NOARGS},
{"isatty", (PyCFunction)TextIOWrapper_isatty, METH_NOARGS},
-/* {"seek", (PyCFunction)TextIOWrapper_seek, METH_VARARGS},*/
+ {"seek", (PyCFunction)TextIOWrapper_seek, METH_VARARGS},
/* {"tell", (PyCFunction)TextIOWrapper_tell, METH_NOARGS},
{"truncate", (PyCFunction)TextIOWrapper_truncate, METH_VARARGS},
{"readinto", (PyCFunction)TextIOWrapper_readinto, METH_VARARGS},
More information about the Python-checkins
mailing list