Changeset 9


Ignore:
Timestamp:
Jan 12, 2006, 6:44:29 PM (15 years ago)
Author:
root
Message:

Update 2005-11-28

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/inout.c

    r3 r9  
    353353 *
    354354 **********************************************************************/
     355typedef size_t (* iofunc) ( void *, size_t, size_t, FILE * );
    355356static int readOrWriteBytes( tr_io_t * io, uint64_t offset, int size,
    356357                             uint8_t * buf, int write )
     
    359360    tr_info_t    * inf = &tor->info;
    360361
    361     int          piece = offset / inf->pieceSize;
    362     int          begin = offset % inf->pieceSize;
    363 
    364     int          i;
    365     uint64_t     foo;
    366     uint64_t     posInFile = 0;
    367     int          willRead;
    368     char       * path;
    369     FILE       * file;
    370 
    371     /* We can't ever read or write more than a piece at a time */
     362    int    piece = offset / inf->pieceSize;
     363    int    begin = offset % inf->pieceSize;
     364    int    i, cur;
     365    char * path;
     366    FILE * file;
     367    iofunc readOrWrite = write ? (iofunc) fwrite : (iofunc) fread;
     368
     369    /* Release the torrent lock so the UI can still update itself if
     370       this blocks for a while */
     371    tr_lockUnlock( tor->lock );
     372
     373    /* We don't ever read or write more than a piece at a time */
    372374    if( tr_pieceSize( piece ) < begin + size )
    373375    {
    374         return 1;
     376        tr_err( "readOrWriteBytes: trying to write more than a piece" );
     377        goto fail;
    375378    }
    376379
    377380    /* Find which file we shall start reading/writing in */
    378     foo = 0;
    379381    for( i = 0; i < inf->fileCount; i++ )
    380382    {
    381         if( offset < foo + inf->files[i].length )
    382         {
    383             posInFile = offset - foo;
     383        if( offset < inf->files[i].length )
     384        {
     385            /* This is the file */
    384386            break;
    385387        }
    386         foo += inf->files[i].length;
     388        offset -= inf->files[i].length;
     389    }
     390    if( i >= inf->fileCount )
     391    {
     392        /* Should not happen */
     393        tr_err( "readOrWriteBytes: offset out of range" );
     394        goto fail;
    387395    }
    388396
    389397    while( size > 0 )
    390398    {
     399        /* How much can we put or take with this file */
     400        if( inf->files[i].length < offset + size )
     401        {
     402            cur = (int) ( inf->files[i].length - offset );
     403        }
     404        else
     405        {
     406            cur = size;
     407        }
     408
     409        /* Now let's get a stream on the file... */
    391410        asprintf( &path, "%s/%s", tor->destination, inf->files[i].name );
    392         tr_lockUnlock( tor->lock );
    393411        file = tr_fdFileOpen( tor->fdlimit, path );
    394         tr_lockLock( tor->lock );
     412        if( !file )
     413        {
     414            tr_err( "readOrWriteBytes: could not open file '%s'", path );
     415            free( path );
     416            goto fail;
     417        }
    395418        free( path );
    396419
    397         if( !file )
    398         {
    399             return 1;
    400         }
    401 
    402         willRead = MIN( inf->files[i].length - posInFile,
    403                           (uint64_t) size );
    404 
    405         tr_lockUnlock( tor->lock );
    406         if( fseeko( file, posInFile, SEEK_SET ) )
    407         {
    408             tr_lockLock( tor->lock );
    409             return 1;
    410         }
    411         if( write )
    412         {
    413             if( fwrite( buf, willRead, 1, file ) != 1 )
    414             {
    415                 tr_lockLock( tor->lock );
    416                 return 1;
    417             }
    418         }
    419         else
    420         {
    421             if( fread( buf, willRead, 1, file ) != 1 )
    422             {
    423                 tr_lockLock( tor->lock );
    424                 return 1;
    425             }
    426         }
    427         tr_lockLock( tor->lock );
     420        /* seek to the right offset... */
     421        if( fseeko( file, offset, SEEK_SET ) )
     422        {
     423            goto fail;
     424        }
     425
     426        /* do what we are here to do... */
     427        if( readOrWrite( buf, cur, 1, file ) != 1 )
     428        {
     429            goto fail;
     430        }
     431
     432        /* and close the stream. */
    428433        tr_fdFileRelease( tor->fdlimit, file );
    429434
    430         /* 'willRead' less bytes to do */
    431         size -= willRead;
    432         buf  += willRead;
    433 
    434         /* Go to the beginning of the next file */
    435         i         += 1;
    436         posInFile  = 0;
    437     }
    438 
     435        /* 'cur' bytes done, 'size - cur' bytes to go with the next file */
     436        i      += 1;
     437        offset  = 0;
     438        size   -= cur;
     439        buf    += cur;
     440    }
     441
     442    tr_lockLock( tor->lock );
    439443    return 0;
     444
     445fail:
     446    tr_lockLock( tor->lock );
     447    return 1;
    440448}
    441449
Note: See TracChangeset for help on using the changeset viewer.