--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2021 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_REPOLIST_H
+#define PAKFIRE_REPOLIST_H
+
+#include <pakfire/repo.h>
+#include <pakfire/types.h>
+
+struct pakfire_repolist;
+
+int pakfire_repolist_create(struct pakfire_repolist** list);
+
+struct pakfire_repolist* pakfire_repolist_ref(struct pakfire_repolist* list);
+struct pakfire_repolist* pakfire_repolist_unref(struct pakfire_repolist* list);
+
+void pakfire_repolist_clear(struct pakfire_repolist* list);
+
+size_t pakfire_repolist_size(struct pakfire_repolist* list);
+int pakfire_repolist_empty(struct pakfire_repolist* list);
+
+PakfireRepo pakfire_repolist_get(struct pakfire_repolist* list, size_t index);
+int pakfire_repolist_append(struct pakfire_repolist* list, PakfireRepo repo);
+
+#endif /* PAKFIRE_REPOLIST_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2021 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pakfire/private.h>
+#include <pakfire/repo.h>
+#include <pakfire/repolist.h>
+#include <pakfire/types.h>
+
+struct pakfire_repolist {
+ int nrefs;
+
+ PakfireRepo* elements;
+ size_t elements_size;
+
+ size_t size;
+};
+
+static int pakfire_repolist_grow(struct pakfire_repolist* list, size_t size) {
+ PakfireRepo* elements = reallocarray(list->elements,
+ list->elements_size + size, sizeof(*list->elements));
+ if (!elements)
+ return -errno;
+
+ list->elements = elements;
+ list->elements_size += size;
+
+ return 0;
+}
+
+PAKFIRE_EXPORT int pakfire_repolist_create(struct pakfire_repolist** list) {
+ struct pakfire_repolist* l = calloc(1, sizeof(*l));
+ if (!l)
+ return ENOMEM;
+
+ l->nrefs = 1;
+
+ *list = l;
+ return 0;
+}
+
+PAKFIRE_EXPORT struct pakfire_repolist* pakfire_repolist_ref(
+ struct pakfire_repolist* list) {
+ list->nrefs++;
+
+ return list;
+}
+
+static void pakfire_repolist_free(struct pakfire_repolist* list) {
+ pakfire_repolist_clear(list);
+ free(list);
+}
+
+PAKFIRE_EXPORT struct pakfire_repolist* pakfire_repolist_unref(
+ struct pakfire_repolist* list) {
+ if (--list->nrefs > 0)
+ return list;
+
+ pakfire_repolist_free(list);
+ return NULL;
+}
+
+PAKFIRE_EXPORT void pakfire_repolist_clear(struct pakfire_repolist* list) {
+ if (!list->elements)
+ return;
+
+ for (unsigned int i = 0; i < list->size; i++)
+ pakfire_repo_unref(list->elements[i]);
+
+ free(list->elements);
+ list->elements = NULL;
+ list->elements_size = 0;
+
+ list->size = 0;
+}
+
+PAKFIRE_EXPORT size_t pakfire_repolist_size(struct pakfire_repolist* list) {
+ return list->size;
+}
+
+PAKFIRE_EXPORT int pakfire_repolist_empty(struct pakfire_repolist* list) {
+ return list->size == 0;
+}
+
+PAKFIRE_EXPORT PakfireRepo pakfire_repolist_get(struct pakfire_repolist* list, size_t index) {
+ if (index >= list->size)
+ return NULL;
+
+ return pakfire_repo_ref(list->elements[index]);
+}
+
+PAKFIRE_EXPORT int pakfire_repolist_append(struct pakfire_repolist* list, PakfireRepo repo) {
+ if (!repo)
+ return EINVAL;
+
+ // Check if we have any space left
+ if (list->size >= list->elements_size) {
+ int r = pakfire_repolist_grow(list, 64);
+ if (r)
+ return r;
+ }
+
+ list->elements[list->size++] = pakfire_repo_ref(repo);
+
+ return 0;
+}