#include <errno.h>
#include <stdlib.h>
-#include <loc/country.h>
-#include <loc/country-list.h>
-#include <loc/private.h>
+#include <libloc/compat.h>
+#include <libloc/country.h>
+#include <libloc/country-list.h>
+#include <libloc/private.h>
struct loc_country_list {
struct loc_ctx* ctx;
size_t size;
};
-static int loc_country_list_grow(struct loc_country_list* list, size_t size) {
+static int loc_country_list_grow(struct loc_country_list* list) {
+ size_t size = list->elements_size * 2;
+ if (size < 1024)
+ size = 1024;
+
DEBUG(list->ctx, "Growing country list %p by %zu to %zu\n",
list, size, list->elements_size + size);
struct loc_country** elements = reallocarray(list->elements,
list->elements_size + size, sizeof(*list->elements));
if (!elements)
- return -errno;
+ return 1;
list->elements = elements;
list->elements_size += size;
}
LOC_EXPORT struct loc_country_list* loc_country_list_unref(struct loc_country_list* list) {
- if (!list)
- return NULL;
-
if (--list->refcount > 0)
return list;
loc_country_unref(list->elements[i]);
free(list->elements);
+ list->elements = NULL;
list->elements_size = 0;
list->size = 0;
// Check if we have space left
if (list->size >= list->elements_size) {
- int r = loc_country_list_grow(list, 64);
+ int r = loc_country_list_grow(list);
if (r)
return r;
}
struct loc_country* country;
int r = loc_country_new(list->ctx, &country, code);
- if (r)
- return -1;
+ if (r) {
+ // Ignore invalid country codes which would never match
+ if (errno == EINVAL)
+ return 0;
+
+ return r;
+ }
r = loc_country_list_contains(list, country);
loc_country_unref(country);
return r;
}
+
+static int __loc_country_cmp(const void* country1, const void* country2) {
+ return loc_country_cmp(*(struct loc_country**)country1, *(struct loc_country**)country2);
+}
+
+LOC_EXPORT void loc_country_list_sort(struct loc_country_list* list) {
+ // Sort everything
+ qsort(list->elements, list->size, sizeof(*list->elements), __loc_country_cmp);
+}