diff Modules/cStringIO.c @ 82814:be4bec689de3 2.7

Issue #10212: Support new buffer interface for struct.unpack and cStringIO
author Kristján Valur Jónsson <sweskman@gmail.com>
date Tue, 19 Mar 2013 17:17:47 -0700
parents 680959a3ae2e
children
line wrap: on
line diff
--- a/Modules/cStringIO.c	Tue Mar 19 16:50:51 2013 -0700
+++ b/Modules/cStringIO.c	Tue Mar 19 17:17:47 2013 -0700
@@ -66,9 +66,7 @@
   PyObject_HEAD
   char *buf;
   Py_ssize_t pos, string_size;
-  /* We store a reference to the object here in order to keep
-     the buffer alive during the lifetime of the Iobject. */
-  PyObject *pbuf;
+    Py_buffer pbuf;
 } Iobject;
 
 /* IOobject (common) methods */
@@ -448,12 +446,14 @@
 
 static PyObject *
 O_write(Oobject *self, PyObject *args) {
-    char *c;
-    int l;
+    Py_buffer buf;
+    int result;
 
-    if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
+    if (!PyArg_ParseTuple(args, "s*:write", &buf)) return NULL;
 
-    if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
+    result = O_cwrite((PyObject*)self, buf.buf, buf.len);
+    PyBuffer_Release(&buf);
+    if (result < 0) return NULL;
 
     Py_INCREF(Py_None);
     return Py_None;
@@ -606,7 +606,7 @@
 
 static PyObject *
 I_close(Iobject *self, PyObject *unused) {
-    Py_CLEAR(self->pbuf);
+    PyBuffer_Release(&self->pbuf);
     self->buf = NULL;
 
     self->pos = self->string_size = 0;
@@ -635,7 +635,7 @@
 
 static void
 I_dealloc(Iobject *self) {
-  Py_XDECREF(self->pbuf);
+  PyBuffer_Release(&self->pbuf);
   PyObject_Del(self);
 }
 
@@ -680,25 +680,26 @@
 static PyObject *
 newIobject(PyObject *s) {
   Iobject *self;
-  char *buf;
-  Py_ssize_t size;
+  Py_buffer buf;
+  PyObject *args;
+  int result;
 
-  if (PyUnicode_Check(s)) {
-    if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0)
+  args = Py_BuildValue("(O)", s);
+  if (args == NULL)
+      return NULL;
+  result = PyArg_ParseTuple(args, "s*:StringIO", &buf);
+  Py_DECREF(args);
+  if (!result)
+      return NULL;
+
+  self = PyObject_New(Iobject, &Itype);
+  if (!self) {
+      PyBuffer_Release(&buf);
       return NULL;
   }
-  else if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
-    PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
-                 s->ob_type->tp_name);
-    return NULL;
-  }
-
-  self = PyObject_New(Iobject, &Itype);
-  if (!self) return NULL;
-  Py_INCREF(s);
-  self->buf=buf;
-  self->string_size=size;
-  self->pbuf=s;
+  self->buf=buf.buf;
+  self->string_size=buf.len;
+  self->pbuf=buf;
   self->pos=0;
 
   return (PyObject*)self;