/* Copyright (c) 1993 Stephen F. White */ #include <stdio.h> #include "config.h" #include "cool.h" #include "proto.h" #include "sys_proto.h" #include "db_setup.h" #define PACK(N, f) fwrite( (char *) &(N), sizeof(N), 1, f) static void pack_methods(HashT *methods, FILE *f); static void pack_verbs(Verbdef *vbhead, FILE *f); static void pack_gvars(HashT *vars, FILE *f); static void pack_vars(Vardef *vhead, FILE *f); static void pack_symbols(Object *o, FILE *f); static void pack_locks(Lock *lhead, FILE *f); static void pack_var(Var v, FILE *f); static void pack_string(String *s, FILE *f); static void pack_list(List *list, FILE *f); int pack_object(Object *o, FILE *f) { PACK(o->id.id, f); PACK(o->id.server, f); pack_list(o->parents, f); pack_symbols(o, f); pack_methods(o->methods, f); pack_verbs(o->verbs, f); pack_gvars(o->vars, f); pack_locks(o->locks, f); return 0; } static void pack_methods(HashT *methods, FILE *f) { int intzero = 0; int hval; Method *m; unsigned char flag; if (methods) { PACK(methods->num, f); for (hval = 0; hval < methods->size; hval++) { for (m = methods->table[hval]; m; m = m->next) { PACK(m->name, f); flag = m->blocked; PACK(flag, f); PACK(m->ninst, f); fwrite((char *) m->ehandler, sizeof(m->ehandler[0]), NERRS, f); pack_vars(m->vars, f); fwrite((char *) m->code, sizeof(Inst), m->ninst, f); } } } else { PACK(intzero, f); } } static void pack_verbs(Verbdef *vbhead, FILE *f) { int nverbs = 0; Verbdef *vb; for (vb = vbhead; vb; vb = vb->next) { nverbs++; } PACK(nverbs, f); for (vb = vbhead; vb; vb = vb->next) { PACK(vb->verb, f); PACK(vb->prep, f); PACK(vb->method, f); } } static void pack_gvars(HashT *vars, FILE *f) { int hval, intzero = 0; Vardef *v; if (vars) { PACK(vars->num, f); for (hval = 0; hval < vars->size; hval++) { for (v = vars->table[hval]; v; v = v->next) { PACK(v->name, f); pack_var(v->value, f); } } } else { PACK(intzero, f); } } static void pack_vars(Vardef *vhead, FILE *f) { int nvars = 0; Vardef *v; for (v = vhead; v; v = v->next) { nvars++; } PACK(nvars, f); for (v = vhead; v; v = v->next) { PACK(v->name, f); pack_var(v->value, f); } } static void pack_var(Var v, FILE *f) { fputc((char) v.type, f); switch (v.type) { case STR: pack_string(v.v.str, f); break; case NUM: PACK(v.v.num, f); break; case OBJ: PACK(v.v.obj.id, f); PACK(v.v.obj.server, f); break; case LIST: pack_list(v.v.list, f); break; case ERR: PACK(v.v.err, f); break; case PC: /* should never happen */ break; } } static void pack_string(String *s, FILE *f) { PACK(s->len, f); fwrite(s->str, sizeof(char), s->len, f); } static void pack_list(List *list, FILE *f) { int i; PACK(list->len, f); for (i = 0; i < list->len; i++) { pack_var(list->el[i], f); } } static void pack_symbols(Object *o, FILE *f) { int i; PACK(o->nsymb, f); PACK(o->st_size, f); for (i = 0; i < o->nsymb; i++) { PACK(o->symbols[i].ref, f); if (o->symbols[i].ref) { pack_string(o->symbols[i].s, f); } } } static void pack_locks(Lock *lhead, FILE *f) { Lock *l; int nlocks = 0; for (l = lhead; l; l = l->next) { nlocks++; } PACK(nlocks, f); for (l = lhead; l; l = l->next) { pack_string(l->name, f); PACK(l->added_by, f); } }