Changeset 10774


Ignore:
Timestamp:
Jun 16, 2010, 3:05:23 AM (13 years ago)
Author:
charles
Message:

(libT) #3291 "tr_torrent.infoDictOffset should be lazily evaluated"

Location:
trunk/libtransmission
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/metainfo.c

    r10502 r10774  
    403403                      tr_info           * inf,
    404404                      tr_bool           * hasInfoDict,
    405                       int               * infoDictOffset,
    406405                      int               * infoDictLength,
    407406                      const tr_benc     * meta_in )
     
    461460        if( infoDictLength != NULL )
    462461            *infoDictLength = len;
    463 
    464         if( infoDictOffset != NULL )
    465         {
    466             int mlen = 0;
    467             char * mstr = tr_bencToStr( meta_in, TR_FMT_BENC, &mlen );
    468             const char * offset = tr_memmem( mstr, mlen, bstr, len );
    469             if( offset != NULL )
    470                 *infoDictOffset = offset - mstr;
    471             tr_free( mstr );
    472             if( offset == NULL )
    473                 return "info";
    474         }
    475462
    476463        tr_free( bstr );
     
    564551                  tr_info          * inf,
    565552                  tr_bool          * hasInfoDict,
    566                   int              * infoDictOffset,
    567553                  int              * infoDictLength )
    568554{
     
    570556                                                inf,
    571557                                                hasInfoDict,
    572                                                 infoDictOffset,
    573558                                                infoDictLength,
    574559                                                meta_in );
  • trunk/libtransmission/metainfo.h

    r10502 r10774  
    2626                           tr_info              * setmeInfo,
    2727                           tr_bool              * setmeHasInfoDict,
    28                            int                  * setmeInfoDictOffset,
    2928                           int                  * setmeInfoDictLength );
    3029
  • trunk/libtransmission/torrent-magnet.c

    r10641 r10774  
    9696}
    9797
     98static int
     99findInfoDictOffset( const tr_torrent * tor )
     100{
     101    size_t fileLen;
     102    uint8_t * fileContents;
     103    int offset = 0;
     104
     105    /* load the file, and find the info dict's offset inside the file */
     106    if(( fileContents = tr_loadFile( tor->info.torrent, &fileLen )))
     107    {
     108        tr_benc top;
     109
     110        if( !tr_bencParse( fileContents, fileContents + fileLen, &top, NULL ) )
     111        {
     112            tr_benc * infoDict;
     113
     114            if( tr_bencDictFindDict( &top, "info", &infoDict ) )
     115            {
     116                int infoLen;
     117                char * infoContents = tr_bencToStr( infoDict, TR_FMT_BENC, &infoLen );
     118                const uint8_t * i = (const uint8_t*) tr_memmem( (char*)fileContents, fileLen, infoContents, infoLen );
     119                offset = i == NULL ? i - fileContents : 0;
     120                tr_free( infoContents );
     121            }
     122
     123            tr_bencFree( &top );
     124        }
     125
     126        tr_free( fileContents );
     127    }
     128
     129    return offset;
     130}
     131
     132static void
     133ensureInfoDictOffsetIsCached( tr_torrent * tor )
     134{
     135    assert( tr_torrentHasMetadata( tor ) );
     136
     137    if( !tor->infoDictOffsetIsCached )
     138    {
     139        tor->infoDictOffset = findInfoDictOffset( tor );
     140        tor->infoDictOffsetIsCached = TRUE;
     141    }
     142}
     143
    98144void*
    99 tr_torrentGetMetadataPiece( const tr_torrent * tor, int piece, int * len )
     145tr_torrentGetMetadataPiece( tr_torrent * tor, int piece, int * len )
    100146{
    101147    char * ret = NULL;
     
    105151    assert( len != NULL );
    106152
    107     if( tor->infoDictLength > 0 )
    108     {
    109         FILE * fp = fopen( tor->info.torrent, "rb" );
     153    if( tr_torrentHasMetadata( tor ) )
     154    {
     155        FILE * fp;
     156
     157        ensureInfoDictOffsetIsCached( tor );
     158
     159        assert( tor->infoDictLength > 0 );
     160        assert( tor->infoDictOffset >= 0 );
     161
     162        fp = fopen( tor->info.torrent, "rb" );
    110163        if( fp != NULL )
    111164        {
     
    209262                    tr_bencMergeDicts( tr_bencDictAddDict( &newMetainfo, "info", 0 ), &infoDict );
    210263
    211                     success = tr_metainfoParse( tor->session, &newMetainfo, &tor->info,
    212                                                 &hasInfo, &tor->infoDictOffset, &tor->infoDictLength );
     264                    success = tr_metainfoParse( tor->session, &newMetainfo, &tor->info, &hasInfo, &tor->infoDictLength );
    213265
    214266                    assert( hasInfo );
  • trunk/libtransmission/torrent-magnet.h

    r9868 r10774  
    2626};
    2727
    28 void* tr_torrentGetMetadataPiece( const tr_torrent * tor, int piece, int * len );
     28void* tr_torrentGetMetadataPiece( tr_torrent * tor, int piece, int * len );
    2929
    3030void tr_torrentSetMetadataPiece( tr_torrent * tor, int piece, const void * data, int len );
  • trunk/libtransmission/torrent.c

    r10736 r10774  
    738738static tr_parse_result
    739739torrentParseImpl( const tr_ctor * ctor, tr_info * setmeInfo,
    740                   tr_bool * setmeHasInfo, int * dictOffset, int * dictLength )
     740                  tr_bool * setmeHasInfo, int * dictLength )
    741741{
    742742    int             doFree;
     
    756756
    757757    didParse = tr_metainfoParse( session, metainfo, setmeInfo,
    758                                  &hasInfo, dictOffset, dictLength );
     758                                 &hasInfo, dictLength );
    759759    doFree = didParse && ( setmeInfo == &tmp );
    760760
     
    780780tr_torrentParse( const tr_ctor * ctor, tr_info * setmeInfo )
    781781{
    782     return torrentParseImpl( ctor, setmeInfo, NULL, NULL, NULL );
     782    return torrentParseImpl( ctor, setmeInfo, NULL, NULL );
    783783}
    784784
     
    786786tr_torrentNew( const tr_ctor * ctor, int * setmeError )
    787787{
    788     int off, len;
     788    int len;
    789789    tr_bool hasInfo;
    790790    tr_info tmpInfo;
     
    795795    assert( tr_isSession( tr_ctorGetSession( ctor ) ) );
    796796
    797     r = torrentParseImpl( ctor, &tmpInfo, &hasInfo, &off, &len );
     797    r = torrentParseImpl( ctor, &tmpInfo, &hasInfo, &len );
    798798    if( r == TR_PARSE_OK )
    799799    {
     
    801801        tor->info = tmpInfo;
    802802        if( hasInfo )
    803         {
    804             tor->infoDictOffset = off;
    805803            tor->infoDictLength = len;
    806         }
    807804        torrentInit( tor, ctor );
    808805    }
     
    21962193        memset( &tmpInfo, 0, sizeof( tr_info ) );
    21972194        if( tr_metainfoParse( tor->session, &metainfo, &tmpInfo,
    2198                               &hasInfo, &tor->infoDictOffset, &tor->infoDictLength ) )
     2195                              &hasInfo, &tor->infoDictLength ) )
    21992196        {
    22002197            /* it's good, so keep these new trackers and free the old ones */
  • trunk/libtransmission/torrent.h

    r10664 r10774  
    166166    char * incompleteDir;
    167167
    168     /* Length, in bytes, of the "info" dict in the .torrent file */
     168    /* Length, in bytes, of the "info" dict in the .torrent file. */
    169169    int infoDictLength;
    170170
    171     /* Offset, in bytes, of the beginning of the "info" dict in the .torrent file */
     171    /* Offset, in bytes, of the beginning of the "info" dict in the .torrent file.
     172     *
     173     * Used by the torrent-magnet code for serving metainfo to peers.
     174     * This field is lazy-generated and might not be initialized yet. */
    172175    int infoDictOffset;
    173176
     
    232235    tr_bool                    startAfterVerify;
    233236    tr_bool                    isDirty;
     237
     238    tr_bool                    infoDictOffsetIsCached;
    234239
    235240    uint16_t                   maxConnectedPeers;
Note: See TracChangeset for help on using the changeset viewer.