summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby Powers <bobbypowers@gmail.com>2011-10-04 17:06:53 -0400
committerBobby Powers <bobbypowers@gmail.com>2011-10-04 23:20:06 -0400
commitb61bf79512e705482ec30f57b5a11170e4eb72f5 (patch)
tree1164ed71360c17a694f77b102ab7709eb282ecf5
parente2d080612f566205d16a65fdad05618f92774d4c (diff)
downloadyajl-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.c30
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;