[Python-checkins] r68050 - in sandbox/trunk/io-c: _bufferedio.c _iomodule.h io.c

antoine.pitrou python-checkins at python.org
Tue Dec 30 02:11:23 CET 2008


Author: antoine.pitrou
Date: Tue Dec 30 02:11:23 2008
New Revision: 68050

Log:
More interned strings + some basic checks.



Modified:
   sandbox/trunk/io-c/_bufferedio.c
   sandbox/trunk/io-c/_iomodule.h
   sandbox/trunk/io-c/io.c

Modified: sandbox/trunk/io-c/_bufferedio.c
==============================================================================
--- sandbox/trunk/io-c/_bufferedio.c	(original)
+++ sandbox/trunk/io-c/_bufferedio.c	Tue Dec 30 02:11:23 2008
@@ -107,6 +107,7 @@
     PyObject_HEAD
 
     PyObject *raw;
+    int ok;    /* Initialized? */
 
     PyObject *read_buf;
     Py_ssize_t read_pos;
@@ -121,7 +122,9 @@
     PyThread_type_lock write_lock;
 
     Py_ssize_t buffer_size;
-    Py_ssize_t max_buffer_size;
+    /* Still unused, but will help us align reads and writes on block
+       boundaries if desireable */
+    Py_ssize_t buffer_mask;
 
     PyObject *dict;
     PyObject *weakreflist;
@@ -145,6 +148,12 @@
 #define LEAVE_BUFFERED_WRITER(self) \
     PyThread_release_lock(self->write_lock);
 
+#define CHECK_INITIALIZED(self) \
+    if (self->ok <= 0) { \
+        PyErr_SetString(PyExc_ValueError, \
+            "I/O operation on uninitialized object"); \
+        return NULL; \
+    }
 
 static void
 BufferedObject_dealloc(BufferedObject *self)
@@ -163,7 +172,7 @@
     }
     if (self->write_lock) {
         PyThread_free_lock(self->write_lock);
-        self->read_lock = NULL;
+        self->write_lock = NULL;
     }
     Py_CLEAR(self->dict);
 }
@@ -183,6 +192,7 @@
     PyObject *pos = Py_None;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
         return NULL;
     }
@@ -215,6 +225,7 @@
 static PyObject *
 BufferedIOMixin_flush(BufferedObject *self, PyObject *args)
 {
+    CHECK_INITIALIZED(self)
     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
 }
 
