/* Copyright (c) 1993 Stephen F. White */ #include "cool.h" #include "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); static void pack_map (Map * map, 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 MAP: pack_map (v.v.map, 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_map (Map * map, FILE * f) { int i; MapPair *pair; PACK (map->num, f); for (i = 0; i < map->size; i++) { for (pair = map->table[i]; pair; pair = pair->next) { pack_var (pair->from, f); pack_var (pair->to, 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); } }