1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-25 17:17:31 +00:00

(trunk libT) #3836 "libevent2 support" -- optimize serialization of json strings for libevent2's new evbuffer API. This also fixes #3843

This commit is contained in:
Charles Kerr 2010-12-21 22:07:15 +00:00
parent 5eafe91824
commit e8c2f6cf15

View file

@ -1355,41 +1355,54 @@ jsonRealFunc( const tr_benc * val, void * vdata )
static void static void
jsonStringFunc( const tr_benc * val, void * vdata ) jsonStringFunc( const tr_benc * val, void * vdata )
{ {
char * out;
char * outwalk;
char * outend;
struct evbuffer_iovec vec[1];
struct jsonWalk * data = vdata; struct jsonWalk * data = vdata;
const unsigned char * it = (const unsigned char *) getStr(val); const unsigned char * it = (const unsigned char *) getStr(val);
const unsigned char * end = it + val->val.s.len; const unsigned char * end = it + val->val.s.len;
const int safeguard = 512; /* arbitrary margin for escapes and unicode */
evbuffer_expand( data->out, val->val.s.len + 2 ); evbuffer_reserve_space( data->out, val->val.s.len+safeguard, vec, 1 );
evbuffer_add( data->out, "\"", 1 ); out = vec[0].iov_base;
outend = out + vec[0].iov_len;
outwalk = out;
*outwalk++ = '"';
for( ; it!=end; ++it ) for( ; it!=end; ++it )
{ {
switch( *it ) switch( *it )
{ {
case '\b': evbuffer_add( data->out, "\\b", 2 ); break; case '\b': *outwalk++ = '\\'; *outwalk++ = 'b'; break;
case '\f': evbuffer_add( data->out, "\\f", 2 ); break; case '\f': *outwalk++ = '\\'; *outwalk++ = 'f'; break;
case '\n': evbuffer_add( data->out, "\\n", 2 ); break; case '\n': *outwalk++ = '\\'; *outwalk++ = 'n'; break;
case '\r': evbuffer_add( data->out, "\\r", 2 ); break; case '\r': *outwalk++ = '\\'; *outwalk++ = 'r'; break;
case '\t': evbuffer_add( data->out, "\\t", 2 ); break; case '\t': *outwalk++ = '\\'; *outwalk++ = 't'; break;
case '"': evbuffer_add( data->out, "\\\"", 2 ); break; case '"' : *outwalk++ = '\\'; *outwalk++ = '"'; break;
case '\\': evbuffer_add( data->out, "\\\\", 2 ); break; case '\\': *outwalk++ = '\\'; *outwalk++ = '\\'; break;
default: default:
if( isascii( *it ) ) if( isascii( *it ) )
evbuffer_add( data->out, it, 1 ); *outwalk++ = *it;
else { else {
const UTF8 * tmp = it; const UTF8 * tmp = it;
UTF32 buf = 0; UTF32 buf = 0;
UTF32 * u32 = &buf; UTF32 * u32 = &buf;
ConversionResult result = ConvertUTF8toUTF32( &tmp, end, &u32, &buf + 1, 0 ); ConversionResult result = ConvertUTF8toUTF32( &tmp, end, &u32, &buf + 1, 0 );
if((( result==conversionOK ) || (result==targetExhausted)) && (tmp!=it)) { if((( result==conversionOK ) || (result==targetExhausted)) && (tmp!=it)) {
evbuffer_add_printf( data->out, "\\u%04x", (unsigned int)buf ); outwalk += tr_snprintf( outwalk, outend-outwalk, "\\u%04x", (unsigned int)buf );
it = tmp - 1; it = tmp - 1;
} }
} }
} }
} }
evbuffer_add( data->out, "\"", 1 );
*outwalk++ = '"';
vec[0].iov_len = outwalk - out;
evbuffer_commit_space( data->out, vec, 1 );
jsonChildFunc( data ); jsonChildFunc( data );
} }