@@ -222,7 +233,9 @@
 BufferedIOMixin_closed(BufferedObject *self)
 {
     int closed;
-    PyObject *res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
+    PyObject *res;
+    CHECK_INITIALIZED(self)
+    res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
     if (res == NULL)
         return -1;
     closed = PyObject_IsTrue(res);
@@ -233,7 +246,8 @@
 static PyObject *
 BufferedIOMixin_closed_get(BufferedObject *self, void *context)
 {
-    return PyObject_GetAttrString(self->raw, "closed");
+    CHECK_INITIALIZED(self)
+    return PyObject_GetAttr(self->raw, _PyIO_str_closed);
 }
 
 static PyObject *
@@ -241,6 +255,7 @@
 {
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (BufferedIOMixin_closed(self))
         Py_RETURN_NONE;
 
@@ -261,30 +276,35 @@
 static PyObject *
 BufferedIOMixin_seekable(BufferedObject *self, PyObject *args)
 {
-    return PyObject_CallMethod(self->raw, "seekable", NULL);
+    CHECK_INITIALIZED(self)
+    return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
 }
 
 static PyObject *
 BufferedIOMixin_readable(BufferedObject *self, PyObject *args)
 {
-    return PyObject_CallMethod(self->raw, "readable", NULL);
+    CHECK_INITIALIZED(self)
+    return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
 }
 
 static PyObject *
 BufferedIOMixin_writable(BufferedObject *self, PyObject *args)
 {
-    return PyObject_CallMethod(self->raw, "writable", NULL);
+    CHECK_INITIALIZED(self)
+    return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
 }
 
 static PyObject *
 BufferedIOMixin_name_get(BufferedObject *self, void *context)
 {
+    CHECK_INITIALIZED(self)
     return PyObject_GetAttrString(self->raw, "name");
 }
 
 static PyObject *
 BufferedIOMixin_mode_get(BufferedObject *self, void *context)
 {
+    CHECK_INITIALIZED(self)
     return PyObject_GetAttrString(self->raw, "mode");
 }
 
@@ -293,15 +313,35 @@
 static PyObject *
 BufferedIOMixin_fileno(BufferedObject *self, PyObject *args)
 {
+    CHECK_INITIALIZED(self)
     return PyObject_CallMethod(self->raw, "fileno", NULL);
 }
 
 static PyObject *
 BufferedIOMixin_isatty(BufferedObject *self, PyObject *args)
 {
+    CHECK_INITIALIZED(self)
     return PyObject_CallMethod(self->raw, "isatty", NULL);
 }
 
+static int
+_BufferedIOMixin_init(BufferedObject *self)
+{
+    Py_ssize_t n;
+    if (self->buffer_size <= 0) {
+        PyErr_SetString(PyExc_ValueError,
+            "buffer size must be strictly positive");
+        return -1;
+    }
+    /* Find out whether buffer_size is a power of 2 */
+    for (n = self->buffer_size - 1; n & 1; n >>= 1)
+        ;
+    if (n == 0)
+        self->buffer_mask = self->buffer_size - 1;
+    else
+        self->buffer_mask = 0;
+    return 0;
+}
 
 /*
  * class BufferedReader
@@ -332,6 +372,8 @@
     Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
     PyObject *raw;
 
+    self->ok = 0;
+
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
                                      &raw, &buffer_size)) {
         return -1;
@@ -340,12 +382,15 @@
     if (_PyIOBase_checkReadable(raw, NULL) == NULL)
         return -1;
 
+    Py_CLEAR(self->raw);
     Py_INCREF(raw);
     self->raw = raw;
 
     self->buffer_size = buffer_size;
     self->read_buf = NULL;
 
+    if (_BufferedIOMixin_init(self) < 0)
+        return -1;
     if (_BufferedReader_reset_buf(self) < 0)
         return -1;
 
@@ -355,6 +400,7 @@
         return -1;
     }
 
+    self->ok = 1;
     return 0;
 }
 
@@ -548,6 +594,7 @@
     Py_ssize_t n = -1;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "|n:read", &n)) {
         return NULL;
     }
@@ -616,6 +663,7 @@
     Py_ssize_t n = 0;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
         return NULL;
     }
@@ -635,6 +683,7 @@
     Py_ssize_t n, have;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "n:read1", &n)) {
         return NULL;
     }
@@ -667,6 +716,7 @@
     int whence = 0;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &whence)) {
         return NULL;
     }
@@ -694,6 +744,7 @@
 {
     PyObject *op1, *op2, *res;
 
+    CHECK_INITIALIZED(self)
     op1 = PyObject_CallMethod(self->raw, "tell", NULL);
 
     if (op1 == NULL)
@@ -793,8 +844,7 @@
     "\n"
     "The constructor creates a BufferedWriter for the given writeable raw\n"
     "stream. If the buffer_size is not given, it defaults to\n"
-    "DEAFULT_BUFFER_SIZE. If max_buffer_size is omitted, it defaults to\n"
-    "twice the buffer size.\n"
+    "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
     );
 
 static int
@@ -808,12 +858,14 @@
 static int
 BufferedWriter_init(BufferedObject *self, PyObject *args, PyObject *kwds)
 {
-    /* TODO: max_buffer_size is unused, remove it */
+    /* TODO: properly deprecate max_buffer_size */
     char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
     Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
     Py_ssize_t max_buffer_size = -1;
     PyObject *raw;
 
+    self->ok = 0;
+
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
                                      &raw, &buffer_size, &max_buffer_size)) {
         return -1;
@@ -822,20 +874,21 @@
     if (_PyIOBase_checkWritable(raw, NULL) == NULL)
         return -1;
 
+    Py_CLEAR(self->raw);
     Py_INCREF(raw);
     self->raw = raw;
 
-    if (max_buffer_size < 0)
-        max_buffer_size = buffer_size * 2;
     self->buffer_size = buffer_size;
-    self->max_buffer_size = max_buffer_size;
 
-    Py_CLEAR(self->write_buf);
+    if (self->write_buf)
+        PyMem_Free(self->write_buf);
     self->write_buf = PyMem_Malloc(self->buffer_size);
     if (self->write_buf == NULL) {
         PyErr_NoMemory();
         return -1;
     }
+    if (_BufferedIOMixin_init(self) < 0)
+        return -1;
     if (_BufferedWriter_reset_buf(self) < 0)
         return -1;
 
@@ -845,6 +898,7 @@
         return -1;
     }
 
