mirror of
https://github.com/transmission/transmission
synced 2025-03-03 02:05:19 +00:00
(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.
This commit is contained in:
parent
bf3bdda68f
commit
8a8c8711d8
3 changed files with 196 additions and 89 deletions
|
@ -13,15 +13,6 @@
|
|||
|
||||
2. Message Format
|
||||
|
||||
Messages are formatted in a subset of JSON easily represented
|
||||
as bencoded data. Arrays, objects, strings, and whole numbers
|
||||
all have one-to-one mappings between JSON and benc.
|
||||
|
||||
Booleans and floating-point numbers are also used in the JSON messages.
|
||||
Those two types aren't native to benc, so they're encoded this way:
|
||||
Booleans are encoded as numbers where 0 is false and 1 is true.
|
||||
Floating-point numbers are represented as strings.
|
||||
|
||||
Messages are formatted as objects. There are two types:
|
||||
requests (described in 2.1) and responses (described in 2.2).
|
||||
|
||||
|
@ -98,19 +89,19 @@
|
|||
string | value type & description
|
||||
----------------------------------+-------------------------------------------------
|
||||
"downloadLimit" | number maximum download speed (in K/s)
|
||||
"downloadLimited" | 'boolean' true if "downloadLimit" is honored
|
||||
"downloadLimited" | boolean true if "downloadLimit" is honored
|
||||
"files-wanted" | array indices of file(s) to download
|
||||
"files-unwanted" | array indices of file(s) to not download
|
||||
"honorsSessionLimits" | 'boolean' true if session upload limits are honored
|
||||
"honorsSessionLimits" | boolean true if session upload limits are honored
|
||||
"ids" | array torrent list, as described in 3.1
|
||||
"peer-limit" | number maximum number of peers
|
||||
"priority-high" | array indices of high-priority file(s)
|
||||
"priority-low" | array indices of low-priority file(s)
|
||||
"priority-normal" | array indices of normal-priority file(s)
|
||||
"seedRatioLimit" | 'double' session seeding ratio
|
||||
"seedRatioLimit" | double session seeding ratio
|
||||
"seedRatioMode" | number which ratio to use. See tr_ratiolimit
|
||||
"uploadLimit" | number maximum upload speed (in K/s)
|
||||
"uploadLimited" | 'boolean' true if "uploadLimit" is honored
|
||||
"uploadLimited" | boolean true if "uploadLimit" is honored
|
||||
|
||||
Just as an empty "ids" value is shorthand for "all ids", using an empty array
|
||||
for "files-wanted", "files-unwanted", "priority-high", "priority-low", or
|
||||
|
@ -151,7 +142,7 @@
|
|||
downloadedEver | number | tr_stat
|
||||
downloaders | number | tr_stat
|
||||
downloadLimit | number | tr_torrent
|
||||
downloadLimited | 'boolean' | tr_torrent
|
||||
downloadLimited | boolean | tr_torrent
|
||||
error | number | tr_stat
|
||||
errorString | number | tr_stat
|
||||
eta | number | tr_stat
|
||||
|
@ -160,9 +151,9 @@
|
|||
hashString | string | tr_info
|
||||
haveUnchecked | number | tr_stat
|
||||
haveValid | number | tr_stat
|
||||
honorsSessionLimits | 'boolean' | tr_torrent
|
||||
honorsSessionLimits | boolean | tr_torrent
|
||||
id | number | tr_torrent
|
||||
isPrivate | 'boolean' | tr_torrent
|
||||
isPrivate | boolean | tr_torrent
|
||||
lastAnnounceTime | number | tr_stat
|
||||
lastScrapeTime | number | tr_stat
|
||||
leechers | number | tr_stat
|
||||
|
@ -179,19 +170,19 @@
|
|||
peersGettingFromUs | number | tr_stat
|
||||
peersKnown | number | tr_stat
|
||||
peersSendingToUs | number | tr_stat
|
||||
percentDone | 'double' | tr_stat
|
||||
percentDone | double | tr_stat
|
||||
pieces | string (see below) | tr_torrent
|
||||
pieceCount | tnumber | tr_info
|
||||
pieceSize | tnumber | tr_info
|
||||
priorities | array (see below) | n/a
|
||||
ratio | 'double' | tr_stat
|
||||
ratio | double | tr_stat
|
||||
rateDownload (B/s) | number | tr_stat
|
||||
rateUpload (B/s) | number | tr_stat
|
||||
recheckProgress | 'double' | tr_stat
|
||||
recheckProgress | double | tr_stat
|
||||
scrapeResponse | string | tr_stat
|
||||
scrapeURL | string | tr_stat
|
||||
seeders | number | tr_stat
|
||||
seedRatioLimit | 'double' | tr_torrent
|
||||
seedRatioLimit | double | tr_torrent
|
||||
seedRatioMode | number | tr_ratiolimit
|
||||
sizeWhenDone | number | tr_stat
|
||||
startDate | number | tr_stat
|
||||
|
@ -203,8 +194,8 @@
|
|||
torrentFile | string | tr_info
|
||||
uploadedEver | number | tr_stat
|
||||
uploadLimit | number | tr_torrent
|
||||
uploadLimited | 'boolean' | tr_torrent
|
||||
uploadRatio | 'double' | tr_stat
|
||||
uploadLimited | boolean | tr_torrent
|
||||
uploadRatio | double | tr_stat
|
||||
wanted | array (see below) | n/a
|
||||
webseeds | array (see below) | n/a
|
||||
webseedsSendingToUs | number | tr_stat
|
||||
|
@ -223,23 +214,23 @@
|
|||
| each containing: |
|
||||
+-------------------------+------------+
|
||||
| bytesCompleted | number | tr_torrent
|
||||
| wanted | 'boolean' | tr_info
|
||||
| wanted | boolean | tr_info
|
||||
| priority | number | tr_info
|
||||
-----------------------+--------------------------------------+
|
||||
peers | array of objects, each containing: |
|
||||
+-------------------------+------------+
|
||||
| address | string | tr_peer_stat
|
||||
| clientName | string | tr_peer_stat
|
||||
| clientIsChoked | 'boolean' | tr_peer_stat
|
||||
| clientIsInterested | 'boolean' | tr_peer_stat
|
||||
| isDownloadingFrom | 'boolean' | tr_peer_stat
|
||||
| isEncrypted | 'boolean' | tr_peer_stat
|
||||
| isIncoming | 'boolean' | tr_peer_stat
|
||||
| isUploadingTo | 'boolean' | tr_peer_stat
|
||||
| peerIsChoked | 'boolean' | tr_peer_stat
|
||||
| peerIsInterested | 'boolean' | tr_peer_stat
|
||||
| clientIsChoked | boolean | tr_peer_stat
|
||||
| clientIsInterested | boolean | tr_peer_stat
|
||||
| isDownloadingFrom | boolean | tr_peer_stat
|
||||
| isEncrypted | boolean | tr_peer_stat
|
||||
| isIncoming | boolean | tr_peer_stat
|
||||
| isUploadingTo | boolean | tr_peer_stat
|
||||
| peerIsChoked | boolean | tr_peer_stat
|
||||
| peerIsInterested | boolean | tr_peer_stat
|
||||
| port | number | tr_peer_stat
|
||||
| progress | 'double' | tr_peer_stat
|
||||
| progress | double | tr_peer_stat
|
||||
| rateToClient (B/s) | number | tr_peer_stat
|
||||
| rateToPeer (B/s) | number | tr_peer_stat
|
||||
-----------------------+--------------------------------------+
|
||||
|
@ -323,7 +314,7 @@
|
|||
"download-dir" | string path to download the torrent to
|
||||
"filename" | string filename or URL of the .torrent file
|
||||
"metainfo" | string base64-encoded .torrent content
|
||||
"paused" | 'boolean' if true, don't start the torrent
|
||||
"paused" | boolean if true, don't start the torrent
|
||||
"peer-limit" | number maximum number of peers
|
||||
"files-wanted" | array indices of file(s) to download
|
||||
"files-unwanted" | array indices of file(s) to not download
|
||||
|
@ -347,7 +338,7 @@
|
|||
string | value type & description
|
||||
---------------------------+-------------------------------------------------
|
||||
"ids" | array torrent list, as described in 3.1
|
||||
"delete-local-data" | 'boolean' delete local data. (default: false)
|
||||
"delete-local-data" | boolean delete local data. (default: false)
|
||||
|
||||
Response arguments: none
|
||||
|
||||
|
@ -359,30 +350,30 @@
|
|||
string | value type & description
|
||||
---------------------------+-------------------------------------------------
|
||||
"alt-speed-down" | number max global download speed (in K/s)
|
||||
"alt-speed-enabled" | 'boolean' true means use the alt speeds
|
||||
"alt-speed-enabled" | boolean true means use the alt speeds
|
||||
"alt-speed-time-begin" | number when to turn on alt speeds (units: minutes after midnight)
|
||||
"alt-speed-time-enabled" | 'boolean' true means the scheduled on/off times are used
|
||||
"alt-speed-time-enabled" | boolean true means the scheduled on/off times are used
|
||||
"alt-speed-time-end" | number when to turn off alt speeds (units: same)
|
||||
"alt-speed-time-day" | number what day(s) to turn on alt speeds (look at tr_sched_day)
|
||||
"alt-speed-up" | number max global upload speed (in K/s)
|
||||
"blocklist-enabled" | 'boolean' true means enabled
|
||||
"blocklist-enabled" | boolean true means enabled
|
||||
"blocklist-size" | number number of rules in the blocklist
|
||||
"encryption" | string "required", "preferred", "tolerated"
|
||||
"download-dir" | string default path to download torrents
|
||||
"peer-limit-global" | number maximum global number of peers
|
||||
"peer-limit-per-torrent" | number maximum global number of peers
|
||||
"pex-enabled" | 'boolean' true means allow pex in public torrents
|
||||
"pex-enabled" | boolean true means allow pex in public torrents
|
||||
"peer-port" | number port number
|
||||
"peer-port-random-on-start"| 'boolean' true means pick a random peer port on launch
|
||||
"port-forwarding-enabled" | 'boolean' true means enabled
|
||||
"peer-port-random-on-start"| boolean true means pick a random peer port on launch
|
||||
"port-forwarding-enabled" | boolean true means enabled
|
||||
"rpc-version" | number the current RPC API version
|
||||
"rpc-version-minimum" | number the minimum RPC API version supported
|
||||
"seedRatioLimit" | 'double' the default seed ratio for torrents to use
|
||||
"seedRatioLimited" | 'boolean' true if seedRatioLimit is honored by default
|
||||
"seedRatioLimit" | double the default seed ratio for torrents to use
|
||||
"seedRatioLimited" | boolean true if seedRatioLimit is honored by default
|
||||
"speed-limit-down" | number max global download speed (in K/s)
|
||||
"speed-limit-down-enabled" | 'boolean' true means enabled
|
||||
"speed-limit-down-enabled" | boolean true means enabled
|
||||
"speed-limit-up" | number max global upload speed (in K/s)
|
||||
"speed-limit-up-enabled" | 'boolean' true means enabled
|
||||
"speed-limit-up-enabled" | boolean true means enabled
|
||||
"version" | string long version string "$version ($revision)"
|
||||
|
||||
"rpc-version" indicates the RPC interface version supported by the RPC server.
|
||||
|
|
|
@ -414,10 +414,17 @@ tr_bool
|
|||
tr_bencGetInt( const tr_benc * val,
|
||||
int64_t * setme )
|
||||
{
|
||||
const tr_bool success = tr_bencIsInt( val );
|
||||
tr_bool success = FALSE;
|
||||
|
||||
if( success && setme )
|
||||
*setme = val->val.i;
|
||||
if( !success && (( success = tr_bencIsInt( val ))))
|
||||
if( setme )
|
||||
*setme = val->val.i;
|
||||
|
||||
if( !success && (( success = tr_bencIsBool( val )))) {
|
||||
fprintf( stderr, "warning: reading bool as an int\n" );
|
||||
if( setme )
|
||||
*setme = val->val.b ? 1 : 0;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -439,6 +446,9 @@ tr_bencGetBool( const tr_benc * val, tr_bool * setme )
|
|||
{
|
||||
tr_bool success = FALSE;
|
||||
|
||||
if(( success = tr_bencIsBool( val )))
|
||||
*setme = val->val.b;
|
||||
|
||||
if( !success && tr_bencIsInt( val ) )
|
||||
if(( success = ( val->val.i==0 || val->val.i==1 ) ))
|
||||
*setme = val->val.i!=0;
|
||||
|
@ -455,6 +465,12 @@ tr_bencGetReal( const tr_benc * val, double * setme )
|
|||
{
|
||||
tr_bool success = FALSE;
|
||||
|
||||
if( !success && (( success = tr_bencIsReal( val ))))
|
||||
*setme = val->val.d;
|
||||
|
||||
if( !success && (( success = tr_bencIsInt( val ))))
|
||||
*setme = val->val.i;
|
||||
|
||||
if( !success && tr_bencIsString(val) )
|
||||
{
|
||||
char * endptr;
|
||||
|
@ -472,11 +488,6 @@ tr_bencGetReal( const tr_benc * val, double * setme )
|
|||
*setme = d;
|
||||
}
|
||||
|
||||
if( !success && tr_bencIsInt(val) )
|
||||
{
|
||||
success = TRUE;
|
||||
*setme = val->val.i;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -598,43 +609,52 @@ tr_bencInitStr( tr_benc * val,
|
|||
}
|
||||
|
||||
void
|
||||
tr_bencInitInt( tr_benc * val,
|
||||
int64_t num )
|
||||
tr_bencInitBool( tr_benc * b, int value )
|
||||
{
|
||||
tr_bencInit( val, TYPE_INT );
|
||||
val->val.i = num;
|
||||
tr_bencInit( b, TYPE_BOOL );
|
||||
b->val.b = value != 0;
|
||||
}
|
||||
|
||||
void
|
||||
tr_bencInitReal( tr_benc * b, double value )
|
||||
{
|
||||
tr_bencInit( b, TYPE_REAL );
|
||||
b->val.d = value;
|
||||
}
|
||||
|
||||
void
|
||||
tr_bencInitInt( tr_benc * b, int64_t value )
|
||||
{
|
||||
tr_bencInit( b, TYPE_INT );
|
||||
b->val.i = value;
|
||||
}
|
||||
|
||||
int
|
||||
tr_bencInitList( tr_benc * val,
|
||||
size_t reserveCount )
|
||||
tr_bencInitList( tr_benc * b, size_t reserveCount )
|
||||
{
|
||||
tr_bencInit( val, TYPE_LIST );
|
||||
return tr_bencListReserve( val, reserveCount );
|
||||
tr_bencInit( b, TYPE_LIST );
|
||||
return tr_bencListReserve( b, reserveCount );
|
||||
}
|
||||
|
||||
int
|
||||
tr_bencListReserve( tr_benc * val,
|
||||
size_t count )
|
||||
tr_bencListReserve( tr_benc * b, size_t count )
|
||||
{
|
||||
assert( tr_bencIsList( val ) );
|
||||
return makeroom( val, count );
|
||||
assert( tr_bencIsList( b ) );
|
||||
return makeroom( b, count );
|
||||
}
|
||||
|
||||
int
|
||||
tr_bencInitDict( tr_benc * val,
|
||||
size_t reserveCount )
|
||||
tr_bencInitDict( tr_benc * b, size_t reserveCount )
|
||||
{
|
||||
tr_bencInit( val, TYPE_DICT );
|
||||
return tr_bencDictReserve( val, reserveCount );
|
||||
tr_bencInit( b, TYPE_DICT );
|
||||
return tr_bencDictReserve( b, reserveCount );
|
||||
}
|
||||
|
||||
int
|
||||
tr_bencDictReserve( tr_benc * val,
|
||||
size_t reserveCount )
|
||||
tr_bencDictReserve( tr_benc * b, size_t reserveCount )
|
||||
{
|
||||
assert( tr_bencIsDict( val ) );
|
||||
return makeroom( val, reserveCount * 2 );
|
||||
assert( tr_bencIsDict( b ) );
|
||||
return makeroom( b, reserveCount * 2 );
|
||||
}
|
||||
|
||||
tr_benc *
|
||||
|
@ -716,16 +736,14 @@ tr_bencDictAdd( tr_benc * dict,
|
|||
return itemval;
|
||||
}
|
||||
|
||||
tr_benc*
|
||||
tr_bencDictAddInt( tr_benc * dict,
|
||||
const char * key,
|
||||
int64_t val )
|
||||
static tr_benc*
|
||||
dictFindOrAdd( tr_benc * dict, const char * key, int type )
|
||||
{
|
||||
tr_benc * child;
|
||||
|
||||
/* see if it already exists, and if so, try to reuse it */
|
||||
if(( child = tr_bencDictFind( dict, key ))) {
|
||||
if( !tr_bencIsInt( child ) ) {
|
||||
if( !tr_bencIsType( child, type ) ) {
|
||||
tr_bencDictRemove( dict, key );
|
||||
child = NULL;
|
||||
}
|
||||
|
@ -735,18 +753,33 @@ tr_bencDictAddInt( tr_benc * dict,
|
|||
if( child == NULL )
|
||||
child = tr_bencDictAdd( dict, key );
|
||||
|
||||
/* set it */
|
||||
tr_bencInitInt( child, val );
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_benc*
|
||||
tr_bencDictAddInt( tr_benc * dict,
|
||||
const char * key,
|
||||
int64_t val )
|
||||
{
|
||||
tr_benc * child = dictFindOrAdd( dict, key, TYPE_INT );
|
||||
tr_bencInitInt( child, val );
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_benc*
|
||||
tr_bencDictAddBool( tr_benc * dict, const char * key, tr_bool val )
|
||||
{
|
||||
assert( tr_isBool( val ) );
|
||||
tr_benc * child = dictFindOrAdd( dict, key, TYPE_BOOL );
|
||||
tr_bencInitBool( child, val );
|
||||
return child;
|
||||
}
|
||||
|
||||
return tr_bencDictAddInt( dict, key, val );
|
||||
tr_benc*
|
||||
tr_bencDictAddReal( tr_benc * dict, const char * key, double val )
|
||||
{
|
||||
tr_benc * child = dictFindOrAdd( dict, key, TYPE_REAL );
|
||||
tr_bencInitReal( child, val );
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_benc*
|
||||
|
@ -774,9 +807,11 @@ tr_bencDictAddStr( tr_benc * dict, const char * key, const char * val )
|
|||
return child;
|
||||
}
|
||||
|
||||
#if 0
|
||||
tr_benc*
|
||||
tr_bencDictAddReal( tr_benc * dict, const char * key, double d )
|
||||
{
|
||||
ccc
|
||||
char buf[128];
|
||||
char * locale;
|
||||
|
||||
|
@ -789,6 +824,7 @@ tr_bencDictAddReal( tr_benc * dict, const char * key, double d )
|
|||
|
||||
return tr_bencDictAddStr( dict, key, buf );
|
||||
}
|
||||
#endif
|
||||
|
||||
tr_benc*
|
||||
tr_bencDictAddList( tr_benc * dict,
|
||||
|
@ -960,6 +996,8 @@ typedef void ( *BencWalkFunc )( const tr_benc * val, void * user_data );
|
|||
struct WalkFuncs
|
||||
{
|
||||
BencWalkFunc intFunc;
|
||||
BencWalkFunc boolFunc;
|
||||
BencWalkFunc realFunc;
|
||||
BencWalkFunc stringFunc;
|
||||
BencWalkFunc dictBeginFunc;
|
||||
BencWalkFunc listBeginFunc;
|
||||
|
@ -1011,6 +1049,14 @@ bencWalk( const tr_benc * top,
|
|||
walkFuncs->intFunc( val, user_data );
|
||||
break;
|
||||
|
||||
case TYPE_BOOL:
|
||||
walkFuncs->boolFunc( val, user_data );
|
||||
break;
|
||||
|
||||
case TYPE_REAL:
|
||||
walkFuncs->realFunc( val, user_data );
|
||||
break;
|
||||
|
||||
case TYPE_STR:
|
||||
walkFuncs->stringFunc( val, user_data );
|
||||
break;
|
||||
|
@ -1050,6 +1096,31 @@ saveIntFunc( const tr_benc * val,
|
|||
evbuffer_add_printf( evbuf, "i%" PRId64 "e", val->val.i );
|
||||
}
|
||||
|
||||
static void
|
||||
saveBoolFunc( const tr_benc * val, void * evbuf )
|
||||
{
|
||||
evbuffer_add_printf( evbuf, "i%de", val->val.b?1:0 );
|
||||
}
|
||||
|
||||
static void
|
||||
saveRealFunc( const tr_benc * val, void * evbuf )
|
||||
{
|
||||
char buf[128];
|
||||
char * locale;
|
||||
size_t len;
|
||||
|
||||
/* always use a '.' decimal point s.t. locale-hopping doesn't bite us */
|
||||
locale = tr_strdup( setlocale ( LC_NUMERIC, NULL ) );
|
||||
setlocale( LC_NUMERIC, "POSIX" );
|
||||
tr_snprintf( buf, sizeof( buf ), "%f", val->val.d );
|
||||
setlocale( LC_NUMERIC, locale );
|
||||
tr_free( locale );
|
||||
|
||||
len = strlen( buf );
|
||||
evbuffer_add_printf( evbuf, "%lu:", (unsigned long)buf );
|
||||
evbuffer_add( evbuf, buf, len );
|
||||
}
|
||||
|
||||
static void
|
||||
saveStringFunc( const tr_benc * val,
|
||||
void * vevbuf )
|
||||
|
@ -1090,6 +1161,8 @@ tr_bencSave( const tr_benc * top,
|
|||
struct evbuffer * out = tr_getBuffer( );
|
||||
|
||||
walkFuncs.intFunc = saveIntFunc;
|
||||
walkFuncs.boolFunc = saveBoolFunc;
|
||||
walkFuncs.realFunc = saveRealFunc;
|
||||
walkFuncs.stringFunc = saveStringFunc;
|
||||
walkFuncs.dictBeginFunc = saveDictBeginFunc;
|
||||
walkFuncs.listBeginFunc = saveListBeginFunc;
|
||||
|
@ -1136,6 +1209,8 @@ tr_bencFree( tr_benc * val )
|
|||
struct WalkFuncs walkFuncs;
|
||||
|
||||
walkFuncs.intFunc = freeDummyFunc;
|
||||
walkFuncs.boolFunc = freeDummyFunc;
|
||||
walkFuncs.realFunc = freeDummyFunc;
|
||||
walkFuncs.stringFunc = freeStringFunc;
|
||||
walkFuncs.dictBeginFunc = freeContainerBeginFunc;
|
||||
walkFuncs.listBeginFunc = freeContainerBeginFunc;
|
||||
|
@ -1235,6 +1310,31 @@ jsonIntFunc( const tr_benc * val,
|
|||
jsonChildFunc( data );
|
||||
}
|
||||
|
||||
static void
|
||||
jsonBoolFunc( const tr_benc * val, void * vdata )
|
||||
{
|
||||
struct jsonWalk * data = vdata;
|
||||
|
||||
evbuffer_add_printf( data->out, "%s", (val->val.b?"true":"false") );
|
||||
jsonChildFunc( data );
|
||||
}
|
||||
|
||||
static void
|
||||
jsonRealFunc( const tr_benc * val, void * vdata )
|
||||
{
|
||||
struct jsonWalk * data = vdata;
|
||||
char * locale;
|
||||
|
||||
/* json requires a '.' decimal point regardless of locale */
|
||||
locale = tr_strdup( setlocale ( LC_NUMERIC, NULL ) );
|
||||
setlocale( LC_NUMERIC, "POSIX" );
|
||||
evbuffer_add_printf( data->out, "%f", val->val.d );
|
||||
setlocale( LC_NUMERIC, locale );
|
||||
tr_free( locale );
|
||||
|
||||
jsonChildFunc( data );
|
||||
}
|
||||
|
||||
static void
|
||||
jsonStringFunc( const tr_benc * val,
|
||||
void * vdata )
|
||||
|
@ -1366,6 +1466,8 @@ tr_bencSaveAsJSON( const tr_benc * top, struct evbuffer * out )
|
|||
data.parents = NULL;
|
||||
|
||||
walkFuncs.intFunc = jsonIntFunc;
|
||||
walkFuncs.boolFunc = jsonBoolFunc;
|
||||
walkFuncs.realFunc = jsonRealFunc;
|
||||
walkFuncs.stringFunc = jsonStringFunc;
|
||||
walkFuncs.dictBeginFunc = jsonDictBeginFunc;
|
||||
walkFuncs.listBeginFunc = jsonListBeginFunc;
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#ifndef TR_BENCODE_H
|
||||
#define TR_BENCODE_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h> /* for int64_t */
|
||||
|
||||
struct evbuffer;
|
||||
|
@ -22,7 +26,9 @@ enum
|
|||
TYPE_INT = 1,
|
||||
TYPE_STR = 2,
|
||||
TYPE_LIST = 4,
|
||||
TYPE_DICT = 8
|
||||
TYPE_DICT = 8,
|
||||
TYPE_BOOL = 16,
|
||||
TYPE_REAL = 32
|
||||
};
|
||||
|
||||
typedef struct tr_benc
|
||||
|
@ -30,13 +36,19 @@ typedef struct tr_benc
|
|||
char type;
|
||||
union
|
||||
{
|
||||
int64_t i;
|
||||
struct
|
||||
uint8_t b; /* bool type */
|
||||
|
||||
double d; /* double type */
|
||||
|
||||
int64_t i; /* int type */
|
||||
|
||||
struct /* string type */
|
||||
{
|
||||
size_t i;
|
||||
char * s;
|
||||
} s;
|
||||
struct
|
||||
|
||||
struct /* list & dict types */
|
||||
{
|
||||
size_t alloc;
|
||||
size_t count;
|
||||
|
@ -45,10 +57,6 @@ typedef struct tr_benc
|
|||
} val;
|
||||
} tr_benc;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
@ -96,6 +104,10 @@ int tr_bencInitDict( tr_benc *, size_t reserveCount );
|
|||
|
||||
int tr_bencInitList( tr_benc *, size_t reserveCount );
|
||||
|
||||
void tr_bencInitBool( tr_benc *, int value );
|
||||
|
||||
void tr_bencInitReal( tr_benc *, double value );
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
@ -172,6 +184,8 @@ static TR_INLINE tr_bool tr_bencIsInt ( const tr_benc * b ) { return tr_bencIs
|
|||
static TR_INLINE tr_bool tr_bencIsDict ( const tr_benc * b ) { return tr_bencIsType( b, TYPE_DICT ); }
|
||||
static TR_INLINE tr_bool tr_bencIsList ( const tr_benc * b ) { return tr_bencIsType( b, TYPE_LIST ); }
|
||||
static TR_INLINE tr_bool tr_bencIsString( const tr_benc * b ) { return tr_bencIsType( b, TYPE_STR ); }
|
||||
static TR_INLINE tr_bool tr_bencIsBool ( const tr_benc * b ) { return tr_bencIsType( b, TYPE_BOOL ); }
|
||||
static TR_INLINE tr_bool tr_bencIsReal ( const tr_benc * b ) { return tr_bencIsType( b, TYPE_REAL ); }
|
||||
|
||||
/**
|
||||
*** Treat these as private -- they're only made public here
|
||||
|
|
Loading…
Reference in a new issue