Remove obsolete file.
[connman] / gatchat / ringbuffer.c
1 /*
2  *
3  *  AT chat library with GLib integration
4  *
5  *  Copyright (C) 2008-2009  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27
28 #include <glib.h>
29
30 #include "ringbuffer.h"
31
32 #define MAX_SIZE 262144
33
34 struct ring_buffer *ring_buffer_new(unsigned int size)
35 {
36         unsigned int real_size = 1;
37         struct ring_buffer *buffer;
38
39         /* Find the next power of two for size */
40         while (real_size < size && real_size < MAX_SIZE)
41                 real_size = real_size << 1;
42
43         if (real_size > MAX_SIZE)
44                 return NULL;
45
46         buffer = g_new(struct ring_buffer, 1);
47
48         if (!buffer)
49                 return NULL;
50
51         buffer->buffer = g_new(unsigned char, real_size);
52
53         if (!buffer->buffer) {
54                 g_free(buffer);
55                 return NULL;
56         }
57
58         buffer->size = real_size;
59         buffer->in = 0;
60         buffer->out = 0;
61
62         return buffer;
63 }
64
65 int ring_buffer_write(struct ring_buffer *buf, const void *data,
66                         unsigned int len)
67 {
68         unsigned int end;
69         unsigned int offset;
70         const unsigned char *d = data; /* Needed to satisfy non-gcc compilers */
71
72         /* Determine how much we can actually write */
73         len = MIN(len, buf->size - buf->in + buf->out);
74
75         /* Determine how much to write before wrapping */
76         offset = buf->in % buf->size;
77         end = MIN(len, buf->size - offset);
78         memcpy(buf->buffer+offset, d, end);
79
80         /* Now put the remainder on the beginning of the buffer */
81         memcpy(buf->buffer, d + end, len - end);
82
83         buf->in += len;
84
85         return len;
86 }
87
88 unsigned char *ring_buffer_write_ptr(struct ring_buffer *buf)
89 {
90         return buf->buffer + buf->in % buf->size;
91 }
92
93 int ring_buffer_avail_no_wrap(struct ring_buffer *buf)
94 {
95         unsigned int offset = buf->in % buf->size;
96         unsigned int len = buf->size - buf->in + buf->out;
97
98         return MIN(len, buf->size - offset);
99 }
100
101 int ring_buffer_write_advance(struct ring_buffer *buf, unsigned int len)
102 {
103         len = MIN(len, buf->size - buf->in + buf->out);
104         buf->in += len;
105
106         return len;
107 }
108
109 int ring_buffer_read(struct ring_buffer *buf, void *data, unsigned int len)
110 {
111         unsigned int end;
112         unsigned int offset;
113         unsigned char *d = data;
114
115         len = MIN(len, buf->in - buf->out);
116
117         /* Grab data from buffer starting at offset until the end */
118         offset = buf->out % buf->size;
119         end = MIN(len, buf->size - offset);
120         memcpy(d, buf->buffer + offset, end);
121
122         /* Now grab remainder from the beginning */
123         memcpy(d + end, buf->buffer, len - end);
124
125         buf->out += len;
126
127         if (buf->out == buf->in)
128                 buf->out = buf->in = 0;
129
130         return len;
131 }
132
133 int ring_buffer_drain(struct ring_buffer *buf, unsigned int len)
134 {
135         len = MIN(len, buf->in - buf->out);
136
137         buf->out += len;
138
139         if (buf->out == buf->in)
140                 buf->out = buf->in = 0;
141
142         return len;
143 }
144
145 int ring_buffer_len_no_wrap(struct ring_buffer *buf)
146 {
147         unsigned int offset = buf->out % buf->size;
148         unsigned int len = buf->in - buf->out;
149
150         return MIN(len, buf->size - offset);
151 }
152
153 unsigned char *ring_buffer_read_ptr(struct ring_buffer *buf,
154                                         unsigned int offset)
155 {
156         return buf->buffer + (buf->out + offset) % buf->size;
157 }
158
159 int ring_buffer_len(struct ring_buffer *buf)
160 {
161         if (!buf)
162                 return -1;
163
164         return buf->in - buf->out;
165 }
166
167 void ring_buffer_reset(struct ring_buffer *buf)
168 {
169         if (!buf)
170                 return;
171
172         buf->in = 0;
173         buf->out = 0;
174 }
175
176 int ring_buffer_avail(struct ring_buffer *buf)
177 {
178         if (!buf)
179                 return -1;
180
181         return buf->size - buf->in + buf->out;
182 }
183
184 int ring_buffer_capacity(struct ring_buffer *buf)
185 {
186         if (!buf)
187                 return -1;
188
189         return buf->size;
190 }
191
192 void ring_buffer_free(struct ring_buffer *buf)
193 {
194         if (!buf)
195                 return;
196
197         g_free(buf->buffer);
198         g_free(buf);
199 }