+    self->ok = 1;
     return 0;
 }
 
@@ -896,8 +950,6 @@
     PyObject *res = NULL;
 
     while (self->write_pos < self->write_end) {
-        /* Export a buffer of write_buf[write_pos:write_end].
-           NOTE: the buffer needn't be released as its object is NULL. */
         n = _BufferedWriter_raw_write(self,
             self->write_buf + self->write_pos,
             self->write_end - self->write_pos);
@@ -932,7 +984,7 @@
     Py_buffer buf;
     Py_ssize_t written, avail, remaining, n;
 
-    /* TODO: check everywhere that write_buf is allocated */
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
         return NULL;
     }
@@ -1034,6 +1086,7 @@
     PyObject *pos = NULL;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
         return NULL;
     }
@@ -1064,6 +1117,7 @@
 {
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (BufferedIOMixin_closed(self)) {
         PyErr_SetString(PyExc_ValueError, "flush of closed file");
         return NULL;
@@ -1083,6 +1137,7 @@
 {
     PyObject *op1, *op2, *res;
 
+    CHECK_INITIALIZED(self)
     op1 = PyObject_CallMethod(self->raw, "tell", NULL);
     op2 = PyLong_FromSsize_t(self->write_end - self->write_pos);
     if (op2 == NULL) {
@@ -1103,6 +1158,7 @@
     int whence = 0;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &whence)) {
         return NULL;
     }
@@ -1429,8 +1485,7 @@
     "\n"
     "The constructor creates a reader and writer for a seekable stream,\n"
     "raw, given in the first argument. If the buffer_size is omitted it\n"
-    "defaults to DEFAULT_BUFFER_SIZE. The max_buffer_size (for the buffered\n"
-    "writer) defaults to twice the buffer size.\n"
+    "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
     );
 
 static int
@@ -1441,6 +1496,8 @@
     Py_ssize_t max_buffer_size = -1;
     PyObject *raw;
 
+    self->ok = 0;
+
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
                                      &raw, &buffer_size, &max_buffer_size)) {
         return -1;
@@ -1456,10 +1513,7 @@
     Py_INCREF(raw);
     self->raw = raw;
 
-    if (max_buffer_size < 0)
-        max_buffer_size = buffer_size * 2;
     self->buffer_size = buffer_size;
-    self->max_buffer_size = max_buffer_size;
 
     if( _BufferedReader_reset_buf(self) < 0)
         return -1;
@@ -1476,6 +1530,8 @@
         PyErr_NoMemory();
         return -1;
     }
+    if (_BufferedIOMixin_init(self) < 0)
+        return -1;
     if (_BufferedWriter_reset_buf(self) < 0)
         return -1;
 
@@ -1485,12 +1541,14 @@
         return -1;
     }
 
