summaryrefslogtreecommitdiffstats
path: root/lib/buffer.c
diff options
context:
space:
mode:
authorGergely Nagy <algernon@balabit.hu>2012-06-22 15:06:49 +0200
committerGergely Nagy <algernon@balabit.hu>2012-06-22 15:06:49 +0200
commit88c48725d12663dd807e28d65871f8db4ac7273e (patch)
treed34485e9442e56de70c67860c3e5fdad076fe07f /lib/buffer.c
parent779645803fe70a389758b76ff01ba676b8a61999 (diff)
downloadlibumberlog-88c48725d12663dd807e28d65871f8db4ac7273e.tar.gz
libumberlog-88c48725d12663dd807e28d65871f8db4ac7273e.tar.xz
libumberlog-88c48725d12663dd807e28d65871f8db4ac7273e.zip
Use a static exception map
* Make the map static, read-only and preinitialized, to avoid thread-safety problems. * Invert the map, making it non-zero for exceptional characters (so that non-exceptional characters don't need to be mentioned) * Tighten the set of exceptional characters, so that most of ASCII goes through the fast path. This increases the speed of test_perf_* by 7.7-20.6%. Signed-off-by: Miloslav Trmač <mitr@redhat.com> Signed-off-by: Gergely Nagy <algernon@balabit.hu>
Diffstat (limited to 'lib/buffer.c')
-rw-r--r--lib/buffer.c76
1 files changed, 25 insertions, 51 deletions
diff --git a/lib/buffer.c b/lib/buffer.c
index a613c98..5cb8d3f 100644
--- a/lib/buffer.c
+++ b/lib/buffer.c
@@ -30,30 +30,10 @@
#include "config.h"
#include "buffer.h"
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
-static const unsigned char json_exceptions[] =
- {
- 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
- 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
- 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
- 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
- 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
- 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
- 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
- 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
- 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
- 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
- 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
- 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
- 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
- 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
- 0xff, '\0'
- };
-
static __thread ul_buffer_t escape_buffer;
static void ul_buffer_finish (void) __attribute__((destructor));
@@ -67,10 +47,19 @@ ul_buffer_finish (void)
static inline char *
_ul_str_escape (const char *str, char *dest, size_t *length)
{
+ /* Assumes ASCII! Keep in sync with the switch! */
+ static const unsigned char json_exceptions[UCHAR_MAX + 1] =
+ {
+ [0x01] = 1, [0x02] = 1, [0x03] = 1, [0x04] = 1, [0x05] = 1, [0x06] = 1,
+ [0x07] = 1, [0x08] = 1, [0x09] = 1, [0x0a] = 1, [0x0b] = 1, [0x0c] = 1,
+ [0x0d] = 1, [0x0e] = 1, [0x0f] = 1, [0x10] = 1, [0x11] = 1, [0x12] = 1,
+ [0x13] = 1, [0x14] = 1, [0x15] = 1, [0x16] = 1, [0x17] = 1, [0x18] = 1,
+ [0x19] = 1, [0x1a] = 1, [0x1b] = 1, [0x1c] = 1, [0x1d] = 1, [0x1e] = 1,
+ [0x1f] = 1, ['\\'] = 1, ['"'] = 1
+ };
+
const unsigned char *p;
char *q;
- static unsigned char exmap[256];
- static int exmap_inited;
if (!str)
return NULL;
@@ -78,25 +67,13 @@ _ul_str_escape (const char *str, char *dest, size_t *length)
p = (unsigned char *)str;
q = dest;
- if (!exmap_inited)
- {
- const unsigned char *e = json_exceptions;
-
- memset (exmap, 0, 256);
- while (*e)
- {
- exmap[*e] = 1;
- e++;
- }
- exmap_inited = 1;
- }
-
while (*p)
{
- if (exmap[*p])
+ if (json_exceptions[*p] == 0)
*q++ = *p;
else
{
+ /* Keep in sync with json_exceptions! */
switch (*p)
{
case '\b':
@@ -124,20 +101,17 @@ _ul_str_escape (const char *str, char *dest, size_t *length)
*q++ = '"';
break;
default:
- if ((*p < ' ') || (*p >= 0177))
- {
- static const char json_hex_chars[16] = "0123456789abcdef";
-
- *q++ = '\\';
- *q++ = 'u';
- *q++ = '0';
- *q++ = '0';
- *q++ = json_hex_chars[(*p) >> 4];
- *q++ = json_hex_chars[(*p) & 0xf];
- }
- else
- *q++ = *p;
- break;
+ {
+ static const char json_hex_chars[16] = "0123456789abcdef";
+
+ *q++ = '\\';
+ *q++ = 'u';
+ *q++ = '0';
+ *q++ = '0';
+ *q++ = json_hex_chars[(*p) >> 4];
+ *q++ = json_hex_chars[(*p) & 0xf];
+ break;
+ }
}
}
p++;