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 ); }
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 ); }
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 ); }
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 ) ); }