source: roaraudio/libroar/buffer.c @ 996:56340a6a3c76

Last change on this file since 996:56340a6a3c76 was 996:56340a6a3c76, checked in by phi, 15 years ago

added new error messages to roar_buffer_shift_out()

File size: 6.0 KB
Line 
1//buffer.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroar.h"
36
37int roar_buffer_new      (struct roar_buffer ** buf, size_t len) {
38 struct roar_buffer * new;
39
40 ROAR_DBG("buffer_new(buf=%p, len=%i) = ?", buf, len);
41
42 if ((new = malloc(sizeof(struct roar_buffer))) == NULL) {
43  *buf = NULL;
44  return -1;
45 }
46
47 if ((new->data = malloc(len)) == NULL) {
48  free(new);
49  *buf = NULL;
50  return -1;
51 }
52
53 new->user_data = new->data;
54
55 new->next      = NULL;
56
57 new->len       = len;
58 new->user_len  = len;
59 *buf           = new;
60
61 ROAR_DBG("buffer_new(buf=%p, len=%i): New buffer at %p", buf, len, new);
62
63 return 0;
64}
65
66int roar_buffer_free     (struct roar_buffer * buf) {
67 struct roar_buffer * next;
68
69 if ( buf == NULL )
70  return -1;
71
72 while ((next = buf->next)) {
73  free(buf->data);
74  free(buf);
75  buf = next;
76 }
77
78 free(buf->data);
79 free(buf);
80
81 return 0;
82}
83
84int roar_buffer_delete   (struct roar_buffer * buf, struct roar_buffer ** next) {
85 if ( buf == NULL ) {
86  if ( next != NULL )
87   *next = NULL;
88  return -1;
89 }
90
91 ROAR_DBG("buffer_delete(buf=%p, next=%p) = ?", buf, next);
92
93 if ( next != NULL )
94  *next = buf->next;
95
96 free(buf->data);
97 free(buf);
98
99 ROAR_DBG("buffer_delete(buf=%p, next=%p) = 0", buf, next);
100 return 0;
101}
102
103int roar_buffer_add      (struct roar_buffer * buf, struct roar_buffer *  next) {
104 if ( buf == NULL )
105  return -1;
106
107 ROAR_DBG("buffer_add(buf=%p, next=%p) = ?", buf, next);
108
109 while ( buf->next != NULL ) {
110  ROAR_DBG("buffer_add(*): buf=%p, next=%p (len=%i)", buf, buf->next, buf->user_len);
111//  ROAR_DBG("buffer_add(): buf=%p, buf->next=%p", buf, buf->next);
112  buf = buf->next;
113 }
114
115 buf->next = next;
116
117 return 0;
118}
119
120int roar_buffer_get_next (struct roar_buffer *  buf, struct roar_buffer ** next) {
121 if ( buf == NULL )
122  return -1;
123
124 *next = buf->next;
125
126 return 0;
127}
128
129int roar_buffer_get_data (struct roar_buffer *  buf, void   ** data) {
130 if ( buf == NULL )
131  return -1;
132
133 *data = buf->user_data;
134
135 return 0;
136}
137
138int roar_buffer_set_offset (struct roar_buffer *  buf, size_t off) {
139 if ( buf == NULL )
140  return -1;
141
142 buf->user_len  -= off;
143 buf->user_data += off;
144
145 return 0;
146}
147
148int roar_buffer_shift_out (struct roar_buffer ** buf, void * data, size_t * len) {
149 size_t todo, cl;
150 struct roar_buffer * cur;
151 void * cd;
152
153 if ( len == NULL || buf == NULL || data == NULL ) {
154  ROAR_DBG("roar_buffer_shift_out(buf=%p, data=%p, len={%lu}) = -1 // Invalid input", buf, data, (unsigned long)len);
155  return -1;
156 }
157
158 if ( *buf == NULL ) {
159  ROAR_DBG("roar_buffer_shift_out(buf=%p, data=%p, len={%lu}) = -1 // Invalid pointer to buffer ring", buf, data, (unsigned long)len);
160  return -1;
161 }
162
163 todo = *len;
164 cur  = *buf;
165
166 *len = 0;
167
168 while (todo) {
169  ROAR_DBG("roar_buffer_shift_out(*): todo=%u, cur=%p", (unsigned int) todo, cur);
170
171  if ( roar_buffer_get_len(cur, &cl) == -1 )
172   return -1;
173
174  if ( cl > todo ) {
175   if ( roar_buffer_get_data(cur, &cd) == -1 )
176    return -1;
177
178   cl = todo;
179
180   memcpy(data, cd, cl);
181   todo -= cl;
182   data += cl;
183   *len += cl;
184
185   if ( roar_buffer_set_offset(cur, cl) == -1 )
186    return -1;
187  } else {
188   if ( roar_buffer_get_data(cur, &cd) == -1 )
189    return -1;
190
191   memcpy(data, cd, cl);
192   todo -= cl;
193   data += cl;
194   *len += cl;
195
196   if ( roar_buffer_next(&cur) == -1 )
197    return -1;
198  }
199
200/*
201  if ( cur == NULL )
202   break;
203*/
204 }
205
206 *buf = cur;
207
208 return 0;
209}
210
211int roar_buffer_set_meta (struct roar_buffer * buf, void *  meta) {
212 if ( buf == NULL )
213  return -1;
214
215 buf->meta = meta;
216
217 return 0;
218}
219
220int roar_buffer_get_meta (struct roar_buffer * buf, void ** meta) {
221 if ( buf == NULL )
222  return -1;
223
224 *meta = buf->meta;
225
226 return 0;
227}
228
229int roar_buffer_set_len  (struct roar_buffer *  buf, size_t    len) {
230 if ( buf == NULL )
231  return -1;
232
233 buf->user_len = len;
234
235 return 0;
236}
237
238int roar_buffer_get_len  (struct roar_buffer *  buf, size_t *  len) {
239 if ( buf == NULL )
240  return -1;
241
242 *len = buf->user_len;
243
244 return 0;
245}
246
247int roar_buffer_duplicate (struct roar_buffer *  buf, struct roar_buffer ** copy) {
248 struct roar_buffer *  cur = buf;
249 struct roar_buffer *  new;
250 void * od, * nd;
251
252 *copy = NULL;
253
254 while (cur) {
255  if ( roar_buffer_new(&new, cur->user_len) == -1 ) {
256   roar_buffer_free(*copy);
257   return -1;
258  }
259
260  if ( *copy == NULL )
261   *copy = new;
262
263  roar_buffer_get_data(cur, &od);
264  roar_buffer_get_data(new, &nd);
265  memcpy(nd, od, cur->user_len);
266
267  roar_buffer_add(*copy, new);
268
269  cur = cur->next;
270 }
271 return 0;
272}
273
274int roar_buffer_ring_stats (struct roar_buffer *  buf, struct roar_buffer_stats * stats) {
275 if ( buf == NULL )
276  return -1;
277
278 stats->parts        = 0;
279 stats->bytes        = 0;
280 stats->memory_usage = 0;
281
282 while (buf) {
283  stats->parts++;
284  stats->bytes        += buf->user_len;
285  stats->memory_usage += buf->len + sizeof(struct roar_buffer);
286  buf = buf->next;
287 }
288
289 return 0;
290}
291
292//ll
Note: See TracBrowser for help on using the repository browser.