]> git.ipfire.org Git - people/ms/libloc.git/blame - src/as-list.c
importer: Drop EDROP as it has been merged into DROP
[people/ms/libloc.git] / src / as-list.c
CommitLineData
84a2f0c2
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2020 IPFire Development Team <info@ipfire.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15*/
16
84a2f0c2
MT
17#include <stdlib.h>
18
c12a1385
MT
19#include <libloc/as.h>
20#include <libloc/as-list.h>
25f300f7 21#include <libloc/compat.h>
c12a1385 22#include <libloc/private.h>
84a2f0c2
MT
23
24struct loc_as_list {
25 struct loc_ctx* ctx;
26 int refcount;
27
1a415f8c
MT
28 struct loc_as** elements;
29 size_t elements_size;
30
84a2f0c2 31 size_t size;
84a2f0c2
MT
32};
33
f13c23b7
MT
34static int loc_as_list_grow(struct loc_as_list* list) {
35 size_t size = list->elements_size * 2;
36 if (size < 1024)
37 size = 1024;
38
1a415f8c
MT
39 DEBUG(list->ctx, "Growing AS list %p by %zu to %zu\n",
40 list, size, list->elements_size + size);
41
42 struct loc_as** elements = reallocarray(list->elements,
43 list->elements_size + size, sizeof(*list->elements));
44 if (!elements)
198e382c 45 return 1;
1a415f8c
MT
46
47 list->elements = elements;
48 list->elements_size += size;
49
50 return 0;
51}
52
84a2f0c2
MT
53LOC_EXPORT int loc_as_list_new(struct loc_ctx* ctx,
54 struct loc_as_list** list) {
55 struct loc_as_list* l = calloc(1, sizeof(*l));
56 if (!l)
198e382c 57 return 1;
84a2f0c2
MT
58
59 l->ctx = loc_ref(ctx);
60 l->refcount = 1;
61
84a2f0c2
MT
62 DEBUG(l->ctx, "AS list allocated at %p\n", l);
63 *list = l;
64
65 return 0;
66}
67
68LOC_EXPORT struct loc_as_list* loc_as_list_ref(struct loc_as_list* list) {
69 list->refcount++;
70
71 return list;
72}
73
74static void loc_as_list_free(struct loc_as_list* list) {
75 DEBUG(list->ctx, "Releasing AS list at %p\n", list);
76
77 loc_as_list_clear(list);
78
79 loc_unref(list->ctx);
80 free(list);
81}
82
83LOC_EXPORT struct loc_as_list* loc_as_list_unref(struct loc_as_list* list) {
84 if (!list)
85 return NULL;
86
87 if (--list->refcount > 0)
88 return list;
89
90 loc_as_list_free(list);
91 return NULL;
92}
93
94LOC_EXPORT size_t loc_as_list_size(struct loc_as_list* list) {
95 return list->size;
96}
97
98LOC_EXPORT int loc_as_list_empty(struct loc_as_list* list) {
99 return list->size == 0;
100}
101
102LOC_EXPORT void loc_as_list_clear(struct loc_as_list* list) {
248f5e04
MT
103 if (!list->elements)
104 return;
105
84a2f0c2 106 for (unsigned int i = 0; i < list->size; i++)
1a415f8c 107 loc_as_unref(list->elements[i]);
248f5e04
MT
108
109 free(list->elements);
a6dc9324 110 list->elements = NULL;
248f5e04
MT
111 list->elements_size = 0;
112
113 list->size = 0;
84a2f0c2
MT
114}
115
116LOC_EXPORT struct loc_as* loc_as_list_get(struct loc_as_list* list, size_t index) {
117 // Check index
118 if (index >= list->size)
119 return NULL;
120
1a415f8c 121 return loc_as_ref(list->elements[index]);
84a2f0c2
MT
122}
123
124LOC_EXPORT int loc_as_list_append(
125 struct loc_as_list* list, struct loc_as* as) {
126 if (loc_as_list_contains(list, as))
127 return 0;
128
129 // Check if we have space left
1a415f8c 130 if (list->size >= list->elements_size) {
f13c23b7 131 int r = loc_as_list_grow(list);
1a415f8c
MT
132 if (r)
133 return r;
84a2f0c2
MT
134 }
135
136 DEBUG(list->ctx, "%p: Appending AS %p to list\n", list, as);
137
1a415f8c 138 list->elements[list->size++] = loc_as_ref(as);
84a2f0c2
MT
139
140 return 0;
141}
142
143LOC_EXPORT int loc_as_list_contains(
144 struct loc_as_list* list, struct loc_as* as) {
145 for (unsigned int i = 0; i < list->size; i++) {
1a415f8c 146 if (loc_as_cmp(as, list->elements[i]) == 0)
84a2f0c2
MT
147 return 1;
148 }
149
150 return 0;
151}
152
153LOC_EXPORT int loc_as_list_contains_number(
154 struct loc_as_list* list, uint32_t number) {
155 struct loc_as* as;
156
157 int r = loc_as_new(list->ctx, &as, number);
158 if (r)
159 return -1;
160
161 r = loc_as_list_contains(list, as);
162 loc_as_unref(as);
163
164 return r;
165}
233311e8
MT
166
167static int __loc_as_cmp(const void* as1, const void* as2) {
168 return loc_as_cmp(*(struct loc_as**)as1, *(struct loc_as**)as2);
169}
170
171LOC_EXPORT void loc_as_list_sort(struct loc_as_list* list) {
172 // Sort everything
173 qsort(list->elements, list->size, sizeof(*list->elements), __loc_as_cmp);
174}