Ignore:
Timestamp:
Apr 5, 2009, 5:52:21 PM (13 years ago)
Author:
charles
Message:

(trunk) Use proper notation for json floating-point and bool types. For backwards compatability, still allow old-style printf strings as doubles, and 0s and 1s as bools.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bencode.c

    r8114 r8154  
    415415               int64_t *       setme )
    416416{
    417     const tr_bool success = tr_bencIsInt( val );
    418 
    419     if( success && setme )
    420         *setme = val->val.i;
     417    tr_bool success = FALSE;
     418
     419    if( !success && (( success = tr_bencIsInt( val ))))
     420        if( setme )
     421            *setme = val->val.i;
     422
     423    if( !success && (( success = tr_bencIsBool( val )))) {
     424        fprintf( stderr, "warning: reading bool as an int\n" );
     425        if( setme )
     426            *setme = val->val.b ? 1 : 0;
     427    }
    421428
    422429    return success;
     
    440447    tr_bool success = FALSE;
    441448
     449    if(( success = tr_bencIsBool( val )))
     450        *setme = val->val.b;
     451
    442452    if( !success && tr_bencIsInt( val ) )
    443453        if(( success = ( val->val.i==0 || val->val.i==1 ) ))
     
    455465{
    456466    tr_bool success = FALSE;
     467
     468    if( !success && (( success = tr_bencIsReal( val ))))
     469        *setme = val->val.d;
     470
     471    if( !success && (( success = tr_bencIsInt( val ))))
     472        *setme = val->val.i;
    457473
    458474    if( !success && tr_bencIsString(val) )
     
    473489    }
    474490
    475     if( !success && tr_bencIsInt(val) )
    476     {
    477         success = TRUE;
    478         *setme = val->val.i;
    479     }
    480491
    481492    return success;
     
    599610
    600611void
    601 tr_bencInitInt( tr_benc * val,
    602                 int64_t   num )
    603 {
    604     tr_bencInit( val, TYPE_INT );
    605     val->val.i = num;
     612tr_bencInitBool( tr_benc * b, int value )
     613{
     614    tr_bencInit( b, TYPE_BOOL );
     615    b->val.b = value != 0;
     616}
     617
     618void
     619tr_bencInitReal( tr_benc * b, double value )
     620{
     621    tr_bencInit( b, TYPE_REAL );
     622    b->val.d = value;
     623}
     624
     625void
     626tr_bencInitInt( tr_benc * b, int64_t value )
     627{
     628    tr_bencInit( b, TYPE_INT );
     629    b->val.i = value;
    606630}
    607631
    608632int
    609 tr_bencInitList( tr_benc * val,
    610                  size_t    reserveCount )
    611 {
    612     tr_bencInit( val, TYPE_LIST );
    613     return tr_bencListReserve( val, reserveCount );
     633tr_bencInitList( tr_benc * b, size_t reserveCount )
     634{
     635    tr_bencInit( b, TYPE_LIST );
     636    return tr_bencListReserve( b, reserveCount );
    614637}
    615638
    616639int
    617 tr_bencListReserve( tr_benc * val,
    618                     size_t    count )
    619 {
    620     assert( tr_bencIsList( val ) );
    621     return makeroom( val, count );
     640tr_bencListReserve( tr_benc * b, size_t count )
     641{
     642    assert( tr_bencIsList( b ) );
     643    return makeroom( b, count );
    622644}
    623645
    624646int
    625 tr_bencInitDict( tr_benc * val,
    626                  size_t    reserveCount )
    627 {
    628     tr_bencInit( val, TYPE_DICT );
    629     return tr_bencDictReserve( val, reserveCount );
     647tr_bencInitDict( tr_benc * b, size_t reserveCount )
     648{
     649    tr_bencInit( b, TYPE_DICT );
     650    return tr_bencDictReserve( b, reserveCount );
    630651}
    631652
    632653int
    633 tr_bencDictReserve( tr_benc * val,
    634                     size_t    reserveCount )
    635 {
    636     assert( tr_bencIsDict( val ) );
    637     return makeroom( val, reserveCount * 2 );
     654tr_bencDictReserve( tr_benc * b, size_t reserveCount )
     655{
     656    assert( tr_bencIsDict( b ) );
     657    return makeroom( b, reserveCount * 2 );
    638658}
    639659
     
    717737}
    718738
     739static tr_benc*
     740dictFindOrAdd( tr_benc * dict, const char * key, int type )
     741{
     742    tr_benc * child;
     743
     744    /* see if it already exists, and if so, try to reuse it */
     745    if(( child = tr_bencDictFind( dict, key ))) {
     746        if( !tr_bencIsType( child, type ) ) {
     747            tr_bencDictRemove( dict, key );
     748            child = NULL;
     749        }
     750    }
     751
     752    /* if it doesn't exist, create it */
     753    if( child == NULL )
     754        child = tr_bencDictAdd( dict, key );
     755
     756    return child;
     757}
     758
    719759tr_benc*
    720760tr_bencDictAddInt( tr_benc *    dict,
     
    722762                   int64_t      val )
    723763{
    724     tr_benc * child;
    725 
    726     /* see if it already exists, and if so, try to reuse it */
    727     if(( child = tr_bencDictFind( dict, key ))) {
    728         if( !tr_bencIsInt( child ) ) {
    729             tr_bencDictRemove( dict, key );
    730             child = NULL;
    731         }
    732     }
    733 
    734     /* if it doesn't exist, create it */
    735     if( child == NULL )
    736         child = tr_bencDictAdd( dict, key );
    737 
    738     /* set it */
     764    tr_benc * child = dictFindOrAdd( dict, key, TYPE_INT );
    739765    tr_bencInitInt( child, val );
    740 
    741766    return child;
    742767}
     
    745770tr_bencDictAddBool( tr_benc * dict, const char * key, tr_bool val )
    746771{
    747     assert( tr_isBool( val ) );
    748 
    749     return tr_bencDictAddInt( dict, key, val );
     772    tr_benc * child = dictFindOrAdd( dict, key, TYPE_BOOL );
     773    tr_bencInitBool( child, val );
     774    return child;
     775}
     776
     777tr_benc*
     778tr_bencDictAddReal( tr_benc * dict, const char * key, double val )
     779{
     780    tr_benc * child = dictFindOrAdd( dict, key, TYPE_REAL );
     781    tr_bencInitReal( child, val );
     782    return child;
    750783}
    751784
     
    775808}
    776809
     810#if 0
    777811tr_benc*
    778812tr_bencDictAddReal( tr_benc * dict, const char * key, double d )
    779813{
     814    ccc
    780815    char buf[128];
    781816    char * locale;
     
    790825    return tr_bencDictAddStr( dict, key, buf );
    791826}
     827#endif
    792828
    793829tr_benc*
     
    961997{
    962998    BencWalkFunc    intFunc;
     999    BencWalkFunc    boolFunc;
     1000    BencWalkFunc    realFunc;
    9631001    BencWalkFunc    stringFunc;
    9641002    BencWalkFunc    dictBeginFunc;
     
    10121050                    break;
    10131051
     1052                case TYPE_BOOL:
     1053                    walkFuncs->boolFunc( val, user_data );
     1054                    break;
     1055
     1056                case TYPE_REAL:
     1057                    walkFuncs->realFunc( val, user_data );
     1058                    break;
     1059
    10141060                case TYPE_STR:
    10151061                    walkFuncs->stringFunc( val, user_data );
     
    10521098
    10531099static void
     1100saveBoolFunc( const tr_benc * val, void * evbuf )
     1101{
     1102    evbuffer_add_printf( evbuf, "i%de", val->val.b?1:0 );
     1103}
     1104
     1105static void
     1106saveRealFunc( const tr_benc * val, void * evbuf )
     1107{
     1108    char buf[128];
     1109    char * locale;
     1110    size_t len;
     1111
     1112    /* always use a '.' decimal point s.t. locale-hopping doesn't bite us */
     1113    locale = tr_strdup( setlocale ( LC_NUMERIC, NULL ) );
     1114    setlocale( LC_NUMERIC, "POSIX" );
     1115    tr_snprintf( buf, sizeof( buf ), "%f", val->val.d );
     1116    setlocale( LC_NUMERIC, locale );
     1117    tr_free( locale );
     1118
     1119    len = strlen( buf );
     1120    evbuffer_add_printf( evbuf, "%lu:", (unsigned long)buf );
     1121    evbuffer_add( evbuf, buf, len );
     1122}
     1123
     1124static void
    10541125saveStringFunc( const tr_benc * val,
    10551126                void *          vevbuf )
     
    10911162
    10921163    walkFuncs.intFunc = saveIntFunc;
     1164    walkFuncs.boolFunc = saveBoolFunc;
     1165    walkFuncs.realFunc = saveRealFunc;
    10931166    walkFuncs.stringFunc = saveStringFunc;
    10941167    walkFuncs.dictBeginFunc = saveDictBeginFunc;
     
    11371210
    11381211        walkFuncs.intFunc = freeDummyFunc;
     1212        walkFuncs.boolFunc = freeDummyFunc;
     1213        walkFuncs.realFunc = freeDummyFunc;
    11391214        walkFuncs.stringFunc = freeStringFunc;
    11401215        walkFuncs.dictBeginFunc = freeContainerBeginFunc;
     
    12331308
    12341309    evbuffer_add_printf( data->out, "%" PRId64, val->val.i );
     1310    jsonChildFunc( data );
     1311}
     1312
     1313static void
     1314jsonBoolFunc( const tr_benc * val, void * vdata )
     1315{
     1316    struct jsonWalk * data = vdata;
     1317
     1318    evbuffer_add_printf( data->out, "%s", (val->val.b?"true":"false") );
     1319    jsonChildFunc( data );
     1320}
     1321
     1322static void
     1323jsonRealFunc( const tr_benc * val, void * vdata )
     1324{
     1325    struct jsonWalk * data = vdata;
     1326    char * locale;
     1327
     1328    /* json requires a '.' decimal point regardless of locale */
     1329    locale = tr_strdup( setlocale ( LC_NUMERIC, NULL ) );
     1330    setlocale( LC_NUMERIC, "POSIX" );
     1331    evbuffer_add_printf( data->out, "%f", val->val.d );
     1332    setlocale( LC_NUMERIC, locale );
     1333    tr_free( locale );
     1334
    12351335    jsonChildFunc( data );
    12361336}
     
    13671467
    13681468    walkFuncs.intFunc = jsonIntFunc;
     1469    walkFuncs.boolFunc = jsonBoolFunc;
     1470    walkFuncs.realFunc = jsonRealFunc;
    13691471    walkFuncs.stringFunc = jsonStringFunc;
    13701472    walkFuncs.dictBeginFunc = jsonDictBeginFunc;
Note: See TracChangeset for help on using the changeset viewer.