Esempio n. 1
0
static void
saveProgress( tr_benc *          dict,
              const tr_torrent * tor )
{
    size_t              i, n;
    time_t *            mtimes;
    tr_benc *           p;
    tr_benc *           m;
    const tr_bitfield * bitfield;

    p = tr_bencDictAdd( dict, KEY_PROGRESS );
    tr_bencInitDict( p, 2 );

    /* add the mtimes */
    mtimes = tr_torrentGetMTimes( tor, &n );
    m = tr_bencDictAddList( p, KEY_PROGRESS_MTIMES, n );
    for( i = 0; i < n; ++i )
    {
        if( !tr_torrentIsFileChecked( tor, i ) )
            mtimes[i] = ~(time_t)0; /* force a recheck */
        tr_bencListAddInt( m, mtimes[i] );
    }

    /* add the bitfield */
    bitfield = tr_cpBlockBitfield( tor->completion );
    tr_bencDictAddRaw( p, KEY_PROGRESS_BITFIELD,
                       bitfield->bits, bitfield->byteCount );

    /* cleanup */
    tr_free( mtimes );
}
Esempio n. 2
0
static void
saveFilePriorities( tr_benc * dict, const tr_torrent * tor )
{
    const tr_info *       inf = tr_torrentInfo( tor );
    const tr_file_index_t n = inf->fileCount;
    tr_file_index_t       i;
    tr_benc *             list;

    list = tr_bencDictAddList( dict, KEY_FILE_PRIORITIES, n );
    for( i = 0; i < n; ++i )
        tr_bencListAddInt( list, inf->files[i].priority );
}
Esempio n. 3
0
static void
saveDND( tr_benc * dict, const tr_torrent * tor )
{
    tr_benc * list;
    tr_file_index_t i;
    const tr_info * const inf = tr_torrentInfo( tor );
    const tr_file_index_t n = inf->fileCount;

    list = tr_bencDictAddList( dict, KEY_DND, n );
    for( i=0; i<n; ++i )
        tr_bencListAddInt( list, inf->files[i].dnd ? 1 : 0 );
}
Esempio n. 4
0
static void
saveProgress( tr_benc * dict, tr_torrent * tor )
{
    tr_benc * l;
    tr_benc * prog;
    tr_file_index_t fi;
    const tr_info * inf = tr_torrentInfo( tor );
    const time_t now = tr_time( );

    prog = tr_bencDictAddDict( dict, KEY_PROGRESS, 3 );

    /* add the file/piece check timestamps... */
    l = tr_bencDictAddList( prog, KEY_PROGRESS_CHECKTIME, inf->fileCount );
    for( fi=0; fi<inf->fileCount; ++fi )
    {
        const tr_piece * p;
        const tr_piece * pend;
        time_t oldest_nonzero = now;
        time_t newest = 0;
        tr_bool has_zero = FALSE;
        const time_t mtime = tr_torrentGetFileMTime( tor, fi );
        const tr_file * f = &inf->files[fi];

        /* get the oldest and newest nonzero timestamps for pieces in this file */
        for( p=&inf->pieces[f->firstPiece], pend=&inf->pieces[f->lastPiece]; p!=pend; ++p )
        {
            if( !p->timeChecked )
                has_zero = TRUE;
            else if( oldest_nonzero > p->timeChecked )
                oldest_nonzero = p->timeChecked;
            if( newest < p->timeChecked )
                newest = p->timeChecked;
        }

        /* If some of a file's pieces have been checked more recently than
           the file's mtime, and some lest recently, then that file will
           have a list containing timestamps for each piece.
           
           However, the most common use case is that the file doesn't change
           after it's downloaded. To reduce overhead in the .resume file,
           only a single timestamp is saved for the file if *all* or *none*
           of the pieces were tested more recently than the file's mtime. */

        if( !has_zero && ( mtime <= oldest_nonzero ) ) /* all checked */
            tr_bencListAddInt( l, oldest_nonzero );
        else if( newest < mtime ) /* none checked */
            tr_bencListAddInt( l, newest );
        else { /* some are checked, some aren't... so list piece by piece */
            const int offset = oldest_nonzero - 1;
            tr_benc * ll = tr_bencListAddList( l, 2 + f->lastPiece - f->firstPiece );
            tr_bencListAddInt( ll, offset );
            for( p=&inf->pieces[f->firstPiece], pend=&inf->pieces[f->lastPiece]+1; p!=pend; ++p )
                tr_bencListAddInt( ll, p->timeChecked ? p->timeChecked - offset : 0 );
        }
    }

    /* add the progress */
    if( tor->completeness == TR_SEED )
        tr_bencDictAddStr( prog, KEY_PROGRESS_HAVE, "all" );

    /* add the blocks bitfield */
    tr_bitsetToBenc( tr_cpBlockBitset( &tor->completion ),
                     tr_bencDictAdd( prog, KEY_PROGRESS_BLOCKS ) );
}