diff options
| author | Tom Smeding <tom@tomsmeding.com> | 2026-05-09 12:48:36 +0200 |
|---|---|---|
| committer | Tom Smeding <tom@tomsmeding.com> | 2026-05-09 12:49:00 +0200 |
| commit | a63a096d075797f12ed614d5029e16f55a8bc769 (patch) | |
| tree | 688b7935f43127310d31ca385969ccdef3b16a2a /cbits/escapexml.c | |
| parent | 4dc5780474753b804cfc7f095c2bc47b8229f5e2 (diff) | |
Optimisations to log rendering with mustache
Diffstat (limited to 'cbits/escapexml.c')
| -rw-r--r-- | cbits/escapexml.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/cbits/escapexml.c b/cbits/escapexml.c new file mode 100644 index 0000000..6eb366d --- /dev/null +++ b/cbits/escapexml.c @@ -0,0 +1,49 @@ +#include <string.h> +#include <stdint.h> + +// https://hackage-content.haskell.org/package/mustache-2.4.3.1/src/src/Text/Mustache/Internal.hs +// +// escapeXML :: String -> String +// escapeXML = concatMap $ \x -> IntMap.findWithDefault [x] (ord x) mp +// where mp = IntMap.fromList [(ord b, "&"++a++";") | (a,[b]) <- xmlEntities] +// +// xmlEntities :: [(String, String)] +// xmlEntities = +// [ ("quot", "\"") +// , ("#39", "'") +// , ("amp" , "&") +// , ("lt" , "<") +// , ("gt" , ">") +// ] + +#define ENTITIES_XLIST \ + X('"', 6, """) \ + X('\'', 5, "'") \ + X('&', 5, "&") \ + X('<', 4, "<") \ + X('>', 4, ">") + +size_t tirclogv_escapexml_len(const uint8_t *src, size_t src_off, size_t src_len) { + size_t reslen = 0; + for (size_t i = 0; i < src_len; i++) { + switch (src[src_off + i]) { +#define X(ch, len, _str) case ch: reslen += len; break; + ENTITIES_XLIST +#undef X + default: reslen += 1; break; + } + } + return reslen; +} + +void tirclogv_escapexml(uint8_t *dst, const uint8_t *src, size_t src_off, size_t src_len) { + for (size_t i = 0, j = 0; i < src_len; i++) { + const uint8_t c = src[src_off + i]; + switch (c) { +#define X(ch, len, str) case ch: memcpy(&dst[j], str, len); j += len; break; + ENTITIES_XLIST +#undef X + default: dst[j++] = c; break; + } + } +} |
