Changeset 2228


Ignore:
Timestamp:
Jun 29, 2007, 2:27:00 AM (15 years ago)
Author:
charles
Message:

get the bencoded text compliant with the bittorrent spec w.r.t. dictionaries: "keys must be strings and appear in sorted order (sorted as raw strings, not alphanumerics)."

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bencode.c

    r2163 r2228  
    398398}
    399399
     400typedef struct
     401{
     402    const char * key;
     403    int index;
     404}
     405KeyIndex;
     406
     407static int compareKeyIndex( const void * va, const void * vb )
     408{
     409    const KeyIndex * a = (const KeyIndex *) va;
     410    const KeyIndex * b = (const KeyIndex *) vb;
     411    return strcmp( a->key, b->key );
     412}
     413
    400414int tr_bencSave( benc_val_t * val, char ** buf, int * used, int * max )
    401415{
     
    406420        case TYPE_INT:
    407421            if( tr_sprintf( buf, used, max, "i%"PRId64"e", val->val.i ) )
    408             {
    409                 return 1;
    410             }
     422                return 1;
    411423            break;
    412424
     
    414426            if( tr_sprintf( buf, used, max, "%i:", val->val.s.i ) ||
    415427                tr_concat( buf, used,  max, val->val.s.s, val->val.s.i ) )
    416             {
    417                 return 1;
    418             }
     428                return 1;
    419429            break;
    420430
    421431        case TYPE_LIST:
     432            if( tr_sprintf( buf, used, max, "l" ) )
     433                return 1;
     434            for( ii = 0; val->val.l.count > ii; ii++ )
     435                if( tr_bencSave( val->val.l.vals + ii, buf, used, max ) )
     436                    return 1;
     437            if( tr_sprintf( buf, used, max, "e" ) )
     438                return 1;
     439            break;
     440
    422441        case TYPE_DICT:
    423             if( tr_sprintf( buf, used, max,
    424                             (TYPE_LIST == val->type ? "l" : "d") ) )
    425             {
    426                 return 1;
    427             }
    428             for( ii = 0; val->val.l.count > ii; ii++ )
    429             {
    430                 if( tr_bencSave( val->val.l.vals + ii, buf, used, max ) )
    431                 {
    432                     return 1;
     442            /* Keys must be strings and appear in sorted order
     443               (sorted as raw strings, not alphanumerics). */
     444            if( tr_sprintf( buf, used, max, "d" ) )
     445                return 1;
     446            if( 1 ) {
     447                int i;
     448                KeyIndex * indices = tr_new( KeyIndex, val->val.l.count );
     449                for( ii=i=0; i<val->val.l.count; i+=2 ) {
     450                    indices[ii].key = val->val.l.vals[i].val.s.s;
     451                    indices[ii].index = i;
     452                    ii++;
    433453                }
    434             }
     454                qsort( indices, ii, sizeof(KeyIndex), compareKeyIndex );
     455                for( i=0; i<ii; ++i ) {
     456                    const int index = indices[i].index;
     457                    if( tr_bencSave( val->val.l.vals + index,     buf, used, max ) ||
     458                        tr_bencSave( val->val.l.vals + index + 1, buf, used, max ) )
     459                        return 1;
     460                }
     461                tr_free( indices );
     462            }
    435463            if( tr_sprintf( buf, used, max, "e" ) )
    436             {
    437                 return 1;
    438             }
     464                return 1;
    439465            break;
    440466    }
Note: See TracChangeset for help on using the changeset viewer.