]> git.proxmox.com Git - spiceterm.git/blame - ring.h
implement scroll
[spiceterm.git] / ring.h
CommitLineData
cc04455b
DM
1/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 Copyright (C) 2009 Red Hat, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifndef _H_RING2
20#define _H_RING2
21
22#include <glib.h>
23#include <spice/macros.h>
24//#include "spice_common.h"
25
26SPICE_BEGIN_DECLS
27
28typedef struct Ring RingItem;
29typedef struct Ring {
30 RingItem *prev;
31 RingItem *next;
32} Ring;
33
34static inline void ring_init(Ring *ring)
35{
36 ring->next = ring->prev = ring;
37}
38
39static inline void ring_item_init(RingItem *item)
40{
41 item->next = item->prev = NULL;
42}
43
44static inline int ring_item_is_linked(RingItem *item)
45{
46 return !!item->next;
47}
48
49static inline int ring_is_empty(Ring *ring)
50{
51 g_assert(ring->next != NULL && ring->prev != NULL);
52 return ring == ring->next;
53}
54
55static inline void ring_add(Ring *ring, RingItem *item)
56{
57 g_assert(ring->next != NULL && ring->prev != NULL);
58 g_assert(item->next == NULL && item->prev == NULL);
59
60 item->next = ring->next;
61 item->prev = ring;
62 ring->next = item->next->prev = item;
63}
64
65static inline void ring_add_after(RingItem *item, RingItem *pos)
66{
67 ring_add(pos, item);
68}
69
70static inline void ring_add_before(RingItem *item, RingItem *pos)
71{
72 ring_add(pos->prev, item);
73}
74
75static inline void __ring_remove(RingItem *item)
76{
77 item->next->prev = item->prev;
78 item->prev->next = item->next;
79 item->prev = item->next = 0;
80}
81
82static inline void ring_remove(RingItem *item)
83{
84 g_assert(item->next != NULL && item->prev != NULL);
85 g_assert(item->next != item);
86
87 __ring_remove(item);
88}
89
90static inline RingItem *ring_get_head(Ring *ring)
91{
92 RingItem *ret;
93
94 g_assert(ring->next != NULL && ring->prev != NULL);
95
96 if (ring_is_empty(ring)) {
97 return NULL;
98 }
99 ret = ring->next;
100 return ret;
101}
102
103static inline RingItem *ring_get_tail(Ring *ring)
104{
105 RingItem *ret;
106
107 g_assert(ring->next != NULL && ring->prev != NULL);
108
109 if (ring_is_empty(ring)) {
110 return NULL;
111 }
112 ret = ring->prev;
113 return ret;
114}
115
116static inline RingItem *ring_next(Ring *ring, RingItem *pos)
117{
118 RingItem *ret;
119
120 g_assert(ring->next != NULL && ring->prev != NULL);
121 g_assert(pos);
122 g_assert(pos->next != NULL && pos->prev != NULL);
123 ret = pos->next;
124 return (ret == ring) ? NULL : ret;
125}
126
127static inline RingItem *ring_prev(Ring *ring, RingItem *pos)
128{
129 RingItem *ret;
130
131 g_assert(ring->next != NULL && ring->prev != NULL);
132 g_assert(pos);
133 g_assert(pos->next != NULL && pos->prev != NULL);
134 ret = pos->prev;
135 return (ret == ring) ? NULL : ret;
136}
137
138#define RING_FOREACH_SAFE(var, next, ring) \
139 for ((var) = ring_get_head(ring); \
140 (var) && ((next) = ring_next(ring, (var)), 1); \
141 (var) = (next))
142
143
144#define RING_FOREACH(var, ring) \
145 for ((var) = ring_get_head(ring); \
146 (var); \
147 (var) = ring_next(ring, var))
148
149#define RING_FOREACH_REVERSED(var, ring) \
150 for ((var) = ring_get_tail(ring); \
151 (var); \
152 (var) = ring_prev(ring, var))
153
154
155static inline unsigned int ring_get_length(Ring *ring)
156{
157 RingItem *i;
158 unsigned int ret = 0;
159
160 for (i = ring_get_head(ring);
161 i != NULL;
162 i = ring_next(ring, i))
163 ret++;
164
165 return ret;
166}
167
168SPICE_END_DECLS
169
170#endif