#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_list_to_packet_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; } /* 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){ pf_symbol_t *got_type = pf_packet_type(h); if (got_type != type){ pf_post("wanted %s but got %s", type->s_name, got_type->s_name); // pf_packet_delete(p); p = 0; } } pf_list_free(l); return p; }