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 )
{
{
int i;
- if( ( i = testInt( ) ) )
+ if(( i = testInt( )))
+ return i;
+
+ if(( i = testStr( )))
return i;
- if( ( i = testStr( ) ) )
+ if(( i = testParse( )))
return i;
- if( ( i = testParse( ) ) )
+ if(( i = testJSON( )))
return i;
- if( ( i = testJSON( ) ) )
+ if(( i = testMerge( )))
return i;
#ifndef WIN32
***
**/
-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
}
tr_benc *
-tr_bencDictFind( tr_benc * val,
- const char * key )
+tr_bencDictFind( tr_benc * val, const char * key )
{
const int i = dictIndexOf( val, key );
return ret;
}
-int
+tr_bool
tr_bencGetInt( const tr_benc * val,
int64_t * setme )
{
return success;
}
-int
+tr_bool
tr_bencGetStr( const tr_benc * val,
const char ** setme )
{
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 )
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 )
*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 )
*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 )
*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 )
*setme_len = child->val.s.i;
found = TRUE;
}
+
return found;
}
****
***/
+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,
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 )
const uint8_t ** setme_str,
size_t * setme_strlen );
+/**
+***
+**/
+
+void tr_bencMergeDicts( tr_benc * b1, const tr_benc * b2 );
+
#endif