source: roaraudio/libroar/buffer.c @ 2976:41c1c4bae1d4

Last change on this file since 2976:41c1c4bae1d4 was 2976:41c1c4bae1d4, checked in by phi, 15 years ago

added memmgr.h, allready used by buffer

File size: 8.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 void * data;
39
40 if ((data = roar_mm_malloc(len)) == NULL) {
41  return -1;
42 }
43
44 if ( roar_buffer_new_no_ma(buf, len, data) == -1 ) {
45  roar_mm_free(data);
46  return -1;
47 }
48
49 if ( roar_buffer_set_flag(*buf, ROAR_BUFFER_FLAG_NOFREE, ROAR_BUFFER_RESET) == -1 ) {
50  roar_buffer_free(*buf);
51  roar_mm_free(data);
52  return -1;
53 }
54
55 return 0;
56}
57
58int roar_buffer_new_no_ma(struct roar_buffer ** buf, size_t len, void * data) { // no internal malloc
59 struct roar_buffer * new;
60
61 ROAR_DBG("buffer_new(buf=%p, len=%i) = ?", buf, len);
62
63 if ( buf == NULL || data == NULL )
64  return -1;
65
66 if ((new = roar_mm_malloc(sizeof(struct roar_buffer))) == NULL) {
67  *buf = NULL;
68  return -1;
69 }
70
71 new->data      = data;
72
73 new->flags     = ROAR_BUFFER_FLAG_NONE|ROAR_BUFFER_FLAG_NOFREE;
74
75 new->user_data = new->data;
76
77 new->next      = NULL;
78
79 new->len       = len;
80 new->user_len  = len;
81 *buf           = new;
82
83 ROAR_DBG("buffer_new(buf=%p, len=%i): New buffer at %p", buf, len, new);
84
85 return 0;
86}
87
88int roar_buffer_free     (struct roar_buffer * buf) {
89 struct roar_buffer * next;
90
91 if ( buf == NULL )
92  return -1;
93
94 while ((next = buf->next)) {
95  if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
96   roar_mm_free(buf->data);
97
98  roar_mm_free(buf);
99  buf = next;
100 }
101
102 if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
103  roar_mm_free(buf->data);
104
105 roar_mm_free(buf);
106
107 return 0;
108}
109
110int roar_buffer_delete   (struct roar_buffer * buf, struct roar_buffer ** next) {
111 if ( buf == NULL ) {
112  if ( next != NULL )
113   *next = NULL;
114  return -1;
115 }
116
117 ROAR_DBG("buffer_delete(buf=%p, next=%p) = ?", buf, next);
118
119 if ( next != NULL )
120  *next = buf->next;
121
122 if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
123  roar_mm_free(buf->data);
124
125 roar_mm_free(buf);
126
127 ROAR_DBG("buffer_delete(buf=%p, next=%p) = 0", buf, next);
128 return 0;
129}
130
131int roar_buffer_add      (struct roar_buffer * buf, struct roar_buffer *  next) {
132 unsigned int deep = 0;
133
134 if ( buf == NULL )
135  return -1;
136
137 ROAR_DBG("buffer_add(buf=%p, next=%p) = ?", buf, next);
138
139 if ( buf == next ) {
140  ROAR_ERR("buffer_add(*): both pointer are of the same destination, This is a error in the application");
141  return -1;
142 }
143
144 while ( buf->next != NULL ) {
145  ROAR_DBG("buffer_add(*): buf=%p, next=%p (len=%i)", buf, buf->next, buf->user_len);
146//  ROAR_DBG("buffer_add(): buf=%p, buf->next=%p", buf, buf->next);
147  buf = buf->next;
148  deep++;
149
150  if ( buf == next ) {
151   ROAR_ERR("buffer_add(*): Can not add buffer: loop detected at deep %u. This is a error in the application", deep);
152  }
153 }
154
155 buf->next = next;
156
157 ROAR_DBG("buffer_add(*): adding buffer at deep %u", deep);
158
159 return 0;
160}
161
162int roar_buffer_get_next (struct roar_buffer *  buf, struct roar_buffer ** next) {
163 if ( buf == NULL )
164  return -1;
165
166 *next = buf->next;
167
168 return 0;
169}
170
171int roar_buffer_get_data (struct roar_buffer *  buf, void   ** data) {
172 if ( buf == NULL )
173  return -1;
174
175 *data = buf->user_data;
176
177 return 0;
178}
179
180int roar_buffer_set_offset (struct roar_buffer *  buf, size_t off) {
181 if ( buf == NULL )
182  return -1;
183
184 buf->user_len  -= off;
185 buf->user_data += off;
186
187 return 0;
188}
189
190int roar_buffer_shift_out (struct roar_buffer ** buf, void * data, size_t * len) {
191 size_t todo, cl;
192 struct roar_buffer * cur;
193 void * cd;
194
195 if ( len == NULL || buf == NULL || data == NULL ) {
196  ROAR_DBG("roar_buffer_shift_out(buf=%p, data=%p, len={%lu}) = -1 // Invalid input", buf, data, (unsigned long)*len);
197  return -1;
198 }
199
200 if ( *buf == NULL ) {
201  ROAR_DBG("roar_buffer_shift_out(buf=%p, data=%p, len={%lu}) = -1 // Invalid pointer to buffer ring", buf, data, (unsigned long)len);
202  return -1;
203 }
204
205 todo = *len;
206 cur  = *buf;
207
208 *len = 0;
209
210 while (todo && cur != NULL) {
211  ROAR_DBG("roar_buffer_shift_out(*): todo=%u, cur=%p", (unsigned int) todo, cur);
212
213  if ( roar_buffer_get_len(cur, &cl) == -1 )
214   return -1;
215
216  if ( cl > todo ) {
217   if ( roar_buffer_get_data(cur, &cd) == -1 )
218    return -1;
219
220   cl = todo;
221
222   memcpy(data, cd, cl);
223   todo -= cl;
224   data += cl;
225   *len += cl;
226
227   if ( roar_buffer_set_offset(cur, cl) == -1 )
228    return -1;
229  } else {
230   if ( roar_buffer_get_data(cur, &cd) == -1 )
231    return -1;
232
233   memcpy(data, cd, cl);
234   todo -= cl;
235   data += cl;
236   *len += cl;
237
238   if ( roar_buffer_next(&cur) == -1 )
239    return -1;
240  }
241
242/*
243  if ( cur == NULL )
244   break;
245*/
246 }
247
248 *buf = cur;
249
250 return 0;
251}
252
253int roar_buffer_set_meta (struct roar_buffer * buf, void *  meta) {
254 if ( buf == NULL )
255  return -1;
256
257 buf->meta.vp = meta;
258
259 return 0;
260}
261
262int roar_buffer_get_meta (struct roar_buffer * buf, void ** meta) {
263 if ( buf == NULL || meta == NULL )
264  return -1;
265
266 *meta = buf->meta.vp;
267
268 return 0;
269}
270
271int roar_buffer_set_meta_i32(struct roar_buffer *  buf, int32_t    meta) {
272 if ( buf == NULL )
273  return -1;
274
275 buf->meta.i32 = meta;
276
277 return 0;
278}
279
280int roar_buffer_get_meta_i32(struct roar_buffer *  buf, int32_t *  meta) {
281 if ( buf == NULL || meta == NULL )
282  return -1;
283
284 *meta = buf->meta.i32;
285
286 return 0;
287}
288
289int roar_buffer_set_len  (struct roar_buffer *  buf, size_t    len) {
290 size_t   totlen;
291 void   * newbuf;
292
293 if ( buf == NULL )
294  return -1;
295
296 if ( len > buf->user_len ) {
297  totlen = buf->len - buf->user_len + len;
298  newbuf = realloc(buf->data, totlen);
299  if ( newbuf == NULL )
300   return -1;
301
302  buf->data = newbuf;
303  buf->user_len = len;
304 } else {
305  buf->user_len = len;
306 }
307
308 return 0;
309}
310
311int roar_buffer_get_len  (struct roar_buffer *  buf, size_t *  len) {
312 if ( buf == NULL )
313  return -1;
314
315 *len = buf->user_len;
316
317 return 0;
318}
319
320int roar_buffer_set_flag (struct roar_buffer *  buf, int flag, int reset) {
321 if ( buf == NULL )
322  return -1;
323
324 buf->flags |= flag;
325
326 if ( reset )
327  buf->flags -= flag;
328
329 return 0;
330}
331
332int roar_buffer_get_flag (struct roar_buffer *  buf, int flag) {
333 if ( buf == NULL )
334  return -1;
335
336 return buf->flags & flag;
337}
338
339int roar_buffer_duplicate (struct roar_buffer *  buf, struct roar_buffer ** copy) {
340 struct roar_buffer *  cur = buf;
341 struct roar_buffer *  new;
342 void * od, * nd;
343
344 *copy = NULL;
345
346 while (cur) {
347  if ( roar_buffer_new(&new, cur->user_len) == -1 ) {
348   roar_buffer_free(*copy);
349   return -1;
350  }
351
352  if ( *copy == NULL )
353   *copy = new;
354
355  roar_buffer_get_data(cur, &od);
356  roar_buffer_get_data(new, &nd);
357  memcpy(nd, od, cur->user_len);
358
359  roar_buffer_add(*copy, new);
360
361  cur = cur->next;
362 }
363 return 0;
364}
365
366int roar_buffer_ring_stats (struct roar_buffer *  buf, struct roar_buffer_stats * stats) {
367 if ( buf == NULL )
368  return -1;
369
370 stats->parts        = 0;
371 stats->bytes        = 0;
372 stats->memory_usage = 0;
373
374 while (buf) {
375  stats->parts++;
376  stats->bytes        += buf->user_len;
377  stats->memory_usage += buf->len + sizeof(struct roar_buffer);
378  buf = buf->next;
379 }
380
381 return 0;
382}
383
384//ll
Note: See TracBrowser for help on using the repository browser.