/* Copyright (c) 1993 Stephen F. White */ #include "cool.h" #include "proto.h" #include "db_setup.h" static void unpack_methods (Object * o, FILE * f); static Verbdef *unpack_verbs (FILE * f); static void unpack_gvars (Object * o, FILE * f); static Vardef *unpack_vars (FILE * f); static void unpack_symbols (Object * o, FILE * f); static Lock *unpack_locks (FILE * f); static Var unpack_var (FILE * f); static String *unpack_string (FILE * f); static List *unpack_list (FILE * f); static Map *unpack_map (FILE * f); #define UNPACK(N, f) fread( (void *) &(N), sizeof(N), 1, f) Object *unpack_object (FILE * f) { Object *o = new_object (); UNPACK (o->id.id, f); UNPACK (o->id.server, f); o->parents = unpack_list (f); unpack_symbols (o, f); unpack_methods (o, f); o->verbs = unpack_verbs (f); unpack_gvars (o, f); o->locks = unpack_locks (f); return o; } static void unpack_methods (Object * o, FILE * f) { int i, nmethods; Method *m; unsigned char flag; UNPACK (nmethods, f); o->methods = hash_new (nmethods / HASH_INIT_LOAD); for (i = 0; i < nmethods; i++) { m = MALLOC (Method, 1); UNPACK (m->name, f); UNPACK (flag, f); m->blocked = flag; UNPACK (m->ninst, f); fread ((void *) m->ehandler, sizeof (m->ehandler[0]), NERRS, f); m->vars = unpack_vars (f); if (m->ninst > 0) { m->code = MALLOC (Inst, m->ninst); fread ((void *) m->code, sizeof (Inst), m->ninst, f); } /* if */ m->ref = 1; m->next = 0; add_method (o, m); } /* for */ } static Verbdef *unpack_verbs (FILE * f) { int nverbs; Verbdef *vb, *prev = 0, *head = 0; UNPACK (nverbs, f); while (nverbs--) { vb = MALLOC (Verbdef, 1); UNPACK (vb->verb, f); UNPACK (vb->prep, f); UNPACK (vb->method, f); vb->next = 0; if (prev) { prev->next = vb; } else { head = vb; } prev = vb; } return head; } static void unpack_gvars (Object * o, FILE * f) { int nvars, name; UNPACK (nvars, f); o->vars = hash_new (nvars / HASH_INIT_LOAD); while (nvars--) { UNPACK (name, f); var_add_global (o, name, unpack_var (f)); } } static Vardef *unpack_vars (FILE * f) { int nvars = 0; Vardef *v, *prev = 0, *head = 0; UNPACK (nvars, f); while (nvars--) { v = MALLOC (Vardef, 1); UNPACK (v->name, f); v->value = unpack_var (f); v->next = 0; if (prev) { prev->next = v; } else { head = v; } prev = v; } return head; } static Var unpack_var (FILE * f) { Var v; v.type = (Type_spec) fgetc (f); switch (v.type) { case STR: v.v.str = unpack_string (f); break; case NUM: UNPACK (v.v.num, f); break; case OBJ: UNPACK (v.v.obj.id, f); UNPACK (v.v.obj.server, f); break; case LIST: v.v.list = unpack_list (f); break; case MAP: v.v.map = unpack_map (f); break; case ERR: UNPACK (v.v.err, f); break; case PC: /* should never happen */ break; } return v; } static String *unpack_string (FILE * f) { String *s; int len; UNPACK (len, f); s = string_new (len + 1); fread (s->str, sizeof (char), len, f); s->str[len] = '\0'; s->len = len; return s; } static List *unpack_list (FILE * f) { int i; List *list = MALLOC (List, 1); UNPACK (list->len, f); list->mem = list->len; if (list->len > 0) { list->el = MALLOC (Var, list->len); } for (i = 0; i < list->len; i++) { list->el[i] = unpack_var (f); } list->ref = 1; return list; } static Map *unpack_map (FILE * f) { int i, nels; Map *map; Var from, to; UNPACK (nels, f); map = map_new (nels); for (i = 0; i < nels; i++) { from = unpack_var (f); to = unpack_var (f); map = map_add (map, from, to); } return map; } static void unpack_symbols (Object * o, FILE * f) { int i; UNPACK (o->nsymb, f); UNPACK (o->st_size, f); if (o->st_size > 0) { o->symbols = MALLOC (Symbol, o->st_size); } for (i = 0; i < o->nsymb; i++) { UNPACK (o->symbols[i].ref, f); if (o->symbols[i].ref) { o->symbols[i].s = unpack_string (f); } } } static Lock *unpack_locks (FILE * f) { Lock *l, *prev = 0, *head = 0; int nlocks = 0; UNPACK (nlocks, f); while (nlocks--) { l = MALLOC (Lock, 1); l->name = unpack_string (f); UNPACK (l->added_by, f); l->next = 0; if (prev) { prev->next = l; } else { head = l; } prev = l; } return head; }