diff options
author | Guido van Rossum <guido@python.org> | 2007-04-11 17:08:28 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-04-11 17:08:28 (GMT) |
commit | b5ddcfd2a203336f3ba7bb1111cda462333c9e1f (patch) | |
tree | 43ff7e83daded1ea92c4a30a948adfc500dbd3ad | |
parent | d0712817ac7139505a38613bb244a66115c24f52 (diff) | |
download | cpython-b5ddcfd2a203336f3ba7bb1111cda462333c9e1f.zip cpython-b5ddcfd2a203336f3ba7bb1111cda462333c9e1f.tar.gz cpython-b5ddcfd2a203336f3ba7bb1111cda462333c9e1f.tar.bz2 |
Make array().tofile() work with a new I/O object.
-rwxr-xr-x | Lib/test/test_array.py | 2 | ||||
-rw-r--r-- | Modules/arraymodule.c | 34 |
2 files changed, 30 insertions, 6 deletions
diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 692760c..ae7156b 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -147,7 +147,7 @@ class BaseTest(unittest.TestCase): def test_tofromfile(self): a = array.array(self.typecode, 2*self.example) self.assertRaises(TypeError, a.tofile) - self.assertRaises(TypeError, a.tofile, cStringIO.StringIO()) + ##self.assertRaises(TypeError, a.tofile, cStringIO.StringIO()) f = open(test_support.TESTFN, 'wb') try: a.tofile(f) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 3d8674c..7fe0b26 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1252,12 +1252,11 @@ array_tofile(arrayobject *self, PyObject *f) { FILE *fp; + if (self->ob_size == 0) + goto done; + fp = PyFile_AsFile(f); - if (fp == NULL) { - PyErr_SetString(PyExc_TypeError, "arg must be open file"); - return NULL; - } - if (self->ob_size > 0) { + if (fp != NULL) { if (fwrite(self->ob_item, self->ob_descr->itemsize, self->ob_size, fp) != (size_t)self->ob_size) { PyErr_SetFromErrno(PyExc_IOError); @@ -1265,6 +1264,31 @@ array_tofile(arrayobject *self, PyObject *f) return NULL; } } + else { + Py_ssize_t nbytes = self->ob_size * self->ob_descr->itemsize; + /* Write 64K blocks at a time */ + /* XXX Make the block size settable */ + int BLOCKSIZE = 64*1024; + Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE; + Py_ssize_t i; + for (i = 0; i < nblocks; i++) { + char* ptr = self->ob_item + i*BLOCKSIZE; + Py_ssize_t size = BLOCKSIZE; + PyObject *bytes, *res; + if (i*BLOCKSIZE + size > nbytes) + size = nbytes - i*BLOCKSIZE; + bytes = PyBytes_FromStringAndSize(ptr, size); + if (bytes == NULL) + return NULL; + res = PyObject_CallMethod(f, "write", "O", + bytes); + Py_DECREF(bytes); + if (res == NULL) + return NULL; + } + } + + done: Py_INCREF(Py_None); return Py_None; } |