int router_add(struct router_t* router, const uint8_t id[N_NODEID], const struct sockaddr_storage* addr, struct node_t** node) { int r; struct rbitem_t* item; struct rbtree_node_t **link; struct rbtree_node_t *parent; if (node) *node = NULL; item = calloc(1, sizeof(*item)); if (!item) return ENOMEM; item->node = node_create2(id, addr); if (!item->node) { free(item->node); return ENOMEM; } locker_lock(&router->locker); r = rbtree_find(&router->rbtree, id, &parent); if (0 == r) { if (node) { *node = (rbtree_entry(parent, struct rbitem_t, link))->node; node_addref(*node); } locker_unlock(&router->locker); node_release(item->node); free(item); return EEXIST; } link = parent ? (r > 0 ? &parent->left : &parent->right) : NULL; assert(!link || !*link); rbtree_insert(&router->rbtree, parent, link, &item->link); router->count += 1; if (node) { node_addref(item->node); *node = item->node; } locker_unlock(&router->locker); return 0; }
static HTMLDOMNode *get_node_obj(IHTMLDOMNode *iface) { HTMLDOMNode *ret; if(iface->lpVtbl != &HTMLDOMNodeVtbl) return NULL; ret = impl_from_IHTMLDOMNode(iface); node_addref(ret); return ret; }
IHTMLElementCollection *create_all_collection(HTMLDOMNode *node, BOOL include_root) { elem_vector_t buf = {NULL, 0, 8}; buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*)); if(include_root) { node_addref(node); elem_vector_add(&buf, elem_from_HTMLDOMNode(node)); } create_all_list(node->doc, node, &buf); elem_vector_normalize(&buf); return HTMLElementCollection_Create(buf.buf, buf.len); }
static HRESULT HTMLObjectElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) { HTMLObjectElement *This = impl_from_HTMLDOMNode(iface); TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); if(IsEqualGUID(&IID_IUnknown, riid)) { *ppv = &This->IHTMLObjectElement_iface; }else if(IsEqualGUID(&IID_IDispatch, riid)) { *ppv = &This->IHTMLObjectElement_iface; }else if(IsEqualGUID(&IID_IHTMLObjectElement, riid)) { *ppv = &This->IHTMLObjectElement_iface; }else if(IsEqualGUID(&IID_IHTMLObjectElement2, riid)) { *ppv = &This->IHTMLObjectElement2_iface; }else if(IsEqualGUID(&IID_HTMLPluginContainer, riid)) { /* Special pseudo-interface returning HTMLPluginContainse struct. */ *ppv = &This->plugin_container; node_addref(&This->plugin_container.element.node); return S_OK; }else { HRESULT hres; hres = HTMLElement_QI(&This->plugin_container.element.node, riid, ppv); if(hres == E_NOINTERFACE && This->plugin_container.plugin_host && This->plugin_container.plugin_host->plugin_unk) { IUnknown *plugin_iface, *ret; hres = IUnknown_QueryInterface(This->plugin_container.plugin_host->plugin_unk, riid, (void**)&plugin_iface); if(hres == S_OK) { hres = wrap_iface(plugin_iface, (IUnknown*)&This->IHTMLObjectElement_iface, &ret); IUnknown_Release(plugin_iface); if(FAILED(hres)) return hres; TRACE("returning plugin iface %p wrapped to %p\n", plugin_iface, ret); *ppv = ret; return S_OK; } } return hres; } IUnknown_AddRef((IUnknown*)*ppv); return S_OK; }
static HRESULT WINAPI HTMLElementCollection_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); DWORD i; nsAString tag_str; const PRUnichar *tag; elem_vector_t buf = {NULL, 0, 8}; if(V_VT(&tagName) != VT_BSTR) { WARN("Invalid arg\n"); return DISP_E_MEMBERNOTFOUND; } TRACE("(%p)->(%s %p)\n", This, debugstr_w(V_BSTR(&tagName)), pdisp); buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*)); nsAString_Init(&tag_str, NULL); for(i=0; i<This->len; i++) { if(!This->elems[i]->nselem) continue; nsIDOMHTMLElement_GetTagName(This->elems[i]->nselem, &tag_str); nsAString_GetData(&tag_str, &tag); if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, tag, -1, V_BSTR(&tagName), -1) == CSTR_EQUAL) { node_addref(&This->elems[i]->node); elem_vector_add(&buf, This->elems[i]); } } nsAString_Finish(&tag_str); elem_vector_normalize(&buf); TRACE("fount %d tags\n", buf.len); *pdisp = (IDispatch*)HTMLElementCollection_Create(buf.buf, buf.len); return S_OK; }
static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); HRESULT hres = S_OK; TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); *pdisp = NULL; switch(V_VT(&name)) { case VT_I4: case VT_INT: if(V_I4(&name) < 0) return E_INVALIDARG; hres = get_item_idx(This, V_I4(&name), pdisp); break; case VT_UI4: case VT_UINT: hres = get_item_idx(This, V_UINT(&name), pdisp); break; case VT_BSTR: { DWORD i; if(V_VT(&index) == VT_I4) { LONG idx = V_I4(&index); if(idx < 0) return E_INVALIDARG; for(i=0; i<This->len; i++) { if(is_elem_name(This->elems[i], V_BSTR(&name)) && !idx--) break; } if(i != This->len) { *pdisp = (IDispatch*)&This->elems[i]->IHTMLElement_iface; IDispatch_AddRef(*pdisp); } }else { elem_vector_t buf = {NULL, 0, 8}; buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*)); for(i=0; i<This->len; i++) { if(is_elem_name(This->elems[i], V_BSTR(&name))) { node_addref(&This->elems[i]->node); elem_vector_add(&buf, This->elems[i]); } } if(buf.len > 1) { elem_vector_normalize(&buf); *pdisp = (IDispatch*)HTMLElementCollection_Create(buf.buf, buf.len); }else { if(buf.len == 1) { /* Already AddRef-ed */ *pdisp = (IDispatch*)&buf.buf[0]->IHTMLElement_iface; } heap_free(buf.buf); } } break; } default: FIXME("Unsupported name %s\n", debugstr_variant(&name)); hres = E_NOTIMPL; } if(SUCCEEDED(hres)) TRACE("returning %p\n", *pdisp); return hres; }
int router_nearest(struct router_t* router, const uint8_t id[N_NODEID], struct node_t* nodes[], size_t count) { int i, min, diff; uint8_t xor[N_NODEID]; heap_t* heap; struct rbitem_t* item; struct rbtree_node_t* node; const struct rbtree_node_t* prev; const struct rbtree_node_t* next; heap = heap_create(node_compare_less, (void*)id); heap_reserve(heap, count + 1); min = N_BITS; locker_lock(&router->locker); rbtree_find(&router->rbtree, id, &node); if (NULL == node) { locker_unlock(&router->locker); return 0; } item = rbtree_entry(node, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); min = min < diff ? min : diff; heap_push(heap, item->node); prev = rbtree_prev(node); next = rbtree_next(node); do { while (prev) { item = rbtree_entry(prev, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); prev = rbtree_prev(prev); if (diff < min) { min = diff; break; // try right } } while (next) { item = rbtree_entry(next, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); next = rbtree_next(next); if (diff < min) { min = diff; break; // try left } } } while (heap_size(heap) < (int)count && (prev || next)); for (i = 0; i < (int)count && !heap_empty(heap); i++) { nodes[i] = heap_top(heap); node_addref(nodes[i]); heap_pop(heap); } locker_unlock(&router->locker); heap_destroy(heap); return i; }