/* 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" 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); #define UNPACK(N, f) fread( (GENPTR) &(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); if (nmethods == 0) return; 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((char *) m->ehandler, sizeof(m->ehandler[0]), NERRS, f); m->vars = unpack_vars(f); if (m->ninst > 0) { m->code = MALLOC(Inst, m->ninst); fread( (GENPTR) 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); if (!nvars) return; 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 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 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; }