#include #include #include static void dtepack(Fmt *f, DTExpr *e) { int i; fmtprint(f, "e%d\n", e->n); for(i = 0; i < e->n; i++) fmtprint(f, "%#.8ux\n", e->b[i]); } void dtgpack(Fmt *f, DTActGr *g) { int i; fmtprint(f, "g%ud\n", g->id); if(g->pred != nil){ fmtprint(f, "p"); dtepack(f, g->pred); } fmtprint(f, "a%d\n", g->nact); for(i = 0; i < g->nact; i++){ fmtprint(f, "t%d\n", g->acts[i].type); fmtprint(f, "s%d\n", g->acts[i].size); dtepack(f, g->acts[i].p); switch(g->acts[i].type){ case ACTAGGKEY: case ACTAGGVAL: fmtprint(f, "A%#.8ux\n", g->acts[i].agg.id); break; } } fmtprint(f, "G"); } void dtclpack(Fmt *f, DTClause *c) { int i; fmtprint(f, "c%d\n", c->nprob); for(i = 0; i < c->nprob; i++) fmtprint(f, "%s\n", c->probs[i]); dtgpack(f, c->gr); } static char * u32unpack(char *s, u32int *np) { char *r; *np = strtoul(s, &r, 0); if(r == s || *r != '\n') return nil; return r + 1; } static char * dteunpack(char *s, DTExpr **rp) { int i; u32int n; DTExpr *e; *rp = nil; if(*s++ != 'e') return nil; s = u32unpack(s, &n); if(s == nil) return nil; e = dtmalloc(sizeof(DTExpr) + n * sizeof(u32int)); e->n = n; e->b = (void*)(e + 1); for(i = 0; i < n; i++){ s = u32unpack(s, &e->b[i]); if(s == nil){ dtfree(e); return nil; } } *rp = e; return s; } void dtgfree(DTActGr *g) { int i; if(g == nil) return; for(i = 0; i < g->nact; i++) dtfree(g->acts[i].p); dtfree(g->acts); dtfree(g->pred); dtfree(g); } char * dtgunpack(char *s, DTActGr **rp) { DTActGr *g; u32int n; int i; *rp = nil; g = dtmalloc(sizeof(DTActGr)); g->reclen = 12; g->ref = 1; if(*s++ != 'g') goto fail; s = u32unpack(s, &g->id); if(s == nil) goto fail; for(;;) switch(*s++){ case 'p': s = dteunpack(s, &g->pred); if(s == nil) goto fail; break; case 'a': s = u32unpack(s, &n); if(s == nil) goto fail; g->acts = dtmalloc(n * sizeof(DTAct)); g->nact = n; for(i = 0; i < n; i++){ if(*s++ != 't') goto fail; s = u32unpack(s, (u32int *) &g->acts[i].type); if(s == nil) goto fail; if(*s++ != 's') goto fail; s = u32unpack(s, (u32int *) &g->acts[i].size); if(s == nil) goto fail; s = dteunpack(s, &g->acts[i].p); if(s == nil) goto fail; switch(g->acts[i].type){ case ACTTRACE: g->reclen += g->acts[i].size; break; case ACTTRACESTR: g->reclen += g->acts[i].size; break; case ACTAGGKEY: if(*s++ != 'A') goto fail; s = u32unpack(s, (u32int *) &g->acts[i].agg.id); if(s == nil) goto fail; break; case ACTAGGVAL: if(*s++ != 'A') goto fail; s = u32unpack(s, (u32int *) &g->acts[i].agg.id); if(s == nil) goto fail; break; case ACTCANCEL: break; default: goto fail; } } break; case 'G': *rp = g; return s; default: goto fail; } fail: dtgfree(g); return nil; } char * dtclunpack(char *s, DTClause **rp) { DTClause *c; char *e; int i; *rp = nil; c = dtmalloc(sizeof(DTClause)); if(*s++ != 'c') goto fail; s = u32unpack(s, (u32int*) &c->nprob); if(s == nil) goto fail; c->probs = dtmalloc(sizeof(char *) * c->nprob); for(i = 0; i < c->nprob; i++){ e = strchr(s, '\n'); if(e == nil) goto fail; c->probs[i] = dtmalloc(e - s + 1); memmove(c->probs[i], s, e - s); s = e + 1; } s = dtgunpack(s, &c->gr); if(s == nil) goto fail; *rp = c; return s; fail: dtclfree(c); return nil; } void dtclfree(DTClause *c) { int i; if(c == nil) return; if(c->gr != nil && --c->gr->ref == 0) dtgfree(c->gr); for(i = 0; i < c->nprob; i++) free(c->probs[i]); free(c->probs); free(c); }