ogg_afh.c: Kill unused vi_bitrate_nominal
[paraslash.git] / ringbuffer.c
1 /*
2  * Copyright (C) 2006 Andre Noll <maan@systemlinux.org>
3  *
4  *     This program is free software; you can redistribute it and/or modify
5  *     it under the terms of the GNU General Public License as published by
6  *     the Free Software Foundation; either version 2 of the License, or
7  *     (at your option) any later version.
8  *
9  *     This program is distributed in the hope that it will be useful,
10  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *     GNU General Public License for more details.
13  *
14  *     You should have received a copy of the GNU General Public License
15  *     along with this program; if not, write to the Free Software
16  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17  */
18
19 /** \file ringbuffer.c simple ringbuffer implementation */
20
21 #include "para.h"
22 #include "ringbuffer.h"
23 #include "string.h"
24
25 /**
26  * holds all information about one ring buffer
27  *
28  * It is intentionally not exported via ringbuffer.h. Think abstract.
29  */
30 struct ringbuffer
31 {
32 /**
33  *
34  *
35  * the size of this ring buffer
36 */
37 unsigned size;
38 /**
39  *
40  *
41  * the actual entries of the ringbuffer
42 */
43 void **entries;
44 /**
45  *
46  *
47  * the next entry will be added at this position
48  */
49 int head;
50 /**
51  *
52  * how many entries the ring buffer contains
53 */
54 unsigned filled;
55 };
56
57 /**
58  * initialize a new ringbuffer
59  *
60  * @param size the number of entries the ringbuffer holds
61  *
62  * This function initializes a circular ring buffer which can hold up to \a
63  * size entries of arbitrary type. If performance is an issue, \a size should
64  * be a power of two to make the underlying modulo operations cheap. Arbitrary
65  * many ringbuffers may be initialized via this function. Each ringbuffer is
66  * identified by a 'cookie'.
67  *
68  * Return value: A 'cookie' which identifies the ringbuffer just created and
69  * which must be passed to ringbuffer_add() and ringbuffer_get().
70  */
71 void *ringbuffer_new(unsigned size)
72 {
73         struct ringbuffer *rb = para_calloc(sizeof(struct ringbuffer));
74         rb->entries = para_calloc(size * sizeof(void *));
75         rb->size = size;
76         return rb;
77 };
78
79 /**
80  * add one entry to a ringbuffer
81  *
82  * @param cookie the ringbuffer identifier
83  * @param data the data to be inserted
84  *
85  * insert \a data into the ringbuffer associated with \a cookie.  As soon as
86  * the ringbuffer fills up, its oldest entry is disregarded and replaced by \a
87  * data.
88  *
89  * \return The old \a data pointer which is going to be disregarded, or
90  * NULL if the ringbuffer is not yet full.
91  */
92 void *ringbuffer_add(void *cookie, void *data)
93 {
94         struct ringbuffer *rb = cookie;
95         void *ret = rb->entries[rb->head];
96         rb->entries[rb->head] = data;
97         rb->head = (rb->head + 1) % rb->size;
98         if (rb->filled < rb->size)
99                 rb->filled++;
100         return ret;
101 }
102
103 /**
104  * get one entry from a ringbuffer
105  *
106  * @param cookie the ringbuffer identifier
107  * @param num the number of the entry
108  *
109  * \return A pointer to data previously added, or NULL if entry number
110  * \a num is not available. \a num counts backwards from zero, i.e.
111  * ringbuffer_get_entry(0) gets the entry which was added most recently.
112  */
113 void *ringbuffer_get(void *cookie, int num)
114 {
115         struct ringbuffer *rb = cookie;
116         int pos = (rb->head + rb->size - 1 - num) % rb->size;
117 //      fprintf(stderr, "pos = %d\n", pos);
118         return rb->entries[pos];
119 }
120
121 /**
122  * get the number of entries in the ring buffer
123  *
124  * @param cookie the ringbuffer identifier
125  *
126  * This function always succeeds and never returns a number greater than the
127  * size of the ring buffer.
128  */
129 unsigned ringbuffer_filled(void *cookie)
130 {
131         struct ringbuffer *rb = cookie;
132         return rb->filled;
133 }