1/*
2 *  OpenVPN -- An application to securely tunnel IP networks
3 *             over a single UDP port, with support for SSL/TLS-based
4 *             session authentication and key exchange,
5 *             packet encryption, packet authentication, and
6 *             packet compression.
7 *
8 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
9 *
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 2
12 *  as published by the Free Software Foundation.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program (see the file COPYING included with this
21 *  distribution); if not, write to the Free Software Foundation, Inc.,
22 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25#ifndef CIRC_LIST_H
26#define CIRC_LIST_H
27
28#include "basic.h"
29#include "integer.h"
30#include "error.h"
31
32#define CIRC_LIST(name, type) \
33struct name { \
34  int x_head; \
35  int x_size; \
36  int x_cap; \
37  int x_sizeof; \
38  type x_list[EMPTY_ARRAY_SIZE]; \
39}
40
41#define CIRC_LIST_PUSH(obj, item) \
42{ \
43  (obj)->x_head = modulo_add ((obj)->x_head, -1, (obj)->x_cap); \
44  (obj)->x_list[(obj)->x_head] = (item); \
45  (obj)->x_size = min_int ((obj)->x_size + 1, (obj)->x_cap); \
46}
47
48#define CIRC_LIST_SIZE(obj) \
49  ((obj)->x_size)
50
51#define CIRC_LIST_INDEX(obj, index) \
52  modulo_add ((obj)->x_head, \
53              index_verify ((index), (obj)->x_size, __FILE__, __LINE__), \
54              (obj)->x_cap)
55
56#define CIRC_LIST_ITEM(obj, index) \
57  ((obj)->x_list[CIRC_LIST_INDEX((obj), (index))])
58
59#define CIRC_LIST_RESET(obj) \
60{ \
61  (obj)->x_head = 0; \
62  (obj)->x_size = 0; \
63}
64
65#define CIRC_LIST_ALLOC(dest, list_type, size) \
66{ \
67  const int so = sizeof (list_type) + sizeof ((dest)->x_list[0]) * (size); \
68  (dest) = (list_type *) malloc (so); \
69  check_malloc_return (dest); \
70  memset ((dest), 0, so); \
71  (dest)->x_cap = size; \
72  (dest)->x_sizeof = so; \
73}
74
75#define CIRC_LIST_FREE(dest) \
76  free (dest)
77
78#endif
79