]> WPIA git - cassiopeia.git/blobdiff - lib/openssl/ssl/pqueue.c
upd: openssl to 1.1.0
[cassiopeia.git] / lib / openssl / ssl / pqueue.c
diff --git a/lib/openssl/ssl/pqueue.c b/lib/openssl/ssl/pqueue.c
new file mode 100644 (file)
index 0000000..b447e1d
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "ssl_locl.h"
+#include <openssl/bn.h>
+
+struct pqueue_st {
+    pitem *items;
+    int count;
+};
+
+pitem *pitem_new(unsigned char *prio64be, void *data)
+{
+    pitem *item = OPENSSL_malloc(sizeof(*item));
+    if (item == NULL)
+        return NULL;
+
+    memcpy(item->priority, prio64be, sizeof(item->priority));
+
+    item->data = data;
+    item->next = NULL;
+
+    return item;
+}
+
+void pitem_free(pitem *item)
+{
+    OPENSSL_free(item);
+}
+
+pqueue *pqueue_new()
+{
+    pqueue *pq = OPENSSL_zalloc(sizeof(*pq));
+
+    return pq;
+}
+
+void pqueue_free(pqueue *pq)
+{
+    OPENSSL_free(pq);
+}
+
+pitem *pqueue_insert(pqueue *pq, pitem *item)
+{
+    pitem *curr, *next;
+
+    if (pq->items == NULL) {
+        pq->items = item;
+        return item;
+    }
+
+    for (curr = NULL, next = pq->items;
+         next != NULL; curr = next, next = next->next) {
+        /*
+         * we can compare 64-bit value in big-endian encoding with memcmp:-)
+         */
+        int cmp = memcmp(next->priority, item->priority, 8);
+        if (cmp > 0) {          /* next > item */
+            item->next = next;
+
+            if (curr == NULL)
+                pq->items = item;
+            else
+                curr->next = item;
+
+            return item;
+        }
+
+        else if (cmp == 0)      /* duplicates not allowed */
+            return NULL;
+    }
+
+    item->next = NULL;
+    curr->next = item;
+
+    return item;
+}
+
+pitem *pqueue_peek(pqueue *pq)
+{
+    return pq->items;
+}
+
+pitem *pqueue_pop(pqueue *pq)
+{
+    pitem *item = pq->items;
+
+    if (pq->items != NULL)
+        pq->items = pq->items->next;
+
+    return item;
+}
+
+pitem *pqueue_find(pqueue *pq, unsigned char *prio64be)
+{
+    pitem *next;
+    pitem *found = NULL;
+
+    if (pq->items == NULL)
+        return NULL;
+
+    for (next = pq->items; next->next != NULL; next = next->next) {
+        if (memcmp(next->priority, prio64be, 8) == 0) {
+            found = next;
+            break;
+        }
+    }
+
+    /* check the one last node */
+    if (memcmp(next->priority, prio64be, 8) == 0)
+        found = next;
+
+    if (!found)
+        return NULL;
+
+    return found;
+}
+
+pitem *pqueue_iterator(pqueue *pq)
+{
+    return pqueue_peek(pq);
+}
+
+pitem *pqueue_next(pitem **item)
+{
+    pitem *ret;
+
+    if (item == NULL || *item == NULL)
+        return NULL;
+
+    /* *item != NULL */
+    ret = *item;
+    *item = (*item)->next;
+
+    return ret;
+}
+
+int pqueue_size(pqueue *pq)
+{
+    pitem *item = pq->items;
+    int count = 0;
+
+    while (item != NULL) {
+        count++;
+        item = item->next;
+    }
+    return count;
+}