3 * AT chat library with GLib integration
5 * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
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.
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.
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
30 #include "ringbuffer.h"
32 #define MAX_SIZE 262144
34 struct ring_buffer *ring_buffer_new(unsigned int size)
36 unsigned int real_size = 1;
37 struct ring_buffer *buffer;
39 /* Find the next power of two for size */
40 while (real_size < size && real_size < MAX_SIZE)
41 real_size = real_size << 1;
43 if (real_size > MAX_SIZE)
46 buffer = g_new(struct ring_buffer, 1);
51 buffer->buffer = g_new(unsigned char, real_size);
53 if (!buffer->buffer) {
58 buffer->size = real_size;
65 int ring_buffer_write(struct ring_buffer *buf, const void *data,
70 const unsigned char *d = data; /* Needed to satisfy non-gcc compilers */
72 /* Determine how much we can actually write */
73 len = MIN(len, buf->size - buf->in + buf->out);
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);
80 /* Now put the remainder on the beginning of the buffer */
81 memcpy(buf->buffer, d + end, len - end);
88 unsigned char *ring_buffer_write_ptr(struct ring_buffer *buf)
90 return buf->buffer + buf->in % buf->size;
93 int ring_buffer_avail_no_wrap(struct ring_buffer *buf)
95 unsigned int offset = buf->in % buf->size;
96 unsigned int len = buf->size - buf->in + buf->out;
98 return MIN(len, buf->size - offset);
101 int ring_buffer_write_advance(struct ring_buffer *buf, unsigned int len)
103 len = MIN(len, buf->size - buf->in + buf->out);
109 int ring_buffer_read(struct ring_buffer *buf, void *data, unsigned int len)
113 unsigned char *d = data;
115 len = MIN(len, buf->in - buf->out);
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);
122 /* Now grab remainder from the beginning */
123 memcpy(d + end, buf->buffer, len - end);
127 if (buf->out == buf->in)
128 buf->out = buf->in = 0;
133 int ring_buffer_drain(struct ring_buffer *buf, unsigned int len)
135 len = MIN(len, buf->in - buf->out);
139 if (buf->out == buf->in)
140 buf->out = buf->in = 0;
145 int ring_buffer_len_no_wrap(struct ring_buffer *buf)
147 unsigned int offset = buf->out % buf->size;
148 unsigned int len = buf->in - buf->out;
150 return MIN(len, buf->size - offset);
153 unsigned char *ring_buffer_read_ptr(struct ring_buffer *buf,
156 return buf->buffer + (buf->out + offset) % buf->size;
159 int ring_buffer_len(struct ring_buffer *buf)
164 return buf->in - buf->out;
167 void ring_buffer_reset(struct ring_buffer *buf)
176 int ring_buffer_avail(struct ring_buffer *buf)
181 return buf->size - buf->in + buf->out;
184 int ring_buffer_capacity(struct ring_buffer *buf)
192 void ring_buffer_free(struct ring_buffer *buf)