1 /* sbuffer.c - jonclegg@yahoo.com
2 * general use circular buffer lib
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <stdlib.h>
20 #include "cbuffer.h"
21
22 /*********************************************************************************
23 * Public functions
24 *********************************************************************************/
25 int cbuffer_init(CBUFFER *buffer, unsigned long size);
26 void cbuffer_destroy(CBUFFER *buffer);
27 int cbuffer_extract(CBUFFER *buffer, char *items, unsigned long count);
28 int cbuffer_peek(CBUFFER *buffer, char *items, unsigned long count);
29 int cbuffer_insert(CBUFFER *buffer, const char *items, unsigned long count);
30 unsigned long cbuffer_get_free(CBUFFER *buffer);
31 unsigned long cbuffer_get_used(CBUFFER *buffer);
32 unsigned long cbuffer_get_size(CBUFFER *buffer);
33
34
35 /*********************************************************************************
36 * Private functions
37 *********************************************************************************/
38 static void reset(CBUFFER *buffer);
39 static void increment(CBUFFER *buffer, unsigned long *index);
40
cbuffer_init(CBUFFER * buffer,unsigned long size)41 int cbuffer_init(CBUFFER *buffer, unsigned long size)
42 {
43 if (size == 0) {
44 return 0;
45 }
46 if (size == 0) {
47 buffer->size = 0;
48 buffer->buf = NULL;
49 reset(buffer);
50 } else {
51 buffer->size = size;
52 buffer->buf = (char *)malloc(size);
53 reset(buffer);
54 }
55
56 return 1;
57 }
58
cbuffer_destroy(CBUFFER * buffer)59 void cbuffer_destroy(CBUFFER *buffer)
60 {
61 if (buffer->buf)
62 {
63 free(buffer->buf);
64 buffer->buf = NULL;
65 }
66 }
67
cbuffer_extract(CBUFFER * buffer,char * items,unsigned long count)68 int cbuffer_extract(CBUFFER *buffer, char *items, unsigned long count)
69 {
70 unsigned long i;
71
72 if (buffer->buf) {
73 for(i = 0; i < count; i++)
74 {
75 if (buffer->item_count > 0)
76 buffer->item_count--;
77 else
78 return BUFFER_EMPTY;
79
80 increment(buffer, &buffer->read_index);
81 items[i] = buffer->buf[buffer->read_index];
82 }
83 }
84 else {
85 return 0;
86 }
87 return 1;
88 }
89
90
cbuffer_peek(CBUFFER * buffer,char * items,unsigned long count)91 int cbuffer_peek(CBUFFER *buffer, char *items, unsigned long count)
92 {
93 unsigned long i;
94 unsigned long my_read_index = buffer->read_index;
95 unsigned long my_item_count = buffer->item_count;
96
97 for(i = 0; i < count; i++)
98 {
99 if (my_item_count > 0)
100 my_item_count--;
101 else
102 return BUFFER_EMPTY;
103
104 increment(buffer, &my_read_index);
105 items[i] = buffer->buf[my_read_index];
106 }
107 return 1;
108 }
109
110
cbuffer_insert(CBUFFER * buffer,const char * items,unsigned long count)111 int cbuffer_insert(CBUFFER *buffer, const char *items, unsigned long count)
112 {
113 unsigned long i;
114
115 for(i = 0; i < count; i++)
116 {
117 if (buffer->item_count < cbuffer_get_size(buffer))
118 buffer->item_count++;
119 else
120 return BUFFER_FULL;
121
122 increment(buffer, &buffer->write_index);
123 buffer->buf[buffer->write_index] = items[i];
124 }
125
126 return 1;
127 }
128
cbuffer_get_size(CBUFFER * buffer)129 unsigned long cbuffer_get_size(CBUFFER *buffer)
130 {
131 return buffer->size;
132
133 }
134
cbuffer_get_free(CBUFFER * buffer)135 unsigned long cbuffer_get_free(CBUFFER *buffer)
136 {
137 return cbuffer_get_size(buffer) - cbuffer_get_used(buffer);
138 }
139
cbuffer_get_used(CBUFFER * buffer)140 unsigned long cbuffer_get_used(CBUFFER *buffer)
141 {
142 return buffer->item_count;
143 }
144
145
increment(CBUFFER * buffer,unsigned long * index)146 void increment(CBUFFER *buffer, unsigned long *index)
147 {
148 (*index)++;
149 if (*index >= cbuffer_get_size(buffer))
150 *index = 0;
151 }
152
reset(CBUFFER * buffer)153 void reset(CBUFFER *buffer)
154 {
155 buffer->read_index = buffer->write_index = cbuffer_get_size(buffer) - 1;
156 buffer->item_count = 0;
157 }
158
159
160