diff options
author | Bobby Powers <bobbypowers@gmail.com> | 2011-10-04 17:06:53 -0400 |
---|---|---|
committer | Bobby Powers <bobbypowers@gmail.com> | 2011-10-04 23:20:06 -0400 |
commit | b61bf79512e705482ec30f57b5a11170e4eb72f5 (patch) | |
tree | 1164ed71360c17a694f77b102ab7709eb282ecf5 | |
parent | e2d080612f566205d16a65fdad05618f92774d4c (diff) | |
download | yajl-b61bf79512e705482ec30f57b5a11170e4eb72f5.tar.gz |
encode: use an on-stack buffer for 2-char escape sequences
When profiling my application, this sped up yajl_string_encode by
3.9%.
-rw-r--r-- | src/yajl_encode.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/yajl_encode.c b/src/yajl_encode.c index 9dc9a3e..4aeda9d 100644 --- a/src/yajl_encode.c +++ b/src/yajl_encode.c @@ -23,7 +23,7 @@ static void CharToHex(unsigned char c, char * hexBuf) { - const char * hexchar = "0123456789ABCDEF"; + static const char * hexchar = "0123456789ABCDEF"; hexBuf[0] = hexchar[c >> 4]; hexBuf[1] = hexchar[c & 0x0F]; } @@ -37,36 +37,46 @@ yajl_string_encode(const yajl_print_t print, { size_t beg = 0; size_t end = 0; + size_t escaped_len; + char escBuf[3]; char hexBuf[7]; + escBuf[0] = '\\'; + escBuf[2] = 0; hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0'; hexBuf[6] = 0; while (end < len) { const char * escaped = NULL; + escBuf[1] = 0; switch (str[end]) { - case '\r': escaped = "\\r"; break; - case '\n': escaped = "\\n"; break; - case '\\': escaped = "\\\\"; break; + case '\r': escBuf[1] = 'r'; break; + case '\n': escBuf[1] = 'n'; break; + case '\\': escBuf[1] = '\\'; break; /* it is not required to escape a solidus in JSON: * read sec. 2.5: http://www.ietf.org/rfc/rfc4627.txt * specifically, this production from the grammar: * unescaped = %x20-21 / %x23-5B / %x5D-10FFFF */ - case '/': if (escape_solidus) escaped = "\\/"; break; - case '"': escaped = "\\\""; break; - case '\f': escaped = "\\f"; break; - case '\b': escaped = "\\b"; break; - case '\t': escaped = "\\t"; break; + case '/': if (escape_solidus) escBuf[1] = '/'; break; + case '"': escBuf[1] = '"'; break; + case '\f': escBuf[1] = 'f'; break; + case '\b': escBuf[1] = 'b'; break; + case '\t': escBuf[1] = 't'; break; default: if ((unsigned char) str[end] < 32) { CharToHex(str[end], hexBuf + 4); escaped = hexBuf; + escaped_len = 6; } break; } + if (escBuf[1] != 0) { + escaped = escBuf; + escaped_len = 2; + } if (escaped != NULL) { print(ctx, (const char *) (str + beg), end - beg); - print(ctx, escaped, (unsigned int)strlen(escaped)); + print(ctx, escaped, escaped_len); beg = ++end; } else { ++end; |