summaryrefslogtreecommitdiffstats
path: root/lib/name_val_array.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/name_val_array.h')
-rw-r--r--lib/name_val_array.h125
1 files changed, 125 insertions, 0 deletions
diff --git a/lib/name_val_array.h b/lib/name_val_array.h
new file mode 100644
index 0000000..41e4df9
--- /dev/null
+++ b/lib/name_val_array.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011-2019 Free Software Foundation, Inc.
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef GNUTLS_NAME_VAL_ARRAY_H
+#define GNUTLS_NAME_VAL_ARRAY_H
+
+#include "gnutls_int.h"
+#include "errors.h"
+
+/* Functionality to allow an array of strings. Strings
+ * are allowed to be added to the list and matched against it.
+ */
+
+typedef struct name_val_array_st {
+ char *name;
+ unsigned name_size;
+ char *val;
+ struct name_val_array_st *next;
+} *name_val_array_t;
+
+inline static void _name_val_array_clear(name_val_array_t * head)
+{
+ name_val_array_t prev, array = *head;
+
+ while (array != NULL) {
+ prev = array;
+ array = prev->next;
+ gnutls_free(prev);
+ }
+ *head = NULL;
+}
+
+inline static const char *_name_val_array_value(name_val_array_t head,
+ const char *name, unsigned name_size)
+{
+ name_val_array_t array = head;
+
+ while (array != NULL) {
+ if (array->name_size == name_size &&
+ memcmp(array->name, name, name_size) == 0) {
+ return array->val;
+ }
+ array = array->next;
+ }
+
+ return NULL;
+}
+
+inline static void append(name_val_array_t array, const char *name,
+ unsigned name_len, const char *val,
+ unsigned val_len)
+{
+ array->name = ((char *) array) + sizeof(struct name_val_array_st);
+ memcpy(array->name, name, name_len);
+ array->name[name_len] = 0;
+ array->name_size = name_len;
+
+ array->val = ((char *) array) + name_len + 1 + sizeof(struct name_val_array_st);
+ if (val)
+ memcpy(array->val, val, val_len);
+ array->val[val_len] = 0;
+
+ array->next = NULL;
+}
+
+inline static int _name_val_array_append(name_val_array_t * head,
+ const char *name,
+ const char *val)
+{
+ name_val_array_t prev, array;
+ unsigned name_len = strlen(name);
+ unsigned val_len = (val==NULL)?0:strlen(val);
+
+ if (*head == NULL) {
+ *head =
+ gnutls_malloc(val_len + name_len + 2 +
+ sizeof(struct name_val_array_st));
+ if (*head == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ array = *head;
+ append(array, name, name_len, val, val_len);
+ } else {
+ array = *head;
+ prev = array;
+
+ while (array != NULL) {
+ prev = array;
+ array = prev->next;
+ }
+ prev->next =
+ gnutls_malloc(name_len + val_len + 2 +
+ sizeof(struct name_val_array_st));
+ array = prev->next;
+
+ if (array == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ append(array, name, name_len, val, val_len);
+ }
+
+ return 0;
+}
+
+#endif