1160814Ssimon/* crypto/pqueue/pqueue.c */
2296341Sdelphij/*
3160814Ssimon * DTLS implementation written by Nagendra Modadugu
4296341Sdelphij * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5160814Ssimon */
6160814Ssimon/* ====================================================================
7160814Ssimon * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
8160814Ssimon *
9160814Ssimon * Redistribution and use in source and binary forms, with or without
10160814Ssimon * modification, are permitted provided that the following conditions
11160814Ssimon * are met:
12160814Ssimon *
13160814Ssimon * 1. Redistributions of source code must retain the above copyright
14296341Sdelphij *    notice, this list of conditions and the following disclaimer.
15160814Ssimon *
16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright
17160814Ssimon *    notice, this list of conditions and the following disclaimer in
18160814Ssimon *    the documentation and/or other materials provided with the
19160814Ssimon *    distribution.
20160814Ssimon *
21160814Ssimon * 3. All advertising materials mentioning features or use of this
22160814Ssimon *    software must display the following acknowledgment:
23160814Ssimon *    "This product includes software developed by the OpenSSL Project
24160814Ssimon *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25160814Ssimon *
26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27160814Ssimon *    endorse or promote products derived from this software without
28160814Ssimon *    prior written permission. For written permission, please contact
29160814Ssimon *    openssl-core@OpenSSL.org.
30160814Ssimon *
31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL"
32160814Ssimon *    nor may "OpenSSL" appear in their names without prior written
33160814Ssimon *    permission of the OpenSSL Project.
34160814Ssimon *
35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following
36160814Ssimon *    acknowledgment:
37160814Ssimon *    "This product includes software developed by the OpenSSL Project
38160814Ssimon *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39160814Ssimon *
40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43160814Ssimon * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE.
52160814Ssimon * ====================================================================
53160814Ssimon *
54160814Ssimon * This product includes cryptographic software written by Eric Young
55160814Ssimon * (eay@cryptsoft.com).  This product includes software written by Tim
56160814Ssimon * Hudson (tjh@cryptsoft.com).
57160814Ssimon *
58160814Ssimon */
59160814Ssimon
60160814Ssimon#include "cryptlib.h"
61160814Ssimon#include <openssl/bn.h>
62160814Ssimon#include "pqueue.h"
63160814Ssimon
64296341Sdelphijtypedef struct _pqueue {
65296341Sdelphij    pitem *items;
66296341Sdelphij    int count;
67296341Sdelphij} pqueue_s;
68160814Ssimon
69296341Sdelphijpitem *pitem_new(unsigned char *prio64be, void *data)
70296341Sdelphij{
71296341Sdelphij    pitem *item = (pitem *)OPENSSL_malloc(sizeof(pitem));
72296341Sdelphij    if (item == NULL)
73296341Sdelphij        return NULL;
74160814Ssimon
75296341Sdelphij    memcpy(item->priority, prio64be, sizeof(item->priority));
76160814Ssimon
77296341Sdelphij    item->data = data;
78296341Sdelphij    item->next = NULL;
79160814Ssimon
80296341Sdelphij    return item;
81296341Sdelphij}
82160814Ssimon
83296341Sdelphijvoid pitem_free(pitem *item)
84296341Sdelphij{
85296341Sdelphij    if (item == NULL)
86296341Sdelphij        return;
87160814Ssimon
88296341Sdelphij    OPENSSL_free(item);
89296341Sdelphij}
90160814Ssimon
91296341Sdelphijpqueue_s *pqueue_new()
92296341Sdelphij{
93296341Sdelphij    pqueue_s *pq = (pqueue_s *)OPENSSL_malloc(sizeof(pqueue_s));
94296341Sdelphij    if (pq == NULL)
95296341Sdelphij        return NULL;
96160814Ssimon
97296341Sdelphij    memset(pq, 0x00, sizeof(pqueue_s));
98296341Sdelphij    return pq;
99296341Sdelphij}
100160814Ssimon
101296341Sdelphijvoid pqueue_free(pqueue_s *pq)
102296341Sdelphij{
103296341Sdelphij    if (pq == NULL)
104296341Sdelphij        return;
105160814Ssimon
106296341Sdelphij    OPENSSL_free(pq);
107296341Sdelphij}
108160814Ssimon
109296341Sdelphijpitem *pqueue_insert(pqueue_s *pq, pitem *item)
110296341Sdelphij{
111296341Sdelphij    pitem *curr, *next;
112160814Ssimon
113296341Sdelphij    if (pq->items == NULL) {
114296341Sdelphij        pq->items = item;
115296341Sdelphij        return item;
116296341Sdelphij    }
117160814Ssimon
118296341Sdelphij    for (curr = NULL, next = pq->items;
119296341Sdelphij         next != NULL; curr = next, next = next->next) {
120296341Sdelphij        /*
121296341Sdelphij         * we can compare 64-bit value in big-endian encoding with memcmp:-)
122296341Sdelphij         */
123296341Sdelphij        int cmp = memcmp(next->priority, item->priority, 8);
124296341Sdelphij        if (cmp > 0) {          /* next > item */
125296341Sdelphij            item->next = next;
126160814Ssimon
127296341Sdelphij            if (curr == NULL)
128296341Sdelphij                pq->items = item;
129296341Sdelphij            else
130296341Sdelphij                curr->next = item;
131160814Ssimon
132296341Sdelphij            return item;
133296341Sdelphij        }
134160814Ssimon
135296341Sdelphij        else if (cmp == 0)      /* duplicates not allowed */
136296341Sdelphij            return NULL;
137296341Sdelphij    }
138160814Ssimon
139296341Sdelphij    item->next = NULL;
140296341Sdelphij    curr->next = item;
141160814Ssimon
142296341Sdelphij    return item;
143296341Sdelphij}
144160814Ssimon
145296341Sdelphijpitem *pqueue_peek(pqueue_s *pq)
146296341Sdelphij{
147296341Sdelphij    return pq->items;
148296341Sdelphij}
149160814Ssimon
150296341Sdelphijpitem *pqueue_pop(pqueue_s *pq)
151296341Sdelphij{
152296341Sdelphij    pitem *item = pq->items;
153160814Ssimon
154296341Sdelphij    if (pq->items != NULL)
155296341Sdelphij        pq->items = pq->items->next;
156160814Ssimon
157296341Sdelphij    return item;
158296341Sdelphij}
159160814Ssimon
160296341Sdelphijpitem *pqueue_find(pqueue_s *pq, unsigned char *prio64be)
161296341Sdelphij{
162296341Sdelphij    pitem *next;
163296341Sdelphij    pitem *found = NULL;
164160814Ssimon
165296341Sdelphij    if (pq->items == NULL)
166296341Sdelphij        return NULL;
167160814Ssimon
168296341Sdelphij    for (next = pq->items; next->next != NULL; next = next->next) {
169296341Sdelphij        if (memcmp(next->priority, prio64be, 8) == 0) {
170296341Sdelphij            found = next;
171296341Sdelphij            break;
172296341Sdelphij        }
173296341Sdelphij    }
174160814Ssimon
175296341Sdelphij    /* check the one last node */
176296341Sdelphij    if (memcmp(next->priority, prio64be, 8) == 0)
177296341Sdelphij        found = next;
178296341Sdelphij
179296341Sdelphij    if (!found)
180296341Sdelphij        return NULL;
181296341Sdelphij
182296341Sdelphij#if 0                           /* find works in peek mode */
183296341Sdelphij    if (prev == NULL)
184296341Sdelphij        pq->items = next->next;
185296341Sdelphij    else
186296341Sdelphij        prev->next = next->next;
187238405Sjkim#endif
188238405Sjkim
189296341Sdelphij    return found;
190296341Sdelphij}
191160814Ssimon
192296341Sdelphijvoid pqueue_print(pqueue_s *pq)
193296341Sdelphij{
194296341Sdelphij    pitem *item = pq->items;
195160814Ssimon
196296341Sdelphij    while (item != NULL) {
197296341Sdelphij        printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n",
198296341Sdelphij               item->priority[0], item->priority[1],
199296341Sdelphij               item->priority[2], item->priority[3],
200296341Sdelphij               item->priority[4], item->priority[5],
201296341Sdelphij               item->priority[6], item->priority[7]);
202296341Sdelphij        item = item->next;
203296341Sdelphij    }
204296341Sdelphij}
205160814Ssimon
206296341Sdelphijpitem *pqueue_iterator(pqueue_s *pq)
207296341Sdelphij{
208296341Sdelphij    return pqueue_peek(pq);
209296341Sdelphij}
210160814Ssimon
211296341Sdelphijpitem *pqueue_next(pitem **item)
212296341Sdelphij{
213296341Sdelphij    pitem *ret;
214160814Ssimon
215296341Sdelphij    if (item == NULL || *item == NULL)
216296341Sdelphij        return NULL;
217160814Ssimon
218296341Sdelphij    /* *item != NULL */
219296341Sdelphij    ret = *item;
220296341Sdelphij    *item = (*item)->next;
221160814Ssimon
222296341Sdelphij    return ret;
223296341Sdelphij}
224160814Ssimon
225296341Sdelphijint pqueue_size(pqueue_s *pq)
226296341Sdelphij{
227296341Sdelphij    pitem *item = pq->items;
228296341Sdelphij    int count = 0;
229196474Ssimon
230296341Sdelphij    while (item != NULL) {
231296341Sdelphij        count++;
232296341Sdelphij        item = item->next;
233296341Sdelphij    }
234296341Sdelphij    return count;
235196474Ssimon}
236