Changeset 5498


Ignore:
Timestamp:
Apr 3, 2008, 9:38:32 PM (14 years ago)
Author:
charles
Message:

hack on IPC a bit because it's been too long since I broke it

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/daemon/client.c

    r5143 r5498  
    795795                                        jj->str, -1, 1 );
    796796                    }
    797                     buf = ipc_mkval( &pk, &buflen );
     797                    buf = ipc_serialize( &pk, &buflen );
    798798                    SAFEBENCFREE( &pk );
    799799                }
     
    806806                    tr_bencInitStr( tr_bencDictAdd( val, "data" ),
    807807                                    req->buf, req->listlen, 1 );
    808                     buf = ipc_mkval( &pk, &buflen );
     808                    buf = ipc_serialize( &pk, &buflen );
    809809                    SAFEBENCFREE( &pk );
    810810                }
     
    834834                                        req->numlist[ii] );
    835835                    }
    836                     buf = ipc_mkval( &pk, &buflen );
     836                    buf = ipc_serialize( &pk, &buflen );
    837837                    SAFEBENCFREE( &pk );
    838838                }
  • trunk/daemon/server.c

    r5143 r5498  
    499499    }
    500500
    501     buf = ipc_mkval( &pk, &buflen );
     501    buf = ipc_serialize( &pk, &buflen );
    502502    tr_bencFree( &pk );
    503503    queuemsg( client, buf, buflen );
     
    563563            return;
    564564        }
    565         buf = ipc_mkval( &pk, &buflen );
     565        buf = ipc_serialize( &pk, &buflen );
    566566        tr_bencFree( &pk );
    567567        queuemsg( client, buf, buflen );
     
    762762
    763763    /* generate packet data and send it */
    764     buf = ipc_mkval( &pk, &buflen );
     764    buf = ipc_serialize( &pk, &buflen );
    765765    tr_bencFree( &pk );
    766766    queuemsg( client, buf, buflen );
     
    907907    }
    908908
    909     buf = ipc_mkval( &pk, &buflen );
     909    buf = ipc_serialize( &pk, &buflen );
    910910    tr_bencFree( &pk );
    911911    queuemsg( client, buf, buflen );
     
    10281028    }
    10291029
    1030     buf = ipc_mkval( &pk, &buflen );
     1030    buf = ipc_serialize( &pk, &buflen );
    10311031    tr_bencFree( &pk );
    10321032    queuemsg( client, buf, buflen );
  • trunk/gtk/ipc.c

    r5455 r5498  
    184184                tr_bencInitStr( tr_bencListAdd( val ), ii->data, -1, 0 );
    185185            }
    186             buf = ipc_mkval( &packet, &size );
     186            buf = ipc_serialize( &packet, &size );
    187187            saved = errno;
    188188            tr_bencFree( &packet );
     
    685685    }
    686686
    687     buf = ipc_mkval( &packet, &size );
     687    buf = ipc_serialize( &packet, &size );
    688688    tr_bencFree( &packet );
    689689    if( NULL == buf )
     
    746746    }
    747747
    748     buf = ipc_mkval( &packet, &size );
     748    buf = ipc_serialize( &packet, &size );
    749749    tr_bencFree( &packet );
    750750    if( NULL == buf )
     
    830830    }
    831831
    832     buf = ipc_mkval( &packet, &size );
     832    buf = ipc_serialize( &packet, &size );
    833833    tr_bencFree( &packet );
    834834    if( NULL == buf )
     
    11171117    }
    11181118
    1119     buf = ipc_mkval( &packet, &size );
     1119    buf = ipc_serialize( &packet, &size );
    11201120    tr_bencFree( &packet );
    11211121    if( NULL == buf )
  • trunk/libtransmission/bencode.c

    r5455 r5498  
    442442
    443443int
     444tr_bencInitList( tr_benc * val, int reserveCount )
     445{
     446    tr_bencInit( val, TYPE_LIST );
     447    return tr_bencListReserve( val, reserveCount );
     448}
     449
     450int
    444451tr_bencListReserve( tr_benc * val, int count )
    445452{
    446453    assert( isList( val ) );
    447 
    448454    return makeroom( val, count );
     455}
     456
     457int
     458tr_bencInitDict( tr_benc * val, int reserveCount )
     459{
     460    tr_bencInit( val, TYPE_DICT );
     461    return tr_bencDictReserve( val, reserveCount );
    449462}
    450463
     
    453466{
    454467    assert( isDict( val ) );
    455 
    456468    return makeroom( val, count * 2 );
    457469}
  • trunk/libtransmission/bencode.h

    r5198 r5498  
    8989int    tr_bencInitStrDup( tr_benc * val, const char * str );
    9090void   tr_bencInitInt( tr_benc * val, int64_t num );
     91int   tr_bencInitDict( tr_benc * val, int reserveCount );
     92int   tr_bencInitList( tr_benc * val, int reserveCount );
    9193int   tr_bencListReserve( tr_benc * list, int count );
    9294/* note that for one key-value pair, count should be 1, not 2 */
  • trunk/libtransmission/completion.c

    r5329 r5498  
    9595tr_cpEnsureDoneValid( const tr_completion * ccp )
    9696{
    97     const tr_torrent * tor = ccp->tor;
    98     const tr_info * info = &tor->info;
    99     uint64_t have=0, total=0;
    100     tr_piece_index_t i;
    101     tr_completion * cp ;
    102 
    103     if( !ccp->doneDirty )
    104         return;
    105 
    106     /* too bad C doesn't have 'mutable' */
    107     cp = (tr_completion*) ccp;
    108     cp->doneDirty = FALSE;
    109 
    110     for( i=0; i<info->pieceCount; ++i ) {
    111         if( !info->pieces[i].dnd ) {
    112             total += info->pieceSize;
    113             have += cp->completeBlocks[ i ];
     97    if( ccp->doneDirty )
     98    {
     99        const tr_torrent * tor = ccp->tor;
     100        const tr_info * info = &tor->info;
     101        uint64_t have = 0;
     102        uint64_t total = 0;
     103        tr_piece_index_t i;
     104        tr_completion * cp ;
     105
     106        /* too bad C doesn't have 'mutable' */
     107        cp = (tr_completion*) ccp;
     108        cp->doneDirty = FALSE;
     109
     110        for( i=0; i<info->pieceCount; ++i ) {
     111            if( !info->pieces[i].dnd ) {
     112                total += info->pieceSize;
     113                have += cp->completeBlocks[ i ];
     114            }
    114115        }
     116
     117        have *= tor->blockSize;
     118
     119        /* the last piece/block is probably smaller than the others */
     120        if( !info->pieces[info->pieceCount-1].dnd ) {
     121            total -= ( info->pieceSize - tr_torPieceCountBytes(tor,info->pieceCount-1) );
     122            if( tr_cpBlockIsComplete( cp, tor->blockCount-1 ) )
     123                have -= ( tor->blockSize - tr_torBlockCountBytes(tor,tor->blockCount-1) );
     124        }
     125
     126        assert( have <= total );
     127        assert( total <= info->totalSize );
     128
     129        cp->doneHave = have;
     130        cp->doneTotal = total;
    115131    }
    116 
    117     have *= tor->blockSize;
    118 
    119     /* the last piece/block is probably smaller than the others */
    120     if( !info->pieces[info->pieceCount-1].dnd ) {
    121         total -= ( info->pieceSize - tr_torPieceCountBytes(tor,info->pieceCount-1) );
    122         if( tr_cpBlockIsComplete( cp, tor->blockCount-1 ) )
    123             have -= ( tor->blockSize - tr_torBlockCountBytes(tor,tor->blockCount-1) );
    124     }
    125 
    126     assert( have <= total );
    127     assert( total <= info->totalSize );
    128 
    129     cp->doneHave = have;
    130     cp->doneTotal = total;
    131132}
    132133
     
    312313    tr_cpEnsureDoneValid( cp );
    313314
    314     if( cp->doneHave >= cp->doneTotal )
    315         return TR_CP_DONE;
    316 
    317     return TR_CP_INCOMPLETE;
     315    return cp->doneHave >= cp->doneTotal ? TR_CP_DONE
     316                                         : TR_CP_INCOMPLETE;
    318317}
    319318
  • trunk/libtransmission/ipcparse.c

    r5457 r5498  
    196196
    197197void
    198 ipc_addmsg( struct ipc_funcs * tree, enum ipc_msg id, trd_msgfunc func )
    199 {
    200     assert( MSGVALID( id ) );
    201     assert( IPC_MSG_VERSION != id );
    202 
    203     tree->msgs[id] = func;
     198ipc_addmsg( struct ipc_funcs * funcs, enum ipc_msg msg_id, trd_msgfunc func )
     199{
     200    assert( MSGVALID( msg_id ) );
     201    assert( IPC_MSG_VERSION != msg_id );
     202
     203    funcs->msgs[msg_id] = func;
    204204}
    205205
    206206void
    207 ipc_setdefmsg( struct ipc_funcs * tree, trd_msgfunc func )
    208 {
    209     tree->def = func;
     207ipc_setdefmsg( struct ipc_funcs * funcs, trd_msgfunc func )
     208{
     209    funcs->def = func;
    210210}
    211211
    212212void
    213 ipc_freemsgs( struct ipc_funcs * tree )
    214 {
    215     tr_free( tree );
     213ipc_freemsgs( struct ipc_funcs * funcs )
     214{
     215    tr_free( funcs );
    216216}
    217217
     
    231231}
    232232
     233int
     234ipc_ishandled( const struct ipc_info * info, enum ipc_msg id )
     235{
     236    assert( MSGVALID( id ) );
     237
     238    return info->funcs->msgs[id] != NULL;
     239}
     240
     241int
     242ipc_havetags( const struct ipc_info * info )
     243{
     244    return !DICTPAYLOAD( info );
     245}
     246
    233247static int
    234 ipc_havemsg( const struct ipc_info * info, enum ipc_msg id )
     248sessionSupportsTags( const struct ipc_info * session )
     249{
     250    return session->vers >= 2;
     251}
     252
     253static int
     254sessionSupportsMessage( const struct ipc_info * info, enum ipc_msg id )
    235255{
    236256    assert( MSGVALID( id ) );
     
    240260}
    241261
     262/**
     263 * Creates the benc metainfo structure for a message
     264 * and returns its child where payload should be set.
     265 *
     266 * In protocol version 1, the metainfo is a single-entry
     267 * dictionary with a string from gl_msgs as the key
     268 * and the return tr_benc pointer as the value.
     269 *
     270 * In protocol version 2, the metainfo is a list
     271 * holding a string from gl_msgs, the return benc pointer,
     272 * and (optionally) the integer tag.
     273 */
    242274tr_benc *
    243 ipc_initval( const struct ipc_info * info, enum ipc_msg id, int64_t tag,
    244              tr_benc * pk, int type )
     275ipc_initval( const struct ipc_info * session,
     276             enum ipc_msg            msg_id,
     277             int64_t                 tag,
     278             tr_benc               * pk,
     279             int                     benc_type )
    245280{
    246281    tr_benc * ret;
    247282
    248     assert( MSGVALID( id ) );
    249 
    250     if( !ipc_havemsg( info, id ) || ( 0 < tag && !ipc_havetags( info ) ) )
     283    assert( MSGVALID( msg_id ) );
     284
     285    if( !sessionSupportsMessage( session, msg_id )
     286        || ( (tag>0) && !sessionSupportsTags( session ) ) )
    251287    {
    252288        errno = EPERM;
     
    254290    }
    255291
    256     if( DICTPAYLOAD( info ) )
    257     {
    258         tr_bencInit( pk, TYPE_DICT );
    259         if( tr_bencDictReserve( pk, 1 ) )
    260         {
    261             return NULL;
    262         }
    263         ret = tr_bencDictAdd( pk, MSGNAME( id ) );
     292    if( DICTPAYLOAD( session ) )
     293    {
     294        tr_bencInitDict( pk, 1 );
     295        ret = tr_bencDictAdd( pk, MSGNAME( msg_id ) );
    264296    }
    265297    else
    266298    {
    267         tr_bencInit( pk, TYPE_LIST );
    268         if( tr_bencListReserve( pk, ( 0 < tag ? 3 : 2 ) ) )
    269         {
    270             return NULL;
    271         }
    272         tr_bencInitStr( tr_bencListAdd( pk ), MSGNAME( id ), -1, 1 );
     299        tr_bencInitList( pk, 3 );
     300        tr_bencInitStr( tr_bencListAdd( pk ), MSGNAME( msg_id ), -1, 1 );
    273301        ret = tr_bencListAdd( pk );
    274302        if( 0 < tag )
    275         {
    276303            tr_bencInitInt( tr_bencListAdd( pk ), tag );
    277         }
    278     }
    279 
    280     tr_bencInit( ret, type );
    281 
     304    }
     305
     306    tr_bencInit( ret, benc_type );
    282307    return ret;
    283308}
    284309
     310/**
     311 * Serialize a benc message into a string appended to a
     312 * printf()'ed string IPC_MIN_MSG_LEN bytes long that
     313 * gives the length of the string.
     314 */
    285315uint8_t *
    286 ipc_mkval( const tr_benc * pk, size_t * setmeSize )
     316ipc_serialize( const tr_benc * pk, size_t * setmeSize )
    287317{
    288318    int bencSize = 0;
     
    304334}
    305335
     336/**
     337 * Create a serialized message whose payload is a NULL string
     338 */
    306339uint8_t *
    307 ipc_mkempty( const struct ipc_info * info, size_t * len, enum ipc_msg id,
    308              int64_t tag )
    309 {
    310     tr_benc pk;
    311     uint8_t  * ret = NULL;
    312 
    313     if( ipc_initval( info, id, tag, &pk, TYPE_STR ) )
    314     {
    315         ret = ipc_mkval( &pk, len );
    316         SAFEBENCFREE( &pk );
    317     }
    318 
    319     return ret;
    320 }
    321 
     340ipc_mkempty( const struct ipc_info * session,
     341             size_t                * setmeSize,
     342             enum ipc_msg            msg_id,
     343             int64_t                 tag )
     344{
     345    return ipc_mkstr( session, setmeSize, msg_id, tag, NULL );
     346}
     347
     348/**
     349 * Create a serialized message whose payload is an integer
     350 */
    322351uint8_t *
    323 ipc_mkint( const struct ipc_info * info, size_t * len, enum ipc_msg id,
    324            int64_t tag, int64_t num )
     352ipc_mkint( const struct ipc_info  * session,
     353           size_t                 * setmeSize,
     354           enum ipc_msg             msg_id,
     355           int64_t                  tag,
     356           int64_t                  num )
    325357{
    326358    tr_benc pk, * val;
    327359    uint8_t  * ret = NULL;
    328360
    329     if(( val = ipc_initval( info, id, tag, &pk, TYPE_INT )))
     361    if(( val = ipc_initval( session, msg_id, tag, &pk, TYPE_INT )))
    330362    {
    331363        val->val.i = num;
    332         ret = ipc_mkval( &pk, len );
     364        ret = ipc_serialize( &pk, setmeSize );
    333365        SAFEBENCFREE( &pk );
    334366    }
     
    337369}
    338370
     371/**
     372 * Create a serialized message whose payload is a string
     373 */
    339374uint8_t *
    340 ipc_mkstr( const struct ipc_info * info, size_t * len, enum ipc_msg id,
    341            int64_t tag, const char * str )
     375ipc_mkstr( const struct ipc_info  * session,
     376           size_t                 * setmeSize,
     377           enum ipc_msg             msg_id,
     378           int64_t                  tag,
     379           const char             * str )
    342380{
    343381    tr_benc pk, * val;
    344382    uint8_t  * ret = NULL;
    345383
    346     if(( val = ipc_initval( info, id, tag, &pk, TYPE_STR )))
     384    if(( val = ipc_initval( session, msg_id, tag, &pk, TYPE_STR )))
    347385    {
    348386        tr_bencInitStr( val, str, -1, 1 );
    349         ret = ipc_mkval( &pk, len );
     387        ret = ipc_serialize( &pk, setmeSize );
    350388        SAFEBENCFREE( &pk );
    351389    }
     
    354392}
    355393
     394/**
     395 * Create a serialized message whose payload is a dictionary
     396 * giving the minimum and maximum protocol version we support,
     397 * and (optionally) the label passed in.
     398 *
     399 * Note that this message is just the dictionary payload.
     400 * It doesn't contain metainfo as the other ipc_mk*() functions do.
     401 */
    356402uint8_t *
    357403ipc_mkvers( size_t * len, const char * label )
     
    360406    uint8_t  * ret;
    361407 
    362     tr_bencInit( &pk, TYPE_DICT );
    363     if( tr_bencDictReserve( &pk, 1 ) )
    364     {
    365         return NULL;
    366     }
     408    tr_bencInitDict( &pk, 1 );
    367409    dict = tr_bencDictAdd( &pk, MSGNAME( IPC_MSG_VERSION ) );
    368410
    369     tr_bencInit( dict, TYPE_DICT );
    370     if( tr_bencDictReserve( dict, ( NULL == label ? 2 : 3 ) ) )
    371     {
    372         SAFEBENCFREE( &pk );
    373         return NULL;
    374     }
     411    tr_bencInitDict( dict, 3 );
    375412    tr_bencInitInt( tr_bencDictAdd( dict, "min" ), PROTO_VERS_MIN );
    376413    tr_bencInitInt( tr_bencDictAdd( dict, "max" ), PROTO_VERS_MAX );
    377     if( NULL != label )
     414    if( label )
    378415        tr_bencInitStr( tr_bencDictAdd( dict, "label" ), label, -1, 1 );
    379416
    380     ret = ipc_mkval( &pk, len );
     417    ret = ipc_serialize( &pk, len );
    381418    SAFEBENCFREE( &pk );
    382419
     
    384421}
    385422
     423/**
     424 * Create a serialized message that is used to request
     425 * torrent information or statistics.
     426 *
     427 * msg_id must be one of:
     428 *   IPC_MSG_GETINFO
     429 *   IPC_MSG_GETINFOALL
     430 *   IPC_MSG_GETSTAT
     431 *   IPC_MSG_GETSTATALL
     432 *
     433 * "ids" is an optional array of torrent IDs.
     434 * The array, if included, must be terminated by a 0 torrent id.
     435 *
     436 * "types" is a bitwise-and'ed set of fields from either
     437 * the IPC_INF_* or IPC_ST_* enums in ipc-parse.h.
     438 * Which enums are used is dependent on the value of msg_id.
     439 *
     440 * If torrent ids are specified in the "ids" array,
     441 * the payload is a dictionary of two lists, "id" and "type".
     442 * The "id" list holds the torrent IDs, and
     443 * the "type" list holds string keys from either
     444 * gl_inf or gl_stat, depending on the value of msg_id
     445 *
     446 * If no torrent ids are specified, the payload is
     447 * a single list identical to the "type" list described above.
     448 */
    386449uint8_t *
    387 ipc_mkgetinfo( const struct ipc_info * info, size_t * len, enum ipc_msg id,
    388                int64_t tag, int types, const int * ids )
    389 {
    390     tr_benc   pk, * top, * idlist, * typelist;
     450ipc_mkgetinfo( const struct ipc_info * session,
     451               size_t                * setmeSize,
     452               enum ipc_msg            msg_id,
     453               int64_t                 tag,
     454               int                     types,
     455               const int             * ids )
     456{
     457    tr_benc   pk;
     458    tr_benc * typelist;
    391459    size_t       ii, typecount, used;
    392460    const struct inf * typearray;
     
    394462
    395463    /* no ID list, send an -all message */
    396     if( NULL == ids )
    397     {
    398         typelist = ipc_initval( info, id, tag, &pk, TYPE_LIST );
    399         if( NULL == typelist )
    400         {
     464    if( !ids ) {
     465        typelist = ipc_initval( session, msg_id, tag, &pk, TYPE_LIST );
     466        if( !typelist )
    401467            return NULL;
    402         }
    403468    }
    404469    else
    405470    {
    406         top = ipc_initval( info, id, tag, &pk, TYPE_DICT );
    407         if( NULL == top )
    408         {
     471        tr_benc * top;
     472        tr_benc * idlist;
     473
     474        top = ipc_initval( session, msg_id, tag, &pk, TYPE_DICT );
     475        if( !top )
    409476            return NULL;
    410         }
     477
    411478        /* add the requested IDs */
    412         if( tr_bencDictReserve( top, 2 ) )
    413         {
    414             SAFEBENCFREE( &pk );
    415             return NULL;
    416         }
     479        tr_bencDictReserve( top, 2 );
    417480        idlist   = tr_bencDictAdd( top, "id" );
    418481        typelist = tr_bencDictAdd( top, "type" );
    419         tr_bencInit( idlist, TYPE_LIST );
    420482        tr_bencInit( typelist, TYPE_LIST );
     483        for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ ) { }
     484        tr_bencInitList( idlist, ii );
    421485        for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ )
    422         {
    423         }
    424         if( tr_bencListReserve( idlist, ii ) )
    425         {
    426             SAFEBENCFREE( &pk );
    427             return NULL;
    428         }
    429         for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ )
    430         {
    431486            tr_bencInitInt( tr_bencListAdd( idlist ), ids[ii] );
    432         }
    433487    }
    434488
    435489    /* get the type name array */
    436     switch( id )
     490    switch( msg_id )
    437491    {
    438492        case IPC_MSG_GETINFO:
     
    453507    /* add the type names */
    454508    for( ii = used = 0; typecount > ii; ii++ )
    455     {
    456509        if( types & ( 1 << ii ) )
    457         {
    458510            used++;
    459         }
    460     }
    461     if( tr_bencListReserve( typelist, used ) )
    462     {
    463         SAFEBENCFREE( &pk );
    464         return NULL;
    465     }
     511    tr_bencListReserve( typelist, used );
     512
    466513    for( ii = 0; typecount > ii; ii++ )
    467514    {
    468515        if( !( types & ( 1 << ii ) ) )
    469         {
    470516            continue;
    471         }
    472517        assert( typearray[ii].type == ( 1 << ii ) );
    473518        tr_bencInitStr( tr_bencListAdd( typelist ),
     
    476521
    477522    /* generate packet */
    478     ret = ipc_mkval( &pk, len );
     523    ret = ipc_serialize( &pk, setmeSize );
    479524    SAFEBENCFREE( &pk );
    480525
     
    482527}
    483528
    484 static int
     529static void
    485530filltracker( tr_benc * val, const tr_tracker_info * tk )
    486531{
    487     tr_bencInit( val, TYPE_DICT );
    488     if( tr_bencDictReserve( val, ( NULL == tk->scrape ? 3 : 4 ) ) )
    489         return -1;
    490 
     532    tr_bencInitDict( val, 4 );
    491533    tr_bencInitStr( tr_bencDictAdd( val, "address" ),  tk->address,  -1, 1 );
    492534    tr_bencInitInt( tr_bencDictAdd( val, "port" ),     tk->port );
     
    494536    if( NULL != tk->scrape )
    495537        tr_bencInitStr( tr_bencDictAdd( val, "scrape" ), tk->scrape, -1, 1 );
    496 
    497     return 0;
    498 }
    499 
     538}
     539
     540/**
     541 * append to "list" a dictionary whose keys are
     542 * the string keys from gl_inf and whose values are
     543 * torrent info set from "torrent_id" and "inf".
     544 *
     545 * "types" is a bitwise-and'ed set of fields
     546 * from the IPC_INF_* enum in ipcparse.h.
     547 * It specifies what to put in the dictionary.
     548 */
    500549int
    501 ipc_addinfo( tr_benc * list, int tor, const tr_info * inf, int types )
     550ipc_addinfo( tr_benc         * list,
     551             int               torrent_id,
     552             const tr_info   * inf,
     553             int               types )
    502554{
    503555    tr_benc * dict, * item, * file, * tier;
     
    508560    types |= IPC_INF_ID;
    509561
    510     if( tr_bencListReserve( list, 1 ) )
    511     {
    512         return -1;
    513     }
     562    tr_bencListReserve( list, 1 );
    514563
    515564    dict = tr_bencListAdd( list );
    516     tr_bencInit( dict, TYPE_DICT );
     565
     566    /* count the number of info keys and allocate a dict for them */
    517567    for( ii = jj = 0; IPC_INF__MAX > 1 << ii; ii++ )
    518568    {
    519569        if( !( types & ( 1 << ii ) ) )
    520         {
    521570            continue;
    522         }
     571
    523572        assert( TR_N_ELEMENTS( gl_inf ) > ( unsigned )ii );
    524573        assert( gl_inf[ii].type == ( 1 << ii ) );
    525         /* check for missing optional info */
    526         if( ( IPC_INF_COMMENT == ( 1 << ii ) && !*inf->comment ) ||
    527             ( IPC_INF_CREATOR == ( 1 << ii ) && !*inf->creator ) ||
    528             ( IPC_INF_DATE    == ( 1 << ii ) &&   0  >= inf->dateCreated ) )
    529         {
     574        jj++;
     575    }
     576
     577    tr_bencInitDict( dict, jj );
     578
     579    /* populate the dict with info key->value pairs */
     580    for( ii = 0; IPC_INF__MAX > 1 << ii; ii++ )
     581    {
     582        if( !( types & ( 1 << ii ) ) )
    530583            continue;
    531         }
    532         jj++;
    533     }
    534     if( tr_bencDictReserve( dict, jj ) )
    535     {
    536         return -1;
    537     }
    538 
    539     for( ii = 0; IPC_INF__MAX > 1 << ii; ii++ )
    540     {
    541         if( !( types & ( 1 << ii ) ) )
    542         {
    543             continue;
    544         }
    545         /* check for missing optional info */
    546         if( ( IPC_INF_COMMENT == ( 1 << ii ) && !*inf->comment ) ||
    547             ( IPC_INF_CREATOR == ( 1 << ii ) && !*inf->creator ) ||
    548             ( IPC_INF_DATE    == ( 1 << ii ) && 0 >= inf->dateCreated ) )
    549         {
    550             continue;
    551         }
    552584
    553585        item = tr_bencDictAdd( dict, gl_inf[ii].name );
     
    555587        {
    556588            case IPC_INF_COMMENT:
    557                 tr_bencInitStr( item, inf->comment, -1, 1 );
     589                tr_bencInitStr( item, inf->comment ? inf->comment : "", -1, 1 );
    558590                break;
    559591            case IPC_INF_CREATOR:
    560                 tr_bencInitStr( item, inf->creator, -1, 1 );
     592                tr_bencInitStr( item, inf->creator ? inf->creator : "", -1, 1 );
    561593                break;
    562594            case IPC_INF_DATE:
     
    564596                break;
    565597            case IPC_INF_FILES:
    566                 tr_bencInit( item, TYPE_LIST );
    567                 if( tr_bencListReserve( item, inf->fileCount ) )
    568                 {
    569                     return -1;
    570                 }
     598                tr_bencInitList( item, inf->fileCount );
    571599                for( ff = 0; inf->fileCount > ff; ff++ )
    572600                {
    573601                    file = tr_bencListAdd( item );
    574                     tr_bencInit( file, TYPE_DICT );
    575                     if( tr_bencDictReserve( file, 2 ) )
    576                     {
    577                         return -1;
    578                     }
     602                    tr_bencInitDict( file, 2 );
    579603                    tr_bencInitStr( tr_bencDictAdd( file, "name" ),
    580604                                    inf->files[ff].name, -1, 1 );
     
    587611                break;
    588612            case IPC_INF_ID:
    589                 tr_bencInitInt( item, tor );
     613                tr_bencInitInt( item, torrent_id );
    590614                break;
    591615            case IPC_INF_NAME:
     
    602626                break;
    603627            case IPC_INF_TRACKERS:
    604                 tr_bencInit( item, TYPE_LIST );
    605                 if( tr_bencListReserve( item, inf->trackerTiers ) )
    606                 {
    607                     return -1;
    608                 }
     628                tr_bencInitList( item, inf->trackerTiers );
    609629                for( jj = 0; inf->trackerTiers > jj; jj++ )
    610630                {
    611631                    tier = tr_bencListAdd( item );
    612                     tr_bencInit( tier, TYPE_LIST );
    613                     if( tr_bencListReserve( tier,
    614                                             inf->trackerList[jj].count ) )
    615                     {
    616                         return -1;
    617                     }
     632                    tr_bencInitList( tier, inf->trackerList[jj].count );
    618633                    for( kk = 0; inf->trackerList[jj].count > kk; kk++ )
    619                     {
    620                         if( 0 > filltracker( tr_bencListAdd( tier ),
    621                                              &inf->trackerList[jj].list[kk] ) )
    622                         {
    623                             return -1;
    624                         }
    625                     }
     634                        filltracker( tr_bencListAdd( tier ),
     635                                     &inf->trackerList[jj].list[kk] );
    626636                }
    627637                break;
     
    635645}
    636646
     647/**
     648 * append to "list" a dictionary whose keys are
     649 * the string keys from gl_stat and whose values
     650 * are torrent statistics set from "st".
     651 *
     652 * "types" is a bitwise-and'ed set of fields
     653 * from the IPC_INF_* enum in ipcparse.h.
     654 * It specifies what to put in the dictionary.
     655 */
    637656int
    638 ipc_addstat( tr_benc * list, int tor,
    639              const tr_stat * st, int types )
    640 {
    641     tr_benc  * dict, * item;
    642     int           ii, used;
    643     tr_errno      error;
     657ipc_addstat( tr_benc        * list,
     658             int              torrent_id,
     659             const tr_stat  * st,
     660             int              types )
     661{
     662    tr_benc   * dict;
     663    int         ii, used;
     664
     665    /* add the dictionary child */
     666    tr_bencListReserve( list, 1 );
     667    dict = tr_bencListAdd( list );
    644668
    645669    /* always send torrent id */
    646670    types |= IPC_ST_ID;
    647671
    648     if( tr_bencListReserve( list, 1 ) )
    649         return -1;
    650 
    651     dict = tr_bencListAdd( list );
    652 
     672    /* count the number of stat keys and allocate a dict for them */
    653673    for( ii = used = 0; IPC_ST__MAX > 1 << ii; ii++ )
    654674        if( types & ( 1 << ii ) )
    655675            used++;
    656 
    657     tr_bencInit( dict, TYPE_DICT );
    658     if( tr_bencDictReserve( dict, used ) )
    659         return -1;
    660 
     676    tr_bencInitDict( dict, used );
     677
     678    /* populate the dict */
    661679    for( ii = 0; IPC_ST__MAX > 1 << ii; ii++ )
    662680    {
     681        tr_benc * item;
     682
    663683        if( !( types & ( 1 << ii ) ) )
    664684            continue;
     
    679699                tr_bencInitInt( item, st->downloadedEver );
    680700                break;
    681             case IPC_ST_ERROR:
    682                 error = st->error;
     701            case IPC_ST_ERROR: {
     702                const tr_errno error = st->error;
    683703                if( TR_OK == error )
    684704                {
     
    726746                }
    727747                break;
     748            }
    728749            case IPC_ST_ERRMSG:
    729750                if( TR_OK == st->error )
     
    744765                break;
    745766            case IPC_ST_ID:
    746                 tr_bencInitInt( item, tor );
     767                tr_bencInitInt( item, torrent_id );
    747768                break;
    748769            case IPC_ST_PEERDOWN:
     
    750771                break;
    751772            case IPC_ST_PEERFROM:
    752                 tr_bencInit( item, TYPE_DICT );
    753                 if( tr_bencDictReserve( item, 4 ) )
    754                 {
    755                     return -1;
    756                 }
     773                tr_bencInitDict( item, 4 );
    757774                tr_bencInitInt( tr_bencDictAdd( item, "incoming" ),
    758775                                st->peersFrom[TR_PEER_FROM_INCOMING] );
     
    803820                break;
    804821            case IPC_ST_TRACKER:
    805                 if( 0 > filltracker( item, st->tracker ) )
    806                 {
    807                     return -1;
    808                 }
     822                filltracker( item, st->tracker );
    809823                break;
    810824            case IPC_ST_TKDONE:
     
    905919                    gl_msgs, TR_N_ELEMENTS( gl_msgs ), sizeof( struct msg ),
    906920                    compareNameToMsg );
     921}
     922
     923enum ipc_msg
     924ipc_msgid( const struct ipc_info * info, const char * name )
     925{
     926    const struct msg * msg = msglookup( name );
     927
     928    return msg && sessionSupportsMessage( info, msg->id )
     929        ? msg->id
     930        : IPC__MSG_COUNT;
    907931}
    908932
     
    10431067}
    10441068
    1045 enum ipc_msg
    1046 ipc_msgid( const struct ipc_info * info, const char * name )
    1047 {
    1048     const struct msg * msg = msglookup( name );
    1049 
    1050     return msg && ipc_havemsg( info, msg->id )
    1051         ? msg->id
    1052         : IPC__MSG_COUNT;
    1053 }
    1054 
    1055 int
    1056 ipc_ishandled( const struct ipc_info * info, enum ipc_msg id )
    1057 {
    1058     assert( MSGVALID( id ) );
    1059 
    1060     return info->funcs->msgs[id] != NULL;
    1061 }
    1062 
    1063 int
    1064 ipc_havetags( const struct ipc_info * info )
    1065 {
    1066     return !DICTPAYLOAD( info );
    1067 }
    1068 
    10691069static int
    10701070compareNameToInf( const void * a, const void * b )
  • trunk/libtransmission/ipcparse.h

    r5143 r5498  
    153153struct tr_benc * ipc_initval  ( const struct ipc_info *, enum ipc_msg,
    154154                                int64_t tag, struct tr_benc *, int );
    155 uint8_t *    ipc_mkval    ( const struct tr_benc *, size_t * );
    156 uint8_t *    ipc_mkempty  ( const struct ipc_info *, size_t *, enum ipc_msg,
    157                             int64_t );
    158 uint8_t *    ipc_mkint    ( const struct ipc_info *, size_t *, enum ipc_msg,
    159                             int64_t tag, int64_t val );
    160 uint8_t *    ipc_mkstr    ( const struct ipc_info *, size_t *, enum ipc_msg,
    161                             int64_t tag, const char * val );
    162 uint8_t *    ipc_mkvers   ( size_t *, const char * );
    163 uint8_t *    ipc_mkgetinfo( const struct ipc_info *, size_t *, enum ipc_msg,
     155uint8_t *    ipc_serialize ( const struct tr_benc *, size_t * );
     156uint8_t *    ipc_mkempty   ( const struct ipc_info *, size_t *, enum ipc_msg,
     157                             int64_t );
     158uint8_t *    ipc_mkint     ( const struct ipc_info *, size_t *, enum ipc_msg,
     159                             int64_t tag, int64_t val );
     160uint8_t *    ipc_mkstr     ( const struct ipc_info *, size_t *, enum ipc_msg,
     161                             int64_t tag, const char * val );
     162uint8_t *    ipc_mkvers    ( size_t *, const char * );
     163uint8_t *    ipc_mkgetinfo ( const struct ipc_info *, size_t *, enum ipc_msg,
    164164                            int64_t, int, const int * );
    165 int          ipc_addinfo  ( struct tr_benc *, int,
    166                             const struct tr_info *, int );
    167 int          ipc_addstat  ( struct tr_benc *, int,
    168                             const struct tr_stat *, int );
     165int          ipc_addinfo   ( struct tr_benc *, int,
     166                             const struct tr_info *, int );
     167int          ipc_addstat   ( struct tr_benc *, int,
     168                             const struct tr_stat *, int );
    169169
    170170/* sets errno to EINVAL on parse error or
  • trunk/libtransmission/makemeta.c

    r5366 r5498  
    289289        if (*pch == TR_PATH_DELIMITER)
    290290            ++n;
    291     tr_bencInit( uninitialized_path, TYPE_LIST );
    292     tr_bencListReserve( uninitialized_path, n );
     291    tr_bencInitList( uninitialized_path, n );
    293292    for( prev=pch=file->filename+topLen; ; ++pch )
    294293    {
     
    323322        tr_benc *length, *pathVal;
    324323
    325         tr_bencInit( dict, TYPE_DICT );
    326         tr_bencDictReserve( dict, 2 );
     324        tr_bencInitDict( dict, 2 );
    327325        length = tr_bencDictAdd( dict, "length" );
    328326        pathVal = tr_bencDictAdd( dict, "path" );
     
    375373    tr_benc top, *val;
    376374
    377     tr_bencInit ( &top, TYPE_DICT );
    378375    if ( builder->comment && *builder->comment ) ++n;
    379     tr_bencDictReserve( &top, n );
     376    tr_bencInitDict( &top, n );
    380377
    381378    val = tr_bencDictAdd( &top, "announce" );
     
    403400
    404401        val = tr_bencDictAdd( &top, "info" );
    405         tr_bencInit( val, TYPE_DICT );
    406         tr_bencDictReserve( val, 666 );
     402        tr_bencInitDict( val, 666 );
    407403        makeInfoDict( val, builder );
    408404    }
  • trunk/libtransmission/peer-msgs.c

    r5329 r5498  
    872872        pex = 1;
    873873
    874     tr_bencInit( &val, TYPE_DICT );
    875     tr_bencDictReserve( &val, 4 );
     874    tr_bencInitDict( &val, 4 );
    876875    tr_bencInitInt( tr_bencDictAdd( &val, "e" ), 1 );
    877876    m  = tr_bencDictAdd( &val, "m" );
     
    18411840
    18421841        /* build the pex payload */
    1843         tr_bencInit( &val, TYPE_DICT );
    1844         tr_bencDictReserve( &val, 3 );
     1842        tr_bencInitDict( &val, 3 );
    18451843
    18461844        /* "added" */
  • trunk/libtransmission/stats.c

    r5127 r5498  
    9090    tr_benc top;
    9191
    92     tr_bencInit( &top, TYPE_DICT );
    93     tr_bencDictReserve( &top, 5 );
     92    tr_bencInitDict( &top, 5 );
    9493    tr_bencInitInt( tr_bencDictAdd( &top, "uploaded-bytes" ), stats->uploadedBytes );
    9594    tr_bencInitInt( tr_bencDictAdd( &top, "downloaded-bytes" ), stats->downloadedBytes );
  • trunk/libtransmission/transmission.h

    r5485 r5498  
    724724    char               * comment;
    725725    char               * creator;
    726     int                  dateCreated;
     726    time_t               dateCreated;
    727727
    728728    /* Pieces info */
Note: See TracChangeset for help on using the changeset viewer.