(trunk libT) #1559 (partial): add tr_bencDictMerge() + unit tests. patch by KyleK and charles_

This commit is contained in:
Charles Kerr 2008-12-12 02:12:17 +00:00
parent 659afd89be
commit 72b9845a5e
3 changed files with 203 additions and 130 deletions

View File

@ -361,6 +361,55 @@ testJSON( void )
return 0;
}
static int
testMerge( void )
{
tr_benc dest, src;
int64_t i;
const char * s;
/* initial dictionary (default values) */
tr_bencInitDict( &dest, 10 );
tr_bencDictAddInt( &dest, "i1", 1 );
tr_bencDictAddInt( &dest, "i2", 2 );
tr_bencDictAddInt( &dest, "i4", -35 ); /* remains untouched */
tr_bencDictAddStr( &dest, "s5", "abc" );
tr_bencDictAddStr( &dest, "s6", "def" );
tr_bencDictAddStr( &dest, "s7", "127.0.0.1" ); /* remains untouched */
/* new dictionary, will overwrite items in dest */
tr_bencInitDict( &src, 10 );
tr_bencDictAddInt( &src, "i1", 1 ); /* same value */
tr_bencDictAddInt( &src, "i2", 4 ); /* new value */
tr_bencDictAddInt( &src, "i3", 3 ); /* new key:value */
tr_bencDictAddStr( &src, "s5", "abc" ); /* same value */
tr_bencDictAddStr( &src, "s6", "xyz" ); /* new value */
tr_bencDictAddStr( &src, "s8", "ghi" ); /* new key:value */
tr_bencMergeDicts( &dest, /*const*/ &src );
check( tr_bencDictFindInt( &dest, "i1", &i ));
check( i == 1);
check( tr_bencDictFindInt( &dest, "i2", &i ));
check( i == 4);
check( tr_bencDictFindInt( &dest, "i3", &i ));
check( i == 3);
check( tr_bencDictFindInt( &dest, "i4", &i ));
check( i == -35);
check( tr_bencDictFindStr( &dest, "s5", &s ));
check( strcmp( "abc", s ) == 0 );
check( tr_bencDictFindStr( &dest, "s6", &s ));
check( strcmp( "xyz", s ) == 0 );
check( tr_bencDictFindStr( &dest, "s7", &s ));
check( strcmp( "127.0.0.1", s ) == 0 );
check( tr_bencDictFindStr( &dest, "s8", &s ));
check( strcmp( "ghi", s ) == 0 );
tr_bencFree( &dest );
tr_bencFree( &src );
return 0;
}
static int
testStackSmash( int depth )
{
@ -396,16 +445,19 @@ main( void )
{
int i;
if( ( i = testInt( ) ) )
if(( i = testInt( )))
return i;
if( ( i = testStr( ) ) )
if(( i = testStr( )))
return i;
if( ( i = testParse( ) ) )
if(( i = testParse( )))
return i;
if( ( i = testJSON( ) ) )
if(( i = testJSON( )))
return i;
if(( i = testMerge( )))
return i;
#ifndef WIN32

View File

@ -34,24 +34,22 @@
***
**/
int
tr_bencIsType( const tr_benc * val,
int type )
tr_bool
tr_bencIsType( const tr_benc * val, int type )
{
return ( val ) && ( val->type == type );
}
static int
static tr_bool
isContainer( const tr_benc * val )
{
return tr_bencIsList( val ) || tr_bencIsDict( val );
}
static int
static tr_bool
isSomething( const tr_benc * val )
{
return isContainer( val ) || tr_bencIsInt( val ) || tr_bencIsString(
val );
return isContainer( val ) || tr_bencIsInt( val ) || tr_bencIsString( val );
}
static void
@ -382,8 +380,7 @@ dictIndexOf( const tr_benc * val,
}
tr_benc *
tr_bencDictFind( tr_benc * val,
const char * key )
tr_bencDictFind( tr_benc * val, const char * key )
{
const int i = dictIndexOf( val, key );
@ -417,7 +414,7 @@ tr_bencListChild( tr_benc * val,
return ret;
}
int
tr_bool
tr_bencGetInt( const tr_benc * val,
int64_t * setme )
{
@ -428,7 +425,7 @@ tr_bencGetInt( const tr_benc * val,
return success;
}
int
tr_bool
tr_bencGetStr( const tr_benc * val,
const char ** setme )
{
@ -439,12 +436,10 @@ tr_bencGetStr( const tr_benc * val,
return success;
}
int
tr_bencDictFindInt( tr_benc * dict,
const char * key,
int64_t * setme )
tr_bool
tr_bencDictFindInt( tr_benc * dict, const char * key, int64_t * setme )
{
int found = FALSE;
tr_bool found = FALSE;
tr_benc * child = tr_bencDictFindType( dict, key, TYPE_INT );
if( child )
@ -452,25 +447,22 @@ tr_bencDictFindInt( tr_benc * dict,
return found;
}
int
tr_bencDictFindDouble( tr_benc * dict,
const char * key,
double * setme )
tr_bool
tr_bencDictFindDouble( tr_benc * dict, const char * key, double * setme )
{
const char * str;
const int success = tr_bencDictFindStr( dict, key, &str );
const tr_bool success = tr_bencDictFindStr( dict, key, &str );
if( success )
*setme = strtod( str, NULL );
return success;
}
int
tr_bencDictFindList( tr_benc * dict,
const char * key,
tr_benc ** setme )
tr_bool
tr_bencDictFindList( tr_benc * dict, const char * key, tr_benc ** setme )
{
int found = FALSE;
tr_bool found = FALSE;
tr_benc * child = tr_bencDictFindType( dict, key, TYPE_LIST );
if( child )
@ -478,15 +470,14 @@ tr_bencDictFindList( tr_benc * dict,
*setme = child;
found = TRUE;
}
return found;
}
int
tr_bencDictFindDict( tr_benc * dict,
const char * key,
tr_benc ** setme )
tr_bool
tr_bencDictFindDict( tr_benc * dict, const char * key, tr_benc ** setme )
{
int found = FALSE;
tr_bool found = FALSE;
tr_benc * child = tr_bencDictFindType( dict, key, TYPE_DICT );
if( child )
@ -494,15 +485,14 @@ tr_bencDictFindDict( tr_benc * dict,
*setme = child;
found = TRUE;
}
return found;
}
int
tr_bencDictFindStr( tr_benc * dict,
const char * key,
const char ** setme )
tr_bool
tr_bencDictFindStr( tr_benc * dict, const char * key, const char ** setme )
{
int found = FALSE;
tr_bool found = FALSE;
tr_benc * child = tr_bencDictFindType( dict, key, TYPE_STR );
if( child )
@ -510,16 +500,17 @@ tr_bencDictFindStr( tr_benc * dict,
*setme = child->val.s.s;
found = TRUE;
}
return found;
}
int
tr_bencDictFindRaw( tr_benc * dict,
const char * key,
const uint8_t ** setme_raw,
size_t * setme_len )
tr_bool
tr_bencDictFindRaw( tr_benc * dict,
const char * key,
const uint8_t ** setme_raw,
size_t * setme_len )
{
int found = FALSE;
tr_bool found = FALSE;
tr_benc * child = tr_bencDictFindType( dict, key, TYPE_STR );
if( child )
@ -528,6 +519,7 @@ tr_bencDictFindRaw( tr_benc * dict,
*setme_len = child->val.s.i;
found = TRUE;
}
return found;
}
@ -1316,6 +1308,76 @@ tr_bencSaveAsJSON( const tr_benc * top,
****
***/
static size_t
tr_bencDictSize( const tr_benc * dict )
{
size_t count = 0;
if( tr_bencIsDict( dict ) )
count = dict->val.l.count / 2;
return count;
}
static tr_bool
tr_bencDictChild( const tr_benc * dict, size_t n, const char ** key, const tr_benc ** val )
{
tr_bool success = 0;
assert( tr_bencIsDict( dict ) );
if( tr_bencIsDict( dict ) && (n*2)+1 <= dict->val.l.count )
{
tr_benc * k = dict->val.l.vals + (n*2);
tr_benc * v = dict->val.l.vals + (n*2) + 1;
if(( success = tr_bencGetStr( k, key ) && isSomething( v )))
*val = v;
}
return success;
}
void
tr_bencMergeDicts( tr_benc * target, const tr_benc * source )
{
size_t i;
const size_t sourceCount = tr_bencDictSize( source );
assert( tr_bencIsDict( target ) );
assert( tr_bencIsDict( source ) );
for( i=0; i<sourceCount; ++i )
{
const char * key;
const tr_benc * val;
if( tr_bencDictChild( source, i, &key, &val ) )
{
int64_t i64;
const char * str;
if( tr_bencGetInt( val, &i64 ) )
{
tr_bencDictRemove( target, key );
tr_bencDictAddInt( target, key, i64 );
}
else if( tr_bencGetStr( val, &str ) )
{
tr_bencDictRemove( target, key );
tr_bencDictAddStr( target, key, str );
}
else
{
tr_err( "tr_bencMergeDicts skipping \"%s\"", key );
}
}
}
}
/***
****
***/
static int
saveFile( const char * filename,
const char * content,

View File

@ -70,139 +70,92 @@ void tr_bencPrint( const tr_benc * );
void tr_bencFree( tr_benc * );
char* tr_bencSave( const tr_benc * val,
int * len );
char* tr_bencSave( const tr_benc * val, int * len );
char* tr_bencSaveAsJSON( const tr_benc * top,
int * len );
char* tr_bencSaveAsJSON( const tr_benc * top, int * len );
int tr_bencSaveFile( const char * filename,
const tr_benc * );
int tr_bencSaveFile( const char * filename, const tr_benc * );
int tr_bencSaveJSONFile( const char * filename,
const tr_benc * );
int tr_bencSaveJSONFile( const char * filename, const tr_benc * );
void tr_bencInitStr( tr_benc *,
const void * str,
int str_len );
void tr_bencInitStr( tr_benc *, const void * str, int str_len );
void tr_bencInitRaw( tr_benc *,
const void * raw,
size_t raw_len );
void tr_bencInitRaw( tr_benc *, const void * raw, size_t raw_len );
void tr_bencInitInt( tr_benc *,
int64_t num );
void tr_bencInitInt( tr_benc *, int64_t num );
int tr_bencInitDict( tr_benc *,
size_t reserveCount );
int tr_bencInitDict( tr_benc *, size_t reserveCount );
int tr_bencInitList( tr_benc *,
size_t reserveCount );
int tr_bencInitList( tr_benc *, size_t reserveCount );
/***
****
***/
int tr_bencListReserve( tr_benc *,
size_t reserveCount );
int tr_bencListReserve( tr_benc *, size_t reserveCount );
tr_benc * tr_bencListAdd( tr_benc * );
tr_benc * tr_bencListAddInt( tr_benc *,
int64_t val );
tr_benc * tr_bencListAddInt( tr_benc *, int64_t val );
tr_benc * tr_bencListAddStr( tr_benc *,
const char * val );
tr_benc * tr_bencListAddStr( tr_benc *, const char * val );
tr_benc * tr_bencListAddList( tr_benc *,
size_t reserveCount );
tr_benc * tr_bencListAddList( tr_benc *, size_t reserveCount );
tr_benc * tr_bencListAddDict( tr_benc *,
size_t reserveCount );
tr_benc * tr_bencListAddDict( tr_benc *, size_t reserveCount );
size_t tr_bencListSize( const tr_benc * list );
tr_benc * tr_bencListChild( tr_benc * list,
size_t n );
tr_benc * tr_bencListChild( tr_benc * list, size_t n );
/***
****
***/
int tr_bencDictReserve( tr_benc *,
size_t reserveCount );
int tr_bencDictReserve( tr_benc *, size_t reserveCount );
int tr_bencDictRemove( tr_benc *,
const char * key );
int tr_bencDictRemove( tr_benc *, const char * key );
tr_benc * tr_bencDictAdd( tr_benc *,
const char * key );
tr_benc * tr_bencDictAdd( tr_benc *, const char * key );
tr_benc * tr_bencDictAddDouble( tr_benc *,
const char * key,
double d );
tr_benc * tr_bencDictAddDouble( tr_benc *, const char * key, double );
tr_benc * tr_bencDictAddInt( tr_benc *,
const char * key,
int64_t val );
tr_benc * tr_bencDictAddInt( tr_benc *, const char * key, int64_t );
tr_benc * tr_bencDictAddStr( tr_benc *,
const char * key,
const char * val );
tr_benc * tr_bencDictAddStr( tr_benc *, const char * key, const char * );
tr_benc * tr_bencDictAddList( tr_benc *,
const char * key,
size_t reserve );
tr_benc * tr_bencDictAddList( tr_benc *, const char * key, size_t reserve );
tr_benc * tr_bencDictAddDict( tr_benc *,
const char * key,
size_t reserve );
tr_benc * tr_bencDictAddDict( tr_benc *, const char * key, size_t reserve );
tr_benc * tr_bencDictAddRaw( tr_benc *,
const char * key,
const void *,
size_t len );
tr_benc * tr_bencDictAddRaw( tr_benc *, const char * key,
const void * raw, size_t rawlen );
tr_benc* tr_bencDictFind( tr_benc *,
const char * key );
tr_benc* tr_bencDictFind( tr_benc *, const char * key );
int tr_bencDictFindList( tr_benc *,
const char * key,
tr_benc ** setme );
tr_bool tr_bencDictFindList( tr_benc *, const char * key, tr_benc ** setme );
int tr_bencDictFindDict( tr_benc *,
const char * key,
tr_benc ** setme );
tr_bool tr_bencDictFindDict( tr_benc *, const char * key, tr_benc ** setme );
int tr_bencDictFindInt( tr_benc *,
const char * key,
int64_t * setme );
tr_bool tr_bencDictFindInt( tr_benc *, const char * key, int64_t * setme );
int tr_bencDictFindDouble( tr_benc *,
const char * key,
double * setme );
tr_bool tr_bencDictFindDouble( tr_benc *, const char * key, double * setme );
int tr_bencDictFindStr( tr_benc *,
const char * key,
const char ** setme );
tr_bool tr_bencDictFindStr( tr_benc *, const char * key, const char ** setme );
int tr_bencDictFindRaw( tr_benc *,
const char * key,
const uint8_t ** setme_raw,
size_t * setme_len );
tr_bool tr_bencDictFindRaw( tr_benc *, const char * key,
const uint8_t ** setme_raw, size_t * setme_len );
/***
****
***/
int tr_bencGetInt( const tr_benc * val,
int64_t * setme );
tr_bool tr_bencGetInt( const tr_benc * val, int64_t * setme );
int tr_bencGetStr( const tr_benc * val,
const char ** setme );
tr_bool tr_bencGetStr( const tr_benc * val, const char ** setme );
tr_bool tr_bencIsType( const tr_benc *, int type );
int tr_bencIsType( const tr_benc *,
int type );
#define tr_bencIsInt( b ) tr_bencIsType( ( b ), TYPE_INT )
#define tr_bencIsDict( b ) tr_bencIsType( ( b ), TYPE_DICT )
@ -225,4 +178,10 @@ int tr_bencParseStr( const uint8_t * buf,
const uint8_t ** setme_str,
size_t * setme_strlen );
/**
***
**/
void tr_bencMergeDicts( tr_benc * b1, const tr_benc * b2 );
#endif