/// advance the map iterator to the next node. MapIter map_iter_next (MapIter iter) { PEntry node = iter->node; // basic strategy is to revisit the left branch for the next node in order. // However, if we do have a right node, mark it as visited and go down the left. if (node->_right) { iter->node = node->_right; push_stack(iter,node,true); go_down_left(iter); node = iter->node; } else {// look for an univisited node on the stack PEntry item = pop_stack(iter); while (item) { if (! right_visited(item)) break; obj_unref(item); item = pop_stack(iter); } if (item != NULL) { // gotcha! node = (PEntry)item->data; obj_unref(item); } else {// no more stack, we're finished obj_unref(iter); return NULL; } iter->node = node; } iter->key = node->key; iter->value = map_value_data(iter->map,node); if (iter->pkey) { *iter->pkey = iter->key; *iter->pvalue = iter->value; } return iter; }
static void StrTempl_dispose (StrTempl *stl) { obj_unref_v(stl->str, stl->parts, stl->subt); --templ_instances; if (templ_instances == 0) { obj_unref(builtin_funs); obj_unref(macros); obj_unref(if_stack); builtin_funs = NULL; } }
void list_free_item(List *ls, ListIter item) { if (list_is_container(ls)) { if (ls->flags & LIST_REF) { obj_unref (item->data); } ObjAllocator *alloc = ls->kind->alloc; alloc->free(alloc,item); } else { obj_unref(item); } }
proto_parser * alloc_proto_parser(uint32_t size, proto_parser_ops *ops, void *u) { proto_parser *parser; int32_t err; if (size < sizeof(*parser)) return NULL; parser = (proto_parser*)obj_new(size, on_obj_fin); parser->ops = NULL; if (ops && ops->init) { err = (*ops->init)(parser, u); if (err) { obj_unref(parser); return NULL; } } parser->ops = ops; return parser; }
media_sinker * media_sinker_alloc(uint32_t size, media_sinker_ops *ops, void *u) { int32_t err; media_sinker *sinker; if (size < sizeof(*sinker)) return NULL; sinker = (media_sinker*)obj_new(size, on_obj_fin); if (sinker) { init_self(sinker); sinker->ops = ops; if (ops && ops->init) { err = (*ops->init)(sinker, u); if (err) { sinker->ops = NULL; obj_unref(sinker); return NULL; } } } return sinker; }
static void dispose_map_entries(Map *m, PEntry node) { intptr_t vt = vtype(m), kt = m->flags; //printf("%d %d %p %d\n",vt,kt,node,node->data); // we are a container with string keys if (kt == MAP_KEY_STRING && vt != MAP_NODE) { obj_unref(node->key); } if (vt == MAP_NODE) { // struct map obj_unref(node); } else { if (vt & MAP_STRING) // container disposes of references obj_unref(node->data); free(node); } }
void media_sinker_unref(media_sinker *sinker) { if (sinker) { obj_unref(sinker); } }
// this does the work of inserting an item into the tree. // There are two cases: // (1) the map data is a pointer to a struct with a map/list header; it is its own key. // (2) the map key and data are both pointers. But they may be different kinds // of pointers, e.g. strings for keys, plain pointers/ints for values static PEntry put_item(Map *m, void *key, void *data, int pointer_type) { PEntry item = (PEntry)private_new_item(m,pointer_type ? (PEntry)key : data,sizeof(MapEntry)); // for a pointer/string keyed map, this returns a MapEntryDefault struct, // and the data must also be a pointer or a string, which is put into the 'mdata' field if (pointer_type) { if (pointer_type == MAP_STRING) { // strings _may_ need copying.. data = str_cpy((char*)data); } item->data = data; //printf("key %d data %d\n",key,data); } else { // otherwise the data contains its own key key = item->key; } item->_left = NULL; item->_right = NULL; ++m->size; if (! root(m)) { // first item! root(m) = (ListIter) item; } else { PEntry P = (PEntry)root(m); PEntry last = P; int order, last_order = 0; ListCmpFun compare = m->kind->compare; while (P) { order = compare(P->key,key); if (order == 0) { // gotcha - overwrite existing entry in map if (pointer_type) { P->data = item->data; map_free_item(m,item); } else { // put new node inplace item->_left = P->_left; item->_right = P->_right; if (last_order > 0) { // we are a left child last->_left = item; } else { last->_right = item; } obj_unref(P); } --m->size; return P; } else if (order > 0) { // we go down the left side P = P->_left; if (! P) // and insert if we hit the edge last->_left = item; } else { // down the right side, ditto P = P->_right; if (! P) last->_right = item; } last = P; last_order = order; } } return item; }
/// Get the key/value pairs of a map as an array. MapKeyValue *map_to_array(Map *m) { MapKeyValue *res = array_new(MapKeyValue,map_size(m)); struct ArrayMapIter *ami = obj_new(struct ArrayMapIter,NULL); ami->kp = res; ami->m = m; map_visit(ami,(PEntry)root(m),(MapCallback)add_keypair,0); obj_unref(ami); return res; }
/** Walks though the object pool, and calls unref on each object. If the object is effectively destroyed, it will be removed from the pool too. Otherwise, it remains in the pool. */ ObjPool * objpool_unref(ObjPool * pool) { ObjPoolNode * node, * next, * prev; if(!pool) return NULL; prev = NULL; node = pool->last; while (node) { if(!(obj_unref(node->data))) { // not correct, need to change ObjPoolNode!!! next = node->next; if (!prev) { // begin of list pool->last = node->next; } else { prev->next = next; } mem_free(node); node = next; } } return pool; }
void free_proto_parser(proto_parser *parser) { obj_unref(parser); }
static void proto_watch_on_finalize(void *u) { network_client *nc = (network_client*)u; obj_unref(nc); }
static void destroy_csbh(csbh_context_t *ctx) { obj_unref(ctx); }
static void MapIterator_dispose(MapIterator *iter) { if (! iter->finis) // not already dead... obj_unref(iter->mi); }
static void map_iter_free(MapIter iter) { obj_unref(iter->vstack); }
static void destroy_skm(skm_context_t *ctx) { obj_unref(ctx); }