@@ -1196,53 +1196,54 @@ PyDoc_STRVAR(reverse_doc,
11961196\n\
11971197Reverse the order of the items in the array." );
11981198
1199+
1200+ /* Forward */
1201+ static PyObject * array_fromstring (arrayobject * self , PyObject * args );
1202+
11991203static PyObject *
12001204array_fromfile (arrayobject * self , PyObject * args )
12011205{
1202- PyObject * f ;
1203- Py_ssize_t n ;
1204- FILE * fp ;
1206+ PyObject * f , * b , * res ;
1207+ Py_ssize_t itemsize = self -> ob_descr -> itemsize ;
1208+ Py_ssize_t n , nbytes ;
1209+
12051210 if (!PyArg_ParseTuple (args , "On:fromfile" , & f , & n ))
12061211 return NULL ;
1207- fp = PyFile_AsFile (f );
1208- if (fp == NULL ) {
1209- PyErr_SetString (PyExc_TypeError , "arg1 must be open file" );
1212+
1213+ nbytes = n * itemsize ;
1214+ if (nbytes < 0 || nbytes /itemsize != n ) {
1215+ PyErr_NoMemory ();
12101216 return NULL ;
12111217 }
1212- if (n > 0 ) {
1213- char * item = self -> ob_item ;
1214- Py_ssize_t itemsize = self -> ob_descr -> itemsize ;
1215- size_t nread ;
1216- Py_ssize_t newlength ;
1217- size_t newbytes ;
1218- /* Be careful here about overflow */
1219- if ((newlength = self -> ob_size + n ) <= 0 ||
1220- (newbytes = newlength * itemsize ) / itemsize !=
1221- (size_t )newlength )
1222- goto nomem ;
1223- PyMem_RESIZE (item , char , newbytes );
1224- if (item == NULL ) {
1225- nomem :
1226- PyErr_NoMemory ();
1227- return NULL ;
1228- }
1229- self -> ob_item = item ;
1230- self -> ob_size += n ;
1231- self -> allocated = self -> ob_size ;
1232- nread = fread (item + (self -> ob_size - n ) * itemsize ,
1233- itemsize , n , fp );
1234- if (nread < (size_t )n ) {
1235- self -> ob_size -= (n - nread );
1236- PyMem_RESIZE (item , char , self -> ob_size * itemsize );
1237- self -> ob_item = item ;
1238- self -> allocated = self -> ob_size ;
1239- PyErr_SetString (PyExc_EOFError ,
1240- "not enough items in file" );
1241- return NULL ;
1242- }
1218+
1219+ b = PyObject_CallMethod (f , "read" , "n" , nbytes );
1220+ if (b == NULL )
1221+ return NULL ;
1222+
1223+ if (!PyBytes_Check (b )) {
1224+ PyErr_SetString (PyExc_TypeError ,
1225+ "read() didn't return bytes" );
1226+ Py_DECREF (b );
1227+ return NULL ;
12431228 }
1244- Py_INCREF (Py_None );
1245- return Py_None ;
1229+
1230+ if (PyBytes_GET_SIZE (b ) != nbytes ) {
1231+ printf ("nbytes = %d, len(b) == %d\n" , nbytes , PyBytes_GET_SIZE (b ));
1232+ PyErr_SetString (PyExc_EOFError ,
1233+ "read() didn't return enough bytes" );
1234+ Py_DECREF (b );
1235+ return NULL ;
1236+ }
1237+
1238+ args = Py_BuildValue ("(O)" , b );
1239+ Py_DECREF (b );
1240+ if (args == NULL )
1241+ return NULL ;
1242+
1243+ res = array_fromstring (self , args );
1244+ Py_DECREF (args );
1245+
1246+ return res ;
12461247}
12471248
12481249PyDoc_STRVAR (fromfile_doc ,
@@ -1255,42 +1256,29 @@ array. Also called as read.");
12551256static PyObject *
12561257array_tofile (arrayobject * self , PyObject * f )
12571258{
1258- FILE * fp ;
1259+ Py_ssize_t nbytes = self -> ob_size * self -> ob_descr -> itemsize ;
1260+ /* Write 64K blocks at a time */
1261+ /* XXX Make the block size settable */
1262+ int BLOCKSIZE = 64 * 1024 ;
1263+ Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1 ) / BLOCKSIZE ;
1264+ Py_ssize_t i ;
12591265
12601266 if (self -> ob_size == 0 )
12611267 goto done ;
12621268
1263- fp = PyFile_AsFile (f );
1264- if (fp != NULL ) {
1265- if (fwrite (self -> ob_item , self -> ob_descr -> itemsize ,
1266- self -> ob_size , fp ) != (size_t )self -> ob_size ) {
1267- PyErr_SetFromErrno (PyExc_IOError );
1268- clearerr (fp );
1269+ for (i = 0 ; i < nblocks ; i ++ ) {
1270+ char * ptr = self -> ob_item + i * BLOCKSIZE ;
1271+ Py_ssize_t size = BLOCKSIZE ;
1272+ PyObject * bytes , * res ;
1273+ if (i * BLOCKSIZE + size > nbytes )
1274+ size = nbytes - i * BLOCKSIZE ;
1275+ bytes = PyBytes_FromStringAndSize (ptr , size );
1276+ if (bytes == NULL )
1277+ return NULL ;
1278+ res = PyObject_CallMethod (f , "write" , "O" , bytes );
1279+ Py_DECREF (bytes );
1280+ if (res == NULL )
12691281 return NULL ;
1270- }
1271- }
1272- else {
1273- Py_ssize_t nbytes = self -> ob_size * self -> ob_descr -> itemsize ;
1274- /* Write 64K blocks at a time */
1275- /* XXX Make the block size settable */
1276- int BLOCKSIZE = 64 * 1024 ;
1277- Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1 ) / BLOCKSIZE ;
1278- Py_ssize_t i ;
1279- for (i = 0 ; i < nblocks ; i ++ ) {
1280- char * ptr = self -> ob_item + i * BLOCKSIZE ;
1281- Py_ssize_t size = BLOCKSIZE ;
1282- PyObject * bytes , * res ;
1283- if (i * BLOCKSIZE + size > nbytes )
1284- size = nbytes - i * BLOCKSIZE ;
1285- bytes = PyBytes_FromStringAndSize (ptr , size );
1286- if (bytes == NULL )
1287- return NULL ;
1288- res = PyObject_CallMethod (f , "write" , "O" ,
1289- bytes );
1290- Py_DECREF (bytes );
1291- if (res == NULL )
1292- return NULL ;
1293- }
12941282 }
12951283
12961284 done :
@@ -1349,7 +1337,6 @@ PyDoc_STRVAR(fromlist_doc,
13491337\n\
13501338Append items to array from list." );
13511339
1352-
13531340static PyObject *
13541341array_tolist (arrayobject * self , PyObject * unused )
13551342{
0 commit comments