diff options
Diffstat (limited to 'llparse/src/implementation/c/helpers')
-rw-r--r-- | llparse/src/implementation/c/helpers/match-sequence.ts | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/llparse/src/implementation/c/helpers/match-sequence.ts b/llparse/src/implementation/c/helpers/match-sequence.ts new file mode 100644 index 0000000..278f4b5 --- /dev/null +++ b/llparse/src/implementation/c/helpers/match-sequence.ts @@ -0,0 +1,75 @@ +import * as assert from 'assert'; +import { Buffer } from 'buffer'; +import * as frontend from 'llparse-frontend'; + +import { + SEQUENCE_COMPLETE, SEQUENCE_MISMATCH, SEQUENCE_PAUSE, +} from '../constants'; +import { Transform } from '../transform'; +import { Compilation } from '../compilation'; + +type TransformWrap = Transform<frontend.transform.Transform>; + +export class MatchSequence { + constructor(private readonly transform: TransformWrap) { + } + + public static buildGlobals(out: string[]): void { + out.push('enum llparse_match_status_e {'); + out.push(` ${SEQUENCE_COMPLETE},`); + out.push(` ${SEQUENCE_PAUSE},`); + out.push(` ${SEQUENCE_MISMATCH}`); + out.push('};'); + out.push('typedef enum llparse_match_status_e llparse_match_status_t;'); + out.push(''); + out.push('struct llparse_match_s {'); + out.push(' llparse_match_status_t status;'); + out.push(' const unsigned char* current;'); + out.push('};'); + out.push('typedef struct llparse_match_s llparse_match_t;'); + } + + public getName(): string { + return `llparse__match_sequence_${this.transform.ref.name}`; + } + + public build(ctx: Compilation, out: string[]): void { + out.push(`static llparse_match_t ${this.getName()}(`); + out.push(` ${ctx.prefix}_t* s, const unsigned char* p,`); + out.push(' const unsigned char* endp,'); + out.push(' const unsigned char* seq, uint32_t seq_len) {'); + + // Vars + out.push(' uint32_t index;'); + out.push(' llparse_match_t res;'); + out.push(''); + + // Body + out.push(' index = s->_index;'); + out.push(' for (; p != endp; p++) {'); + out.push(' unsigned char current;'); + out.push(''); + out.push(` current = ${this.transform.build(ctx, '*p')};`); + out.push(' if (current == seq[index]) {'); + out.push(' if (++index == seq_len) {'); + out.push(` res.status = ${SEQUENCE_COMPLETE};`); + out.push(' goto reset;'); + out.push(' }'); + out.push(' } else {'); + out.push(` res.status = ${SEQUENCE_MISMATCH};`); + out.push(' goto reset;'); + out.push(' }'); + out.push(' }'); + + out.push(' s->_index = index;'); + out.push(` res.status = ${SEQUENCE_PAUSE};`); + out.push(' res.current = p;'); + out.push(' return res;'); + + out.push('reset:'); + out.push(' s->_index = 0;'); + out.push(' res.current = p;'); + out.push(' return res;'); + out.push('}'); + } +} |