+    self->ok = 1;
     return 0;
 }
 
 static PyObject *
 BufferedRandom_tell(BufferedObject *self, PyObject *args)
 {
+    CHECK_INITIALIZED(self)
     if (self->write_end > self->write_pos)
         return BufferedWriter_tell(self, args);
     else
@@ -1504,6 +1562,7 @@
     int whence = 0;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &whence)) {
         return NULL;
     }
@@ -1536,6 +1595,7 @@
     PyObject *pos = Py_None;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
         return NULL;
     }
@@ -1567,6 +1627,7 @@
     Py_ssize_t n = -1;
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     if (!PyArg_ParseTuple(args, "|n:read", &n)) {
         return NULL;
     }
@@ -1583,6 +1644,7 @@
 {
     PyObject *res;
 
+    CHECK_INITIALIZED(self)
     res = BufferedWriter_flush(self, Py_None);
     if (res == NULL)
         return NULL;
@@ -1594,7 +1656,9 @@
 static PyObject *
 BufferedRandom_peek(BufferedObject *self, PyObject *args)
 {
-    PyObject *res = BufferedWriter_flush(self, Py_None);
+    PyObject *res;
+    CHECK_INITIALIZED(self)
+    res = BufferedWriter_flush(self, Py_None);
     if (res == NULL)
         return NULL;
     Py_DECREF(res);
@@ -1605,7 +1669,9 @@
 static PyObject *
 BufferedRandom_read1(BufferedObject *self, PyObject *args)
 {
-    PyObject *res = BufferedWriter_flush(self, Py_None);
+    PyObject *res;
+    CHECK_INITIALIZED(self)
+    res = BufferedWriter_flush(self, Py_None);
     if (res == NULL)
         return NULL;
     Py_DECREF(res);
@@ -1616,6 +1682,7 @@
 static PyObject *
 BufferedRandom_write(BufferedObject *self, PyObject *args)
 {
+    CHECK_INITIALIZED(self)
     if (Py_SIZE(self->read_buf) > 0) {
         PyObject *res;
         /* Undo readahead */

Modified: sandbox/trunk/io-c/_iomodule.h
==============================================================================
--- sandbox/trunk/io-c/_iomodule.h	(original)
+++ sandbox/trunk/io-c/_iomodule.h	Tue Dec 30 02:11:23 2008
@@ -53,4 +53,7 @@
 extern PyObject *_PyIO_str_closed;
 extern PyObject *_PyIO_str_flush;
 extern PyObject *_PyIO_str_read;
+extern PyObject *_PyIO_str_readable;
+extern PyObject *_PyIO_str_seekable;
+extern PyObject *_PyIO_str_writable;
 extern PyObject *_PyIO_str_write;

Modified: sandbox/trunk/io-c/io.c
==============================================================================
--- sandbox/trunk/io-c/io.c	(original)
+++ sandbox/trunk/io-c/io.c	Tue Dec 30 02:11:23 2008
@@ -9,6 +9,9 @@
 PyObject *_PyIO_str_closed;
 PyObject *_PyIO_str_flush;
 PyObject *_PyIO_str_read;
+PyObject *_PyIO_str_readable;
+PyObject *_PyIO_str_seekable;
+PyObject *_PyIO_str_writable;
 PyObject *_PyIO_str_write;
 
 
@@ -613,8 +616,14 @@
         goto fail;
     if (!(_PyIO_str_read = PyUnicode_InternFromString("read")))
         goto fail;
+    if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable")))
+        goto fail;
+    if (!(_PyIO_str_seekable = PyUnicode_InternFromString("seekable")))
+        goto fail;
     if (!(_PyIO_str_write = PyUnicode_InternFromString("write")))
         goto fail;
+    if (!(_PyIO_str_writable = PyUnicode_InternFromString("writable")))
+        goto fail;
 
     return m;
 


More information about the Python-checkins mailing list