#include #include #include #include "girzu.h" typedef void *(*Transformer)(void *aux, void *data); /* transformation chains, codec.c */ typedef struct Transform Transform; struct Transform { void *aux; Transformer decode; Transformer encode; char name[32]; }; typedef struct Codec Codec; struct Codec { WaitGroup; int nstack; Transform *stack; }; Codec *newcodec(void); int appendcodec(Codec*, void *aux, Transformer decode, Transformer encode, char *name); int runcodec(Codec*); int stopcodec(Codec*); Codec* newcodec(void) { return mallocz(sizeof(Codec), 1); } typedef struct CodecCtx CodecCtx; struct CodecCtx { WaitGroup *wg; Channel *in; Channel *out; Channel *cancel; Transform *t; }; static void codecproc(void *v) { int rv, dec, enc; void *in, *inr, *out, *outr; CodecCtx *ctx; ctx = v; Alt a[] = { [0] { ctx->in, &in, CHANRCV }, [1] { ctx->out, &inr, CHANNOP }, [2] { ctx->cancel, nil, CHANRCV }, [3] { nil, nil, CHANEND }, }; for(;;){ rv = alt(a); /* switch(rv){ case -1: fprint(2, "codecproc %s: interrupted: %r\n", ctx->t->name); goto done; case 0: inr = ctx->t->decode(ctx->t->aux, in); case 1: case 2: case 3: } */ } done: wgdone(ctx->wg); threadexits(nil); } int appendcodec(Codec *c, void *aux, Transformer decode, Transformer encode, char *name) { Transform *newstack, *t; newstack = realloc(c->stack, c->nstack * sizeof(Transform)); if(newstack == nil) return -1; t = &c->stack[c->nstack++]; t->aux = aux; t->decode = decode; t->encode = encode; snprint(t->name, sizeof(t->name), "%s", name); return 0; } void usage(void) { fprint(2, "usage: %s\n", argv0); threadexitsall("usage"); } void threadmain(int argc, char *argv[]) { ARGBEGIN{ default: usage(); }ARGEND threadexitsall(nil); }