#include #include #include #include #include #include #include #include #include #include #include // packet class implementation /* the list of classes */ static pf_list_t *class_list; void pf_class_setup(void){ class_list = pf_list_new(); } /* class methods */ pf_class_t * pf_class_new(pf_symbol_t *type, pf_method_list2packet_t create){ pf_class_t *c = (pf_class_t *)pf_alloc(sizeof(pf_class_t)); memset(c, 0, sizeof(pf_class_t)); c->create = create; c->type = type; // set type pf_list_push(class_list, a_pointer, (pf_word_t)((void *)c)); return c; } void pf_class_set_cleanup(pf_class_t *class, pf_method_pheader_t m) {class->cleanup = m;} void pf_class_set_sleep(pf_class_t *class, pf_method_pheader_t m) {class->sleep = m;} void pf_class_set_wakeup(pf_class_t *class, pf_method_pheader_t m) {class->wakeup = m;} void pf_class_set_print(pf_class_t *class, pf_method_pheader_string_t m) {class->print = m;} void pf_class_set_write(pf_class_t *class, pf_method_pheader_string_t m) {class->write = m;} void pf_class_set_report(pf_class_t *class, pf_method_pheader_string_t m) {class->report = m;} //void pf_class_set_copydata(pf_class_t *class, pf_method_pheader2_t m) {class->copydata = m;} /* the packet factory */ pf_packet_t pf_factory_newpacket(pf_symbol_t *type) { pf_packet_t p; pf_class_t *c; pf_atom_t *a = class_list->first; /* try to reuse first */ p = pf_packet_reuse(type); if (p) return p; /* call class constructor it will be passed a parsed type list */ pf_list_t *l = pf_list_from_typesymbol(type); PF_ASSERT(l->first->t == a_symbol); pf_symbol_t *s = l->first->w.w_symbol; // get main type selector while(a && (!p)){ c = (pf_class_t *)(a->w.w_pointer); if (c->type == s) p = (c->create) ? (*c->create)(l) : 0; a = a->next; } /* check if we got what we wanted */ pf_header_t *h = pf_packet_header(p); if (h){ if (h->desc != type){ pf_post("wanted %s but got %s", type->s_name, h->desc->s_name); // pf_packet_delete(p); p = 0; } } pf_list_free(l); return p; }