#include #include #include #include #include #include #include #include struct mie_module *mie_module_create(void) { struct mie_module *out = malloc(sizeof *out); if (!out) { return NULL; } memset(out, 0x0, sizeof *out); mie_value_init(&out->m_base, MIE_VALUE_MODULE); out->m_names = mie_name_map_create(); out->m_data = b_hashmap_create(NULL, NULL); out->m_data_strings = b_hashmap_create(NULL, NULL); return out; } void mie_module_add_function( struct mie_module *mod, struct mie_func *func, const char *name) { struct mie_value *v = mie_module_generate_value_name(mod, MIE_VALUE(func), name); if (!v) { return; } b_queue_push_back(&mod->m_func, &v->v_entry); } struct mie_data *mie_module_get_string_ptr(struct mie_module *mod, const char *s) { b_hashmap_key key = { .key_data = s, .key_size = strlen(s), }; const b_hashmap_value *entry = b_hashmap_get(mod->m_data_strings, &key); if (entry) { return entry->value_data; } return NULL; } struct mie_data *mie_module_get_data(struct mie_module *mod, const char *name) { b_hashmap_key key = { .key_data = name, .key_size = strlen(name), }; const b_hashmap_value *entry = b_hashmap_get(mod->m_data, &key); if (entry) { return entry->value_data; } /* don't search m_data_strings, as it is keyed by the string contents * rather than the data entry name, and its entries are duplicated in * m_data anyway */ return NULL; } enum b_status mie_module_put_data( struct mie_module *mod, struct mie_data *data, const char *name) { struct mie_value *v = mie_module_generate_value_name(mod, MIE_VALUE(data), name); b_hashmap_key key = { .key_data = v->v_name.n_str, .key_size = strlen(name), }; b_hashmap_value value = { .value_data = data, .value_size = sizeof *data, }; b_hashmap_put(mod->m_data, &key, &value); if (data->d_type != MIE_DATA_CONST) { return B_SUCCESS; } struct mie_const *const_data = data->d_const.c_value; if (const_data->c_type->t_id == MIE_TYPE_STR) { struct mie_string *s = MIE_STRING(const_data); key.key_data = s->s_value; key.key_size = strlen(key.key_data); b_hashmap_put(mod->m_data_strings, &key, &value); } return B_SUCCESS; } struct mie_value *mie_module_generate_value_name( struct mie_module *mod, struct mie_value *val, const char *hint) { struct mie_name *name = mie_name_map_put(mod->m_names, &val->v_name, hint, 0); return b_unbox(struct mie_value, name, v_name); } static void cleanup(struct mie_value *value) { struct mie_module *module = MIE_MODULE(value); b_queue_entry *entry = b_queue_first(&module->m_records); b_queue_entry *next = NULL; while (entry) { struct mie_value *v = b_unbox(struct mie_value, entry, v_entry); next = b_queue_next(entry); b_queue_delete(&module->m_records, entry); mie_value_destroy(v); entry = next; } entry = b_queue_first(&module->m_types); while (entry) { struct mie_value *v = b_unbox(struct mie_value, entry, v_entry); next = b_queue_next(entry); b_queue_delete(&module->m_types, entry); mie_value_destroy(v); entry = next; } entry = b_queue_first(&module->m_func); while (entry) { struct mie_value *v = b_unbox(struct mie_value, entry, v_entry); next = b_queue_next(entry); b_queue_delete(&module->m_func, entry); mie_value_destroy(v); entry = next; } b_hashmap_unref(module->m_data_strings); b_hashmap_unref(module->m_data); } const struct mie_value_type module_value_type = { .t_id = MIE_VALUE_MODULE, .t_cleanup = cleanup, };