#include "fsm.h" #include const uint8_t CH_HTML_ESCAPE[256] = { ['&'] = 1, ['<'] = 1, ['>'] = 1, ['"'] = 1, }; const uint8_t CH_JSON_ESCAPE[256] = { ['"'] = 1, ['\\'] = 1, [0x00] = 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, }; /* Inline special + HTML escape; combine with (c & 0x80) in the scan loop. */ const uint8_t CH_SCAN_STOP[256] = { ['*'] = 1, ['_'] = 1, ['`'] = 1, ['$'] = 1, ['!'] = 1, ['['] = 1, ['&'] = 1, ['<'] = 1, ['>'] = 1, ['\\'] = 1, ['~'] = 1, }; void fsm_write_begin(sashidown_ctx_t *ctx) { ctx->overflow = 0; ctx->write_ptr = ctx->output + ctx->output_len; ctx->write_end = ctx->output + ctx->output_cap - 1; } void fsm_write_end(sashidown_ctx_t *ctx) { if (ctx->write_ptr) ctx->output_len = (size_t)(ctx->write_ptr - ctx->output); ctx->write_ptr = NULL; ctx->write_end = NULL; } int fsm_append(sashidown_ctx_t *ctx, char c) { if (unlikely(ctx->overflow)) return -1; if (ctx->write_ptr) { if (unlikely(ctx->write_ptr >= ctx->write_end)) { ctx->overflow = 1; return -1; } *ctx->write_ptr++ = c; return 0; } if (unlikely(ctx->output_len + 1 >= ctx->output_cap)) { ctx->overflow = 1; return -1; } ctx->output[ctx->output_len++] = c; return 0; } int fsm_append_len(sashidown_ctx_t *restrict ctx, const char *restrict s, size_t n) { if (n == 0) return 0; if (unlikely(ctx->overflow)) return -1; if (ctx->write_ptr) { if (unlikely(ctx->write_ptr + n > ctx->write_end)) { ctx->overflow = 1; return -1; } memcpy(ctx->write_ptr, s, n); ctx->write_ptr += n; return 0; } if (unlikely(ctx->output_len + n >= ctx->output_cap)) { ctx->overflow = 1; return -1; } memcpy(ctx->output + ctx->output_len, s, n); ctx->output_len += n; return 0; } int fsm_append_str(sashidown_ctx_t *ctx, const char *s) { return fsm_append_len(ctx, s, strlen(s)); } void fsm_append_fast(sashidown_ctx_t *ctx, char c) { if (unlikely(ctx->overflow)) return; if (unlikely(ctx->write_ptr >= ctx->write_end)) { ctx->overflow = 1; return; } *ctx->write_ptr++ = c; } void fsm_append_len_fast(sashidown_ctx_t *restrict ctx, const char *restrict s, size_t n) { if (n == 0) return; if (unlikely(ctx->overflow)) return; if (unlikely(ctx->write_ptr + n > ctx->write_end)) { ctx->overflow = 1; return; } memcpy(ctx->write_ptr, s, n); ctx->write_ptr += n; }