source: roaraudio/libroar/buffer.c @ 4905:3b98d0dc037b

Last change on this file since 4905:3b98d0dc037b was 4905:3b98d0dc037b, checked in by phi, 13 years ago

added clean error handling

File size: 16.9 KB
RevLine 
[0]1//buffer.c:
2
[690]3/*
[4708]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
[690]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
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[690]23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
[0]36#include "libroar.h"
37
[4516]38struct roar_buffer_ring {
39 size_t read_pos;
40 size_t write_pos;
41};
42
43struct roar_buffer {
44 size_t               refc;
45 size_t               len;
46 size_t               user_len;
47 int                  flags;
48 void               * data;
49 void               * user_data;
50 union {
51  void                    * vp;
52  int32_t                   i32;
53  struct roar_buffer_ring   ring;
54 }                    meta;
[4901]55 int                  type;
[4516]56 struct roar_buffer * next;
57};
[1215]58
[4905]59#define _ckbuf(m)  if ( buf == NULL || (m) ) { roar_err_set(ROAR_ERROR_FAULT); return -1; }
60
[3764]61int roar_buffer_new_data (struct roar_buffer ** buf, size_t len, void ** data) {
62 void * bufdata;
[4905]63 int err;
[3764]64
65 if ((bufdata = roar_mm_malloc(len)) == NULL) {
[1215]66  return -1;
67 }
68
[3764]69 if ( roar_buffer_new_no_ma(buf, len, bufdata) == -1 ) {
[4905]70  err = roar_error;
[3764]71  roar_mm_free(bufdata);
[4905]72  roar_err_set(err);
[1215]73  return -1;
74 }
75
76 if ( roar_buffer_set_flag(*buf, ROAR_BUFFER_FLAG_NOFREE, ROAR_BUFFER_RESET) == -1 ) {
[4905]77  err = roar_error;
[1215]78  roar_buffer_free(*buf);
[3764]79  roar_mm_free(bufdata);
[4905]80  roar_err_set(err);
[1215]81  return -1;
82 }
83
[3764]84 if ( data != NULL )
85  *data = bufdata;
86
[1215]87 return 0;
88}
89
90int roar_buffer_new_no_ma(struct roar_buffer ** buf, size_t len, void * data) { // no internal malloc
[0]91 struct roar_buffer * new;
92
93 ROAR_DBG("buffer_new(buf=%p, len=%i) = ?", buf, len);
94
[4905]95 _ckbuf(data == NULL)
[1215]96
[2976]97 if ((new = roar_mm_malloc(sizeof(struct roar_buffer))) == NULL) {
[0]98  *buf = NULL;
99  return -1;
100 }
101
[4901]102 new->refc      =  1;
[4522]103
[1215]104 new->data      = data;
105
106 new->flags     = ROAR_BUFFER_FLAG_NONE|ROAR_BUFFER_FLAG_NOFREE;
[4901]107 new->type      = -1;
[0]108
109 new->user_data = new->data;
110
111 new->next      = NULL;
112
113 new->len       = len;
114 new->user_len  = len;
115 *buf           = new;
116
117 ROAR_DBG("buffer_new(buf=%p, len=%i): New buffer at %p", buf, len, new);
118
119 return 0;
120}
121
[4522]122int roar_buffer_ref      (struct roar_buffer *  buf) {
[4905]123 _ckbuf(0)
[4522]124
125 buf->refc++;
126
127 return 0;
128}
129
130int roar_buffer_unref     (struct roar_buffer * buf) {
[0]131 struct roar_buffer * next;
132
[4905]133 _ckbuf(0)
[0]134
[4522]135 if ( buf->refc == 0 ) {
136  ROAR_WARN("roar_buffer_unref(buf=%p): Ref counter is wrong. assuming one.");
137  buf->refc = 1;
138 }
139
140 buf->refc--;
141
142 if ( buf->refc )
143  return 0;
144
[0]145 while ((next = buf->next)) {
[2976]146  if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
147   roar_mm_free(buf->data);
148
149  roar_mm_free(buf);
[0]150  buf = next;
151 }
152
[1215]153 if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
[2976]154  roar_mm_free(buf->data);
[1215]155
[2976]156 roar_mm_free(buf);
[0]157
158 return 0;
159}
160
161int roar_buffer_delete   (struct roar_buffer * buf, struct roar_buffer ** next) {
162 if ( buf == NULL ) {
163  if ( next != NULL )
164   *next = NULL;
[4905]165  roar_err_set(ROAR_ERROR_FAULT);
[0]166  return -1;
167 }
168
169 ROAR_DBG("buffer_delete(buf=%p, next=%p) = ?", buf, next);
170
171 if ( next != NULL )
172  *next = buf->next;
173
[2976]174 if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
175  roar_mm_free(buf->data);
176
177 roar_mm_free(buf);
[0]178
179 ROAR_DBG("buffer_delete(buf=%p, next=%p) = 0", buf, next);
180 return 0;
181}
182
183int roar_buffer_add      (struct roar_buffer * buf, struct roar_buffer *  next) {
[1953]184 unsigned int deep = 0;
185
[4905]186 _ckbuf(0)
[0]187
188 ROAR_DBG("buffer_add(buf=%p, next=%p) = ?", buf, next);
189
[4905]190 if ( buf->flags & ROAR_BUFFER_FLAG_RING ) {
191  roar_err_set(ROAR_ERROR_INVAL);
[3020]192  return -1;
[4905]193 }
[3020]194
[1953]195 if ( buf == next ) {
196  ROAR_ERR("buffer_add(*): both pointer are of the same destination, This is a error in the application");
[4905]197  roar_err_set(ROAR_ERROR_INVAL);
[1953]198  return -1;
199 }
200
[0]201 while ( buf->next != NULL ) {
[302]202  ROAR_DBG("buffer_add(*): buf=%p, next=%p (len=%i)", buf, buf->next, buf->user_len);
[0]203//  ROAR_DBG("buffer_add(): buf=%p, buf->next=%p", buf, buf->next);
204  buf = buf->next;
[1953]205  deep++;
206
207  if ( buf == next ) {
208   ROAR_ERR("buffer_add(*): Can not add buffer: loop detected at deep %u. This is a error in the application", deep);
[4905]209   // why don't we return here?
[1953]210  }
[0]211 }
212
213 buf->next = next;
214
[1953]215 ROAR_DBG("buffer_add(*): adding buffer at deep %u", deep);
216
[0]217 return 0;
218}
219
[4516]220int roar_buffer_clear_next (struct roar_buffer *  buf) {
[4905]221 _ckbuf(0)
[4516]222
223 buf->next = NULL;
224
225 return 0;
226}
227
[0]228int roar_buffer_get_next (struct roar_buffer *  buf, struct roar_buffer ** next) {
[4905]229 _ckbuf(0)
[0]230
231 *next = buf->next;
232
233 return 0;
234}
235
[3020]236int roar_buffer_ring_new (struct roar_buffer ** buf, size_t len, int free_running) {
237 struct roar_buffer * n;
238
[4905]239 _ckbuf(0)
240
241 if ( len == 0 ) {
242  roar_err_set(ROAR_ERROR_RANGE);
[3020]243  return -1;
[4905]244 }
[3020]245
246 // just to be sure:
247 *buf = NULL;
248
249 if ( roar_buffer_new(&n, len) == -1 )
250  return -1;
251
252 n->flags |= ROAR_BUFFER_FLAG_RING;
253
254 if ( free_running )
255  n->flags |= ROAR_BUFFER_FLAG_FREE_RUNNING;
256
257 n->meta.ring.read_pos  = 0;
258 n->meta.ring.write_pos = 0;
259
260 memset(n->data, 0, n->len);
261
262 *buf = n;
263
264 return 0;
265}
266
[0]267int roar_buffer_get_data (struct roar_buffer *  buf, void   ** data) {
[4905]268 _ckbuf(0)
[0]269
270 *data = buf->user_data;
271
272 return 0;
273}
274
275int roar_buffer_set_offset (struct roar_buffer *  buf, size_t off) {
[4905]276 _ckbuf(0)
277
278 if ( off > buf->user_len ) {
279  roar_err_set(ROAR_ERROR_RANGE);
[0]280  return -1;
[4905]281 }
[0]282
283 buf->user_len  -= off;
284 buf->user_data += off;
285
286 return 0;
287}
288
[904]289int roar_buffer_shift_out (struct roar_buffer ** buf, void * data, size_t * len) {
290 size_t todo, cl;
291 struct roar_buffer * cur;
292 void * cd;
293
[4905]294 _ckbuf(len == NULL || data == NULL);
[904]295
[996]296 if ( *buf == NULL ) {
297  ROAR_DBG("roar_buffer_shift_out(buf=%p, data=%p, len={%lu}) = -1 // Invalid pointer to buffer ring", buf, data, (unsigned long)len);
[4905]298  roar_err_set(ROAR_ERROR_FAULT);
[904]299  return -1;
[996]300 }
[904]301
302 todo = *len;
303 cur  = *buf;
304
305 *len = 0;
306
[2066]307 while (todo && cur != NULL) {
[904]308  ROAR_DBG("roar_buffer_shift_out(*): todo=%u, cur=%p", (unsigned int) todo, cur);
309
310  if ( roar_buffer_get_len(cur, &cl) == -1 )
311   return -1;
312
313  if ( cl > todo ) {
314   if ( roar_buffer_get_data(cur, &cd) == -1 )
315    return -1;
316
317   cl = todo;
318
319   memcpy(data, cd, cl);
320   todo -= cl;
321   data += cl;
322   *len += cl;
323
324   if ( roar_buffer_set_offset(cur, cl) == -1 )
325    return -1;
326  } else {
327   if ( roar_buffer_get_data(cur, &cd) == -1 )
328    return -1;
329
330   memcpy(data, cd, cl);
331   todo -= cl;
332   data += cl;
333   *len += cl;
334
335   if ( roar_buffer_next(&cur) == -1 )
336    return -1;
337  }
338
339/*
340  if ( cur == NULL )
341   break;
342*/
343 }
344
345 *buf = cur;
346
[996]347 return 0;
[904]348}
349
[0]350int roar_buffer_set_meta (struct roar_buffer * buf, void *  meta) {
[4905]351 _ckbuf(0)
[0]352
[2333]353 buf->meta.vp = meta;
[0]354
355 return 0;
356}
357
358int roar_buffer_get_meta (struct roar_buffer * buf, void ** meta) {
[4905]359 _ckbuf(meta == NULL)
[2333]360
361 *meta = buf->meta.vp;
362
363 return 0;
364}
365
366int roar_buffer_set_meta_i32(struct roar_buffer *  buf, int32_t    meta) {
[4905]367 _ckbuf(0)
[0]368
[2333]369 buf->meta.i32 = meta;
370
371 return 0;
372}
373
374int roar_buffer_get_meta_i32(struct roar_buffer *  buf, int32_t *  meta) {
[4905]375 _ckbuf(meta == NULL)
[2333]376
377 *meta = buf->meta.i32;
[0]378
379 return 0;
380}
381
[4901]382int roar_buffer_set_type    (struct roar_buffer *  buf, int        type) {
[4905]383 _ckbuf(0)
[4901]384
[4903]385 switch (type) {
386  case ROAR_VIO_DFT_RAW:
387  case ROAR_VIO_DFT_PACKET:
388  case ROAR_VIO_DFT_UNFRAMED:
389   break;
390  default:
[4905]391    roar_err_set(ROAR_ERROR_NOTSUP);
[4903]392    return -1;
393 }
394
[4901]395 buf->type = type;
396
397 return 0;
398}
399
400int roar_buffer_get_type    (struct roar_buffer *  buf, int     *  type) {
[4905]401 _ckbuf(type == NULL)
[4901]402
403 *type = buf->type;
404
405 return 0;
406}
407
[0]408int roar_buffer_set_len  (struct roar_buffer *  buf, size_t    len) {
[2334]409 size_t   totlen;
410 void   * newbuf;
411
[4905]412 _ckbuf(0)
[0]413
[3032]414 // handle specal case where user length is zero:
415 if ( len && !buf->user_len ) {
416  buf->user_data = buf->data;
417  buf->user_len  = buf->len;
418 }
419
[2334]420 if ( len > buf->user_len ) {
[3021]421  // we can only enlage a buffer if it's one of our own memory segments
[4905]422  if ( buf->flags & ROAR_BUFFER_FLAG_NOFREE )  {
423   roar_err_set(ROAR_ERROR_NOTSUP);
[3021]424   return -1;
[4905]425  }
[3021]426
[2334]427  totlen = buf->len - buf->user_len + len;
[3021]428  newbuf = roar_mm_realloc(buf->data, totlen);
[2334]429  if ( newbuf == NULL )
430   return -1;
431
432  buf->data = newbuf;
433  buf->user_len = len;
434 } else {
435  buf->user_len = len;
436 }
[0]437
438 return 0;
439}
440
441int roar_buffer_get_len  (struct roar_buffer *  buf, size_t *  len) {
[4905]442 _ckbuf(0)
[0]443
444 *len = buf->user_len;
445
446 return 0;
447}
448
[1215]449int roar_buffer_set_flag (struct roar_buffer *  buf, int flag, int reset) {
[4905]450 _ckbuf(0)
[1215]451
452 buf->flags |= flag;
453
454 if ( reset )
455  buf->flags -= flag;
456
457 return 0;
458}
459
460int roar_buffer_get_flag (struct roar_buffer *  buf, int flag) {
[4905]461 _ckbuf(0)
[1215]462
463 return buf->flags & flag;
464}
465
[46]466int roar_buffer_duplicate (struct roar_buffer *  buf, struct roar_buffer ** copy) {
467 struct roar_buffer *  cur = buf;
468 struct roar_buffer *  new;
[48]469 void * od, * nd;
[4905]470 int err;
471
472 _ckbuf(copy == NULL)
[46]473
474 *copy = NULL;
475
[4905]476 while (cur != NULL) {
[46]477  if ( roar_buffer_new(&new, cur->user_len) == -1 ) {
[4905]478   err = roar_error;
[46]479   roar_buffer_free(*copy);
[4905]480   roar_err_set(err);
[46]481   return -1;
482  }
483
484  if ( *copy == NULL )
485   *copy = new;
486
[48]487  roar_buffer_get_data(cur, &od);
488  roar_buffer_get_data(new, &nd);
489  memcpy(nd, od, cur->user_len);
490
[46]491  roar_buffer_add(*copy, new);
492
493  cur = cur->next;
494 }
[4905]495
[46]496 return 0;
497}
498
[7]499int roar_buffer_ring_stats (struct roar_buffer *  buf, struct roar_buffer_stats * stats) {
[4905]500 _ckbuf(0)
[7]501
502 stats->parts        = 0;
503 stats->bytes        = 0;
504 stats->memory_usage = 0;
505
[4905]506 while (buf != NULL ) {
[7]507  stats->parts++;
508  stats->bytes        += buf->user_len;
509  stats->memory_usage += buf->len + sizeof(struct roar_buffer);
510  buf = buf->next;
511 }
512
513 return 0;
514}
515
[3020]516int roar_buffer_ring_read  (struct roar_buffer *  buf, void * data, size_t * len) {
[4615]517 struct roar_buffer_ring * ring;
518 size_t havelen;
519 size_t done;
520 size_t tmp;
521
[4905]522 _ckbuf(len == NULL)
523
[3020]524 if ( buf == NULL || len == NULL )
525  return -1;
526
[4905]527 if ( data == NULL && *len != 0 ) {
528  roar_err_set(ROAR_ERROR_FAULT);
[3020]529  return -1;
[4905]530 }
[3020]531
[4905]532 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
533  roar_err_set(ROAR_ERROR_TYPEMM);
[3020]534  return -1;
[4905]535 }
[3020]536
537 if ( *len == 0 )
538  return 0;
539
540 // we may handle this later:
[4905]541 if ( *len > buf->user_len ) {
542  roar_err_set(ROAR_ERROR_NOTSUP);
[3020]543  return -1;
[4905]544 }
[3020]545
[4615]546 if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) {
547  if ( buf->meta.ring.read_pos >= buf->user_len )
548   buf->meta.ring.read_pos -= buf->user_len;
[3020]549
[4615]550  if ( (*len + buf->meta.ring.read_pos) > buf->user_len ) {
551   // wraped mode:
552   memcpy(data, buf->user_data+buf->meta.ring.read_pos, buf->user_len - buf->meta.ring.read_pos);
553   memcpy(data, buf->user_data, *len + buf->meta.ring.read_pos - buf->user_len);
554 
555   buf->meta.ring.read_pos += *len;
556   buf->meta.ring.read_pos -= buf->user_len;
557   return 0;
558  } else {
559   // unwarped mode:
560   memcpy(data, buf->user_data+buf->meta.ring.read_pos, *len);
561   buf->meta.ring.read_pos += *len;
562   return 0;
563  }
564 } else {
565  ring = &(buf->meta.ring);
566
567  if ( ring->read_pos == ring->write_pos ) {
568   *len = 0;
569   return 0;
570  } else if ( ring->read_pos < ring->write_pos ) {
571   havelen = ring->write_pos - ring->read_pos;
572
573   if ( havelen > *len )
574    havelen = *len;
575
576   memcpy(data, buf->user_data+ring->read_pos, havelen);
577   ring->read_pos += havelen;
[3020]578
[4615]579   *len = havelen;
580   return 0;
581  } else { // write_pos < read_pos
582   done = 0;
583
584   // first pass: use data up to end of buffer
585
586   havelen = buf->user_len - ring->read_pos;
587
588   if ( havelen > *len )
589    havelen = *len;
590
591   memcpy(data, buf->user_data+ring->read_pos, havelen);
592   ring->read_pos += havelen;
593
594   done += havelen;
595
596   if ( ring->read_pos == buf->user_len ) {
597    ring->read_pos = 0;
598   }
599
600   // second pass: use data from strat of buffer to write pointer
601
602   if ( *len > done ) {
603    tmp = *len - done;
604    if ( roar_buffer_ring_read(buf, data+done, &tmp) == 0 ) {
605     done += tmp;
606    }
607   }
608
609   *len = done;
610   return 0;
611  }
[3020]612 }
613
[4905]614 roar_err_set(ROAR_ERROR_UNKNOWN);
[3020]615 return -1;
616}
617
618int roar_buffer_ring_write (struct roar_buffer *  buf, void * data, size_t * len) {
[4624]619 struct roar_buffer_ring * ring;
620 size_t havelen;
621 size_t done;
622 size_t tmp;
623
[4625]624 ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
625
[4905]626 _ckbuf(len == NULL)
[3020]627
[4905]628 if ( data == NULL && *len != 0 ) {
629  roar_err_set(ROAR_ERROR_FAULT);
[3020]630  return -1;
[4905]631 }
[3020]632
[4905]633 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
634  roar_err_set(ROAR_ERROR_TYPEMM);
[3020]635  return -1;
[4905]636 }
[3020]637
638 if ( *len == 0 )
639  return 0;
640
641 // we may handle this later:
[4905]642 if ( *len > buf->user_len ) {
643  roar_err_set(ROAR_ERROR_NOTSUP);
[3020]644  return -1;
[4905]645 }
[3020]646
[4615]647 if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) {
648  if ( buf->meta.ring.write_pos >= buf->user_len )
649   buf->meta.ring.write_pos -= buf->user_len;
[3020]650
[4615]651  if ( (*len + buf->meta.ring.write_pos) > buf->user_len ) {
652   // wraped mode:
653   memcpy(buf->user_data+buf->meta.ring.write_pos, data, buf->user_len - buf->meta.ring.write_pos);
654   memcpy(buf->user_data, data, *len + buf->meta.ring.write_pos - buf->user_len);
[3020]655
[4615]656   buf->meta.ring.write_pos += *len;
657   buf->meta.ring.write_pos -= buf->user_len;
658   return 0;
659  } else {
660   // unwarped mode:
661   memcpy(buf->user_data+buf->meta.ring.write_pos, data, *len);
662   buf->meta.ring.write_pos += *len;
663   return 0;
664  }
[3020]665 } else {
[4624]666  ring = &(buf->meta.ring);
667  done = 0;
668
669  ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p): write_pos=%u, read_pos=%u, user_len=%u", buf, data, len, (unsigned int)ring->write_pos, (unsigned int)ring->read_pos, (unsigned int)buf->user_len);
670
671  if ( ring->write_pos >= ring->read_pos ) {
[4625]672   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
673
[4624]674   havelen = buf->user_len - ring->write_pos;
675
676   if ( ring->read_pos == 0 )
677    havelen--;
678
679   if ( havelen > *len )
680    havelen = *len;
681
682   memcpy(buf->user_data+ring->write_pos, data, havelen);
683
684   done += havelen;
685   ring->write_pos += havelen;
686
687   if ( ring->write_pos == buf->user_len )
688    ring->write_pos = 0;
689
690   if ( *len > done && ring->read_pos != 0 ) {
691    tmp = *len - done;
692    if ( roar_buffer_ring_write(buf, data+done, &tmp) == 0 ) {
693     done += tmp;
694    }
695   }
696
697   *len = done;
[4625]698   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len);
[4624]699   return 0;
700  } else {
[4625]701   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
702
[4624]703   // test for buffer-is-full:
704   if ( (ring->write_pos + 1) == ring->read_pos ) {
705    *len = 0;
[4625]706    ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len);
[4624]707    return 0;
708   }
709
[4625]710   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
711
[4624]712   havelen = ring->read_pos - ring->write_pos - 1;
713
714   if ( havelen > *len )
715    havelen = *len;
716
717   memcpy(buf->user_data+ring->write_pos, data, havelen);
718
[4625]719   ring->write_pos += havelen;
[4624]720   *len = havelen;
[4625]721
722   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len);
[4624]723   return 0;
724  }
[3020]725 }
726
[4905]727 roar_err_set(ROAR_ERROR_UNKNOWN);
[3020]728 return -1;
729}
730
[4625]731int roar_buffer_ring_avail(struct roar_buffer *  buf, size_t * readlen, size_t * writelen) {
732 struct roar_buffer_ring * ring;
733 size_t have;
734
[4905]735 _ckbuf(0)
[4625]736
[4905]737 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
738  roar_err_set(ROAR_ERROR_TYPEMM);
[4625]739  return -1;
[4905]740 }
[4625]741
742 ring = &(buf->meta.ring);
743
744 ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p) = ?", buf, readlen, writelen);
745
746 if ( readlen != NULL ) {
747  have = 0;
748
749  if ( ring->write_pos >= ring->read_pos ) {
750   have  = ring->write_pos - ring->read_pos;
751  } else {
752   have  = buf->user_len - ring->read_pos;
753   have += ring->write_pos;
754   have -= 1;
755  }
756
757  *readlen = have;
758  ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p): readlen=%llu", buf, readlen, writelen, (unsigned long long int)have);
759 }
760
761 if ( writelen != NULL ) {
762  have = 0;
763
764  if ( ring->read_pos > ring->write_pos ) {
765   have  = ring->read_pos - ring->write_pos - 1;
766  } else {
767   have  = buf->user_len - ring->write_pos;
768   have += ring->read_pos;
769   have -= 1;
770  }
771
772  *writelen = have;
773  ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p): readlen=%llu", buf, readlen, writelen, (unsigned long long int)have);
774 }
775
776 ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p) = 0", buf, readlen, writelen);
777
778 return 0;
779}
780
[4629]781int roar_buffer_ring_reset(struct roar_buffer *  buf) {
[4905]782 _ckbuf(0)
[4629]783
[4905]784 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
785  roar_err_set(ROAR_ERROR_TYPEMM);
[4629]786  return -1;
[4905]787 }
[4629]788
789 buf->meta.ring.read_pos = buf->meta.ring.write_pos = 0;
790
791 return 0;
792}
793
[0]794//ll
Note: See TracBrowser for help on using the repository browser.