mirror of
https://github.com/transmission/transmission
synced 2024-12-25 01:03:01 +00:00
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)."
This commit is contained in:
parent
a09a9c9157
commit
3d7f38fa68
1 changed files with 41 additions and 15 deletions
|
@ -397,6 +397,20 @@ char * tr_bencSaveMalloc( benc_val_t * val, int * len )
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char * key;
|
||||||
|
int index;
|
||||||
|
}
|
||||||
|
KeyIndex;
|
||||||
|
|
||||||
|
static int compareKeyIndex( const void * va, const void * vb )
|
||||||
|
{
|
||||||
|
const KeyIndex * a = (const KeyIndex *) va;
|
||||||
|
const KeyIndex * b = (const KeyIndex *) vb;
|
||||||
|
return strcmp( a->key, b->key );
|
||||||
|
}
|
||||||
|
|
||||||
int tr_bencSave( benc_val_t * val, char ** buf, int * used, int * max )
|
int tr_bencSave( benc_val_t * val, char ** buf, int * used, int * max )
|
||||||
{
|
{
|
||||||
int ii;
|
int ii;
|
||||||
|
@ -405,37 +419,49 @@ int tr_bencSave( benc_val_t * val, char ** buf, int * used, int * max )
|
||||||
{
|
{
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
if( tr_sprintf( buf, used, max, "i%"PRId64"e", val->val.i ) )
|
if( tr_sprintf( buf, used, max, "i%"PRId64"e", val->val.i ) )
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_STR:
|
case TYPE_STR:
|
||||||
if( tr_sprintf( buf, used, max, "%i:", val->val.s.i ) ||
|
if( tr_sprintf( buf, used, max, "%i:", val->val.s.i ) ||
|
||||||
tr_concat( buf, used, max, val->val.s.s, val->val.s.i ) )
|
tr_concat( buf, used, max, val->val.s.s, val->val.s.i ) )
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
case TYPE_DICT:
|
if( tr_sprintf( buf, used, max, "l" ) )
|
||||||
if( tr_sprintf( buf, used, max,
|
|
||||||
(TYPE_LIST == val->type ? "l" : "d") ) )
|
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
for( ii = 0; val->val.l.count > ii; ii++ )
|
for( ii = 0; val->val.l.count > ii; ii++ )
|
||||||
{
|
|
||||||
if( tr_bencSave( val->val.l.vals + ii, buf, used, max ) )
|
if( tr_bencSave( val->val.l.vals + ii, buf, used, max ) )
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
|
||||||
if( tr_sprintf( buf, used, max, "e" ) )
|
if( tr_sprintf( buf, used, max, "e" ) )
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case TYPE_DICT:
|
||||||
|
/* Keys must be strings and appear in sorted order
|
||||||
|
(sorted as raw strings, not alphanumerics). */
|
||||||
|
if( tr_sprintf( buf, used, max, "d" ) )
|
||||||
|
return 1;
|
||||||
|
if( 1 ) {
|
||||||
|
int i;
|
||||||
|
KeyIndex * indices = tr_new( KeyIndex, val->val.l.count );
|
||||||
|
for( ii=i=0; i<val->val.l.count; i+=2 ) {
|
||||||
|
indices[ii].key = val->val.l.vals[i].val.s.s;
|
||||||
|
indices[ii].index = i;
|
||||||
|
ii++;
|
||||||
|
}
|
||||||
|
qsort( indices, ii, sizeof(KeyIndex), compareKeyIndex );
|
||||||
|
for( i=0; i<ii; ++i ) {
|
||||||
|
const int index = indices[i].index;
|
||||||
|
if( tr_bencSave( val->val.l.vals + index, buf, used, max ) ||
|
||||||
|
tr_bencSave( val->val.l.vals + index + 1, buf, used, max ) )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
tr_free( indices );
|
||||||
|
}
|
||||||
|
if( tr_sprintf( buf, used, max, "e" ) )
|
||||||
|
return 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue