@@ -83,11 +83,8 @@ typedef struct {
8383 PyObject_HEAD
8484 PyObject * info ;
8585 FILE * logfp ;
86- int filled ;
87- int index ;
8886 int linetimings ;
8987 int frametimings ;
90- unsigned char buffer [BUFFERSIZE ];
9188} LogReaderObject ;
9289
9390static PyObject * ProfilerError = NULL ;
@@ -272,25 +269,21 @@ logreader_tp_iter(LogReaderObject *self)
272269static int
273270unpack_packed_int (LogReaderObject * self , int * pvalue , int discard )
274271{
272+ int c ;
275273 int accum = 0 ;
276274 int bits = 0 ;
277- int index = self -> index ;
278275 int cont ;
279276
280277 do {
281- if (index >= self -> filled )
282- return ERR_EOF ;
283278 /* read byte */
284- accum |= ((self -> buffer [index ] & 0x7F ) >> discard ) << bits ;
279+ if ((c = fgetc (self -> logfp )) == EOF )
280+ return ERR_EOF ;
281+ accum |= ((c & 0x7F ) >> discard ) << bits ;
285282 bits += (7 - discard );
286- cont = self -> buffer [index ] & 0x80 ;
287- /* move to next */
283+ cont = c & 0x80 ;
288284 discard = 0 ;
289- index ++ ;
290285 } while (cont );
291286
292- /* save state */
293- self -> index = index ;
294287 * pvalue = accum ;
295288
296289 return 0 ;
@@ -302,43 +295,37 @@ unpack_packed_int(LogReaderObject *self, int *pvalue, int discard)
302295static int
303296unpack_string (LogReaderObject * self , PyObject * * pvalue )
304297{
298+ int i ;
305299 int len ;
306- int oldindex = self -> index ;
307- int err = unpack_packed_int (self , & len , 0 );
308-
309- if (!err ) {
310- /* need at least len bytes in buffer */
311- if (len > (self -> filled - self -> index )) {
312- self -> index = oldindex ;
313- err = ERR_EOF ;
314- }
315- else {
316- * pvalue = PyString_FromStringAndSize ((char * )self -> buffer + self -> index ,
317- len );
318- if (* pvalue == NULL ) {
319- self -> index = oldindex ;
320- err = ERR_EXCEPTION ;
321- }
322- else
323- self -> index += len ;
300+ int err ;
301+ char * buf ;
302+
303+ if ((err = unpack_packed_int (self , & len , 0 )))
304+ return err ;
305+
306+ buf = malloc (len );
307+ for (i = 0 ; i < len ; i ++ ) {
308+ if ((buf [i ] = fgetc (self -> logfp )) == EOF ) {
309+ free (buf );
310+ return ERR_EOF ;
324311 }
325312 }
326- return err ;
313+ * pvalue = PyString_FromStringAndSize (buf , len );
314+ free (buf );
315+ if (* pvalue == NULL ) {
316+ return ERR_EXCEPTION ;
317+ }
318+ return 0 ;
327319}
328320
329321
330322static int
331- unpack_add_info (LogReaderObject * self , int skip_opcode )
323+ unpack_add_info (LogReaderObject * self )
332324{
333325 PyObject * key ;
334326 PyObject * value = NULL ;
335327 int err ;
336328
337- if (skip_opcode ) {
338- if (self -> buffer [self -> index ] != WHAT_ADD_INFO )
339- return ERR_BAD_RECTYPE ;
340- self -> index ++ ;
341- }
342329 err = unpack_string (self , & key );
343330 if (!err ) {
344331 err = unpack_string (self , & value );
@@ -368,25 +355,6 @@ unpack_add_info(LogReaderObject *self, int skip_opcode)
368355}
369356
370357
371- static void
372- logreader_refill (LogReaderObject * self )
373- {
374- int needed ;
375- size_t res ;
376-
377- if (self -> index ) {
378- memmove (self -> buffer , & self -> buffer [self -> index ],
379- self -> filled - self -> index );
380- self -> filled = self -> filled - self -> index ;
381- self -> index = 0 ;
382- }
383- needed = BUFFERSIZE - self -> filled ;
384- if (needed > 0 ) {
385- res = fread (& self -> buffer [self -> filled ], 1 , needed , self -> logfp );
386- self -> filled += res ;
387- }
388- }
389-
390358static void
391359eof_error (void )
392360{
@@ -397,7 +365,8 @@ eof_error(void)
397365static PyObject *
398366logreader_tp_iternext (LogReaderObject * self )
399367{
400- int what , oldindex ;
368+ int c ;
369+ int what ;
401370 int err = ERR_NONE ;
402371 int lineno = -1 ;
403372 int fileno = -1 ;
@@ -413,22 +382,18 @@ logreader_tp_iternext(LogReaderObject *self)
413382 "cannot iterate over closed LogReader object" );
414383 return NULL ;
415384 }
416- restart :
417- if ((self -> filled - self -> index ) < MAXEVENTSIZE )
418- logreader_refill (self );
419385
420- /* end of input */
421- if (self -> filled == 0 )
386+ restart :
387+ /* decode the record type */
388+ if ((c = fgetc (self -> logfp )) == EOF )
422389 return NULL ;
423390
424- oldindex = self -> index ;
391+ what = c & WHAT_OTHER ;
392+ if (what == WHAT_OTHER )
393+ what = c ; /* need all the bits for type */
394+ else
395+ ungetc (c , self -> logfp ); /* type byte includes packed int */
425396
426- /* decode the record type */
427- what = self -> buffer [self -> index ] & WHAT_OTHER ;
428- if (what == WHAT_OTHER ) {
429- what = self -> buffer [self -> index ];
430- self -> index ++ ;
431- }
432397 switch (what ) {
433398 case WHAT_ENTER :
434399 err = unpack_packed_int (self , & fileno , 2 );
@@ -447,7 +412,7 @@ logreader_tp_iternext(LogReaderObject *self)
447412 err = unpack_packed_int (self , & tdelta , 0 );
448413 break ;
449414 case WHAT_ADD_INFO :
450- err = unpack_add_info (self , 0 );
415+ err = unpack_add_info (self );
451416 break ;
452417 case WHAT_DEFINE_FILE :
453418 err = unpack_packed_int (self , & fileno , 0 );
@@ -468,40 +433,29 @@ logreader_tp_iternext(LogReaderObject *self)
468433 }
469434 break ;
470435 case WHAT_LINE_TIMES :
471- if (self -> index >= self -> filled )
436+ if (( c = fgetc ( self -> logfp )) == EOF )
472437 err = ERR_EOF ;
473438 else {
474- self -> linetimings = self -> buffer [self -> index ] ? 1 : 0 ;
475- self -> index ++ ;
476- goto restart ;
477- }
439+ self -> linetimings = c ? 1 : 0 ;
440+ goto restart ;
441+ }
478442 break ;
479443 case WHAT_FRAME_TIMES :
480- if (self -> index >= self -> filled )
444+ if (( c = fgetc ( self -> logfp )) == EOF )
481445 err = ERR_EOF ;
482446 else {
483- self -> frametimings = self -> buffer [self -> index ] ? 1 : 0 ;
484- self -> index ++ ;
485- goto restart ;
486- }
447+ self -> frametimings = c ? 1 : 0 ;
448+ goto restart ;
449+ }
487450 break ;
488451 default :
489452 err = ERR_BAD_RECTYPE ;
490453 }
491- if (err == ERR_EOF && oldindex != 0 ) {
492- /* It looks like we ran out of data before we had it all; this
493- * could easily happen with large packed integers or string
494- * data. Try forcing the buffer to be re-filled before failing.
495- */
496- err = ERR_NONE ;
497- logreader_refill (self );
498- }
499454 if (err == ERR_BAD_RECTYPE ) {
500455 PyErr_SetString (PyExc_ValueError ,
501456 "unknown record type in log file" );
502457 }
503458 else if (err == ERR_EOF ) {
504- /* Could not avoid end-of-buffer error. */
505459 eof_error ();
506460 }
507461 else if (!err ) {
@@ -1389,12 +1343,12 @@ hotshot_logreader(PyObject *unused, PyObject *args)
13891343{
13901344 LogReaderObject * self = NULL ;
13911345 char * filename ;
1346+ int c ;
1347+ int err = 0 ;
13921348
13931349 if (PyArg_ParseTuple (args , "s:logreader" , & filename )) {
13941350 self = PyObject_New (LogReaderObject , & LogReaderType );
13951351 if (self != NULL ) {
1396- self -> filled = 0 ;
1397- self -> index = 0 ;
13981352 self -> frametimings = 1 ;
13991353 self -> linetimings = 0 ;
14001354 self -> info = NULL ;
@@ -1410,14 +1364,17 @@ hotshot_logreader(PyObject *unused, PyObject *args)
14101364 Py_DECREF (self );
14111365 goto finally ;
14121366 }
1413- /* Aggressively attempt to load all preliminary ADD_INFO
1414- * records from the log so the info records are available
1415- * from a fresh logreader object.
1416- */
1417- logreader_refill (self );
1418- while (self -> filled > self -> index
1419- && self -> buffer [self -> index ] == WHAT_ADD_INFO ) {
1420- int err = unpack_add_info (self , 1 );
1367+ /* read initial info */
1368+ for (;;) {
1369+ if ((c = fgetc (self -> logfp )) == EOF ) {
1370+ eof_error ();
1371+ break ;
1372+ }
1373+ if (c != WHAT_ADD_INFO ) {
1374+ ungetc (c , self -> logfp );
1375+ break ;
1376+ }
1377+ err = unpack_add_info (self );
14211378 if (err ) {
14221379 if (err == ERR_EOF )
14231380 eof_error ();
@@ -1426,12 +1383,6 @@ hotshot_logreader(PyObject *unused, PyObject *args)
14261383 "unexpected error" );
14271384 break ;
14281385 }
1429- /* Refill agressively so we can avoid EOF during
1430- * initialization unless there's a real EOF condition
1431- * (the tp_iternext handler loops attempts to refill
1432- * and try again).
1433- */
1434- logreader_refill (self );
14351386 }
14361387 }
14371388 }
0 commit comments