static int G_GNUC_WGET_NONNULL((2)) _vec_insert_sorted_private(wget_vector_t *v, const void *elem, size_t size, int alloc) { int m = 0; if (!v) return -1; if (!v->cmp) return _vec_insert_private(v, elem, size, v->cur, 0, alloc); if (!v->sorted) wget_vector_sort(v); // vec_sort will leave v->sorted alone if it fails, so check again if (v->sorted) { // binary search for element int l = 0, r = v->cur - 1, res = 0; while (l <= r) { m = (l + r) / 2; if ((res = v->cmp(elem, v->entry[m])) > 0) l = m + 1; else if (res < 0) r = m - 1; else return _vec_insert_private(v, elem, size, m, 0, alloc); } if (res > 0) m++; } return _vec_insert_private(v, elem, size, m, 0, alloc); }
wget_metalink_t *wget_metalink_parse(const char *xml) { wget_metalink_t *metalink = xcalloc(1, sizeof(wget_metalink_t)); _metalink_context_t ctx = { .metalink = metalink, .priority = 999999, .location = "-" }; wget_xml_parse_buffer(xml, _metalink_parse, &ctx, 0); return metalink; } void wget_metalink_free(wget_metalink_t **metalink) { if (metalink && *metalink) { xfree((*metalink)->name); wget_vector_free(&(*metalink)->mirrors); wget_vector_free(&(*metalink)->hashes); wget_vector_free(&(*metalink)->pieces); xfree(*metalink); } } static int G_GNUC_WGET_PURE _compare_mirror(wget_metalink_mirror_t **m1, wget_metalink_mirror_t **m2) { return (*m1)->priority - (*m2)->priority; } void wget_metalink_sort_mirrors(wget_metalink_t *metalink) { if (metalink) { wget_vector_setcmpfunc(metalink->mirrors, (int(*)(const void *, const void *))_compare_mirror); wget_vector_sort(metalink->mirrors); } }