]> git.ipfire.org Git - people/ms/libloc.git/blob - src/as-list.c
as: Add list for easier processing
[people/ms/libloc.git] / src / as-list.c
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
17 #include <errno.h>
18 #include <stdlib.h>
19
20 #include <loc/as.h>
21 #include <loc/as-list.h>
22 #include <loc/private.h>
23
24 struct loc_as_list {
25 struct loc_ctx* ctx;
26 int refcount;
27
28 struct loc_as* list[1024];
29 size_t size;
30 size_t max_size;
31 };
32
33 LOC_EXPORT int loc_as_list_new(struct loc_ctx* ctx,
34 struct loc_as_list** list) {
35 struct loc_as_list* l = calloc(1, sizeof(*l));
36 if (!l)
37 return -ENOMEM;
38
39 l->ctx = loc_ref(ctx);
40 l->refcount = 1;
41
42 // Do not allow this list to grow larger than this
43 l->max_size = 1024;
44
45 DEBUG(l->ctx, "AS list allocated at %p\n", l);
46 *list = l;
47
48 return 0;
49 }
50
51 LOC_EXPORT struct loc_as_list* loc_as_list_ref(struct loc_as_list* list) {
52 list->refcount++;
53
54 return list;
55 }
56
57 static void loc_as_list_free(struct loc_as_list* list) {
58 DEBUG(list->ctx, "Releasing AS list at %p\n", list);
59
60 loc_as_list_clear(list);
61
62 loc_unref(list->ctx);
63 free(list);
64 }
65
66 LOC_EXPORT struct loc_as_list* loc_as_list_unref(struct loc_as_list* list) {
67 if (!list)
68 return NULL;
69
70 if (--list->refcount > 0)
71 return list;
72
73 loc_as_list_free(list);
74 return NULL;
75 }
76
77 LOC_EXPORT size_t loc_as_list_size(struct loc_as_list* list) {
78 return list->size;
79 }
80
81 LOC_EXPORT int loc_as_list_empty(struct loc_as_list* list) {
82 return list->size == 0;
83 }
84
85 LOC_EXPORT void loc_as_list_clear(struct loc_as_list* list) {
86 for (unsigned int i = 0; i < list->size; i++)
87 loc_as_unref(list->list[i]);
88 }
89
90 LOC_EXPORT struct loc_as* loc_as_list_get(struct loc_as_list* list, size_t index) {
91 // Check index
92 if (index >= list->size)
93 return NULL;
94
95 return loc_as_ref(list->list[index]);
96 }
97
98 LOC_EXPORT int loc_as_list_append(
99 struct loc_as_list* list, struct loc_as* as) {
100 if (loc_as_list_contains(list, as))
101 return 0;
102
103 // Check if we have space left
104 if (list->size == list->max_size) {
105 ERROR(list->ctx, "%p: Could not append AS to the list. List full\n", list);
106 return -ENOMEM;
107 }
108
109 DEBUG(list->ctx, "%p: Appending AS %p to list\n", list, as);
110
111 list->list[list->size++] = loc_as_ref(as);
112
113 return 0;
114 }
115
116 LOC_EXPORT int loc_as_list_contains(
117 struct loc_as_list* list, struct loc_as* as) {
118 for (unsigned int i = 0; i < list->size; i++) {
119 if (loc_as_cmp(as, list->list[i]) == 0)
120 return 1;
121 }
122
123 return 0;
124 }
125
126 LOC_EXPORT int loc_as_list_contains_number(
127 struct loc_as_list* list, uint32_t number) {
128 struct loc_as* as;
129
130 int r = loc_as_new(list->ctx, &as, number);
131 if (r)
132 return -1;
133
134 r = loc_as_list_contains(list, as);
135 loc_as_unref(as);
136
137 return r;
138 }