[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

AltStyle によって変換されたページ (->オリジナル) /