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