source: roaraudio/libroar/buffer.c @ 4989:be7f633988f4

Last change on this file since 4989:be7f633988f4 was 4989:be7f633988f4, checked in by phi, 13 years ago

yet another reallocation correction

File size: 17.1 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;
[4973]138  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL);
[4522]139 }
140
141 buf->refc--;
142
143 if ( buf->refc )
144  return 0;
145
[0]146 while ((next = buf->next)) {
[2976]147  if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
148   roar_mm_free(buf->data);
149
150  roar_mm_free(buf);
[0]151  buf = next;
152 }
153
[1215]154 if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
[2976]155  roar_mm_free(buf->data);
[1215]156
[2976]157 roar_mm_free(buf);
[0]158
159 return 0;
160}
161
162int roar_buffer_delete   (struct roar_buffer * buf, struct roar_buffer ** next) {
163 if ( buf == NULL ) {
164  if ( next != NULL )
165   *next = NULL;
[4905]166  roar_err_set(ROAR_ERROR_FAULT);
[0]167  return -1;
168 }
169
170 ROAR_DBG("buffer_delete(buf=%p, next=%p) = ?", buf, next);
171
172 if ( next != NULL )
173  *next = buf->next;
174
[2976]175 if ( roar_buffer_get_flag(buf, ROAR_BUFFER_FLAG_NOFREE) != 1 )
176  roar_mm_free(buf->data);
177
178 roar_mm_free(buf);
[0]179
180 ROAR_DBG("buffer_delete(buf=%p, next=%p) = 0", buf, next);
181 return 0;
182}
183
184int roar_buffer_add      (struct roar_buffer * buf, struct roar_buffer *  next) {
[1953]185 unsigned int deep = 0;
186
[4905]187 _ckbuf(0)
[0]188
189 ROAR_DBG("buffer_add(buf=%p, next=%p) = ?", buf, next);
190
[4905]191 if ( buf->flags & ROAR_BUFFER_FLAG_RING ) {
192  roar_err_set(ROAR_ERROR_INVAL);
[3020]193  return -1;
[4905]194 }
[3020]195
[1953]196 if ( buf == next ) {
197  ROAR_ERR("buffer_add(*): both pointer are of the same destination, This is a error in the application");
[4905]198  roar_err_set(ROAR_ERROR_INVAL);
[1953]199  return -1;
200 }
201
[0]202 while ( buf->next != NULL ) {
[302]203  ROAR_DBG("buffer_add(*): buf=%p, next=%p (len=%i)", buf, buf->next, buf->user_len);
[0]204//  ROAR_DBG("buffer_add(): buf=%p, buf->next=%p", buf, buf->next);
205  buf = buf->next;
[1953]206  deep++;
207
208  if ( buf == next ) {
209   ROAR_ERR("buffer_add(*): Can not add buffer: loop detected at deep %u. This is a error in the application", deep);
[4905]210   // why don't we return here?
[1953]211  }
[0]212 }
213
214 buf->next = next;
215
[1953]216 ROAR_DBG("buffer_add(*): adding buffer at deep %u", deep);
217
[0]218 return 0;
219}
220
[4516]221int roar_buffer_clear_next (struct roar_buffer *  buf) {
[4905]222 _ckbuf(0)
[4516]223
224 buf->next = NULL;
225
226 return 0;
227}
228
[0]229int roar_buffer_get_next (struct roar_buffer *  buf, struct roar_buffer ** next) {
[4905]230 _ckbuf(0)
[0]231
232 *next = buf->next;
233
234 return 0;
235}
236
[3020]237int roar_buffer_ring_new (struct roar_buffer ** buf, size_t len, int free_running) {
238 struct roar_buffer * n;
239
[4905]240 _ckbuf(0)
241
242 if ( len == 0 ) {
243  roar_err_set(ROAR_ERROR_RANGE);
[3020]244  return -1;
[4905]245 }
[3020]246
247 // just to be sure:
248 *buf = NULL;
249
250 if ( roar_buffer_new(&n, len) == -1 )
251  return -1;
252
253 n->flags |= ROAR_BUFFER_FLAG_RING;
254
255 if ( free_running )
256  n->flags |= ROAR_BUFFER_FLAG_FREE_RUNNING;
257
258 n->meta.ring.read_pos  = 0;
259 n->meta.ring.write_pos = 0;
260
261 memset(n->data, 0, n->len);
262
263 *buf = n;
264
265 return 0;
266}
267
[0]268int roar_buffer_get_data (struct roar_buffer *  buf, void   ** data) {
[4905]269 _ckbuf(0)
[0]270
271 *data = buf->user_data;
272
273 return 0;
274}
275
276int roar_buffer_set_offset (struct roar_buffer *  buf, size_t off) {
[4905]277 _ckbuf(0)
278
279 if ( off > buf->user_len ) {
280  roar_err_set(ROAR_ERROR_RANGE);
[0]281  return -1;
[4905]282 }
[0]283
284 buf->user_len  -= off;
285 buf->user_data += off;
286
287 return 0;
288}
289
[904]290int roar_buffer_shift_out (struct roar_buffer ** buf, void * data, size_t * len) {
291 size_t todo, cl;
292 struct roar_buffer * cur;
293 void * cd;
294
[4905]295 _ckbuf(len == NULL || data == NULL);
[904]296
[996]297 if ( *buf == NULL ) {
298  ROAR_DBG("roar_buffer_shift_out(buf=%p, data=%p, len={%lu}) = -1 // Invalid pointer to buffer ring", buf, data, (unsigned long)len);
[4905]299  roar_err_set(ROAR_ERROR_FAULT);
[904]300  return -1;
[996]301 }
[904]302
303 todo = *len;
304 cur  = *buf;
305
306 *len = 0;
307
[2066]308 while (todo && cur != NULL) {
[904]309  ROAR_DBG("roar_buffer_shift_out(*): todo=%u, cur=%p", (unsigned int) todo, cur);
310
311  if ( roar_buffer_get_len(cur, &cl) == -1 )
312   return -1;
313
314  if ( cl > todo ) {
315   if ( roar_buffer_get_data(cur, &cd) == -1 )
316    return -1;
317
318   cl = todo;
319
320   memcpy(data, cd, cl);
321   todo -= cl;
322   data += cl;
323   *len += cl;
324
325   if ( roar_buffer_set_offset(cur, cl) == -1 )
326    return -1;
327  } else {
328   if ( roar_buffer_get_data(cur, &cd) == -1 )
329    return -1;
330
331   memcpy(data, cd, cl);
332   todo -= cl;
333   data += cl;
334   *len += cl;
335
336   if ( roar_buffer_next(&cur) == -1 )
337    return -1;
338  }
339
340/*
341  if ( cur == NULL )
342   break;
343*/
344 }
345
346 *buf = cur;
347
[996]348 return 0;
[904]349}
350
[0]351int roar_buffer_set_meta (struct roar_buffer * buf, void *  meta) {
[4905]352 _ckbuf(0)
[0]353
[2333]354 buf->meta.vp = meta;
[0]355
356 return 0;
357}
358
359int roar_buffer_get_meta (struct roar_buffer * buf, void ** meta) {
[4905]360 _ckbuf(meta == NULL)
[2333]361
362 *meta = buf->meta.vp;
363
364 return 0;
365}
366
367int roar_buffer_set_meta_i32(struct roar_buffer *  buf, int32_t    meta) {
[4905]368 _ckbuf(0)
[0]369
[2333]370 buf->meta.i32 = meta;
371
372 return 0;
373}
374
375int roar_buffer_get_meta_i32(struct roar_buffer *  buf, int32_t *  meta) {
[4905]376 _ckbuf(meta == NULL)
[2333]377
378 *meta = buf->meta.i32;
[0]379
380 return 0;
381}
382
[4901]383int roar_buffer_set_type    (struct roar_buffer *  buf, int        type) {
[4905]384 _ckbuf(0)
[4901]385
[4903]386 switch (type) {
387  case ROAR_VIO_DFT_RAW:
388  case ROAR_VIO_DFT_PACKET:
389  case ROAR_VIO_DFT_UNFRAMED:
[4988]390  case ROAR_VIO_DFT_OGG_PACKET:
391  case ROAR_VIO_DFT_OGG_PAGE:
[4903]392   break;
393  default:
[4905]394    roar_err_set(ROAR_ERROR_NOTSUP);
[4903]395    return -1;
396 }
397
[4901]398 buf->type = type;
399
400 return 0;
401}
402
403int roar_buffer_get_type    (struct roar_buffer *  buf, int     *  type) {
[4905]404 _ckbuf(type == NULL)
[4901]405
406 *type = buf->type;
407
408 return 0;
409}
410
[0]411int roar_buffer_set_len  (struct roar_buffer *  buf, size_t    len) {
[2334]412 size_t   totlen;
413 void   * newbuf;
414
[4905]415 _ckbuf(0)
[0]416
[3032]417 // handle specal case where user length is zero:
418 if ( len && !buf->user_len ) {
419  buf->user_data = buf->data;
420  buf->user_len  = buf->len;
421 }
422
[2334]423 if ( len > buf->user_len ) {
[3021]424  // we can only enlage a buffer if it's one of our own memory segments
[4905]425  if ( buf->flags & ROAR_BUFFER_FLAG_NOFREE )  {
426   roar_err_set(ROAR_ERROR_NOTSUP);
[3021]427   return -1;
[4905]428  }
[3021]429
[4989]430  totlen = (buf->len - buf->user_len) + len;
[3021]431  newbuf = roar_mm_realloc(buf->data, totlen);
[2334]432  if ( newbuf == NULL )
433   return -1;
434
[4988]435  buf->user_data = newbuf + (buf->user_data - buf->data);
[4989]436  buf->user_len = len;
[2334]437  buf->data = newbuf;
[4989]438  buf->len  = totlen;
[2334]439 } else {
440  buf->user_len = len;
441 }
[0]442
443 return 0;
444}
445
446int roar_buffer_get_len  (struct roar_buffer *  buf, size_t *  len) {
[4905]447 _ckbuf(0)
[0]448
449 *len = buf->user_len;
450
451 return 0;
452}
453
[1215]454int roar_buffer_set_flag (struct roar_buffer *  buf, int flag, int reset) {
[4905]455 _ckbuf(0)
[1215]456
457 buf->flags |= flag;
458
459 if ( reset )
460  buf->flags -= flag;
461
462 return 0;
463}
464
465int roar_buffer_get_flag (struct roar_buffer *  buf, int flag) {
[4905]466 _ckbuf(0)
[1215]467
468 return buf->flags & flag;
469}
470
[46]471int roar_buffer_duplicate (struct roar_buffer *  buf, struct roar_buffer ** copy) {
472 struct roar_buffer *  cur = buf;
473 struct roar_buffer *  new;
[48]474 void * od, * nd;
[4905]475 int err;
476
477 _ckbuf(copy == NULL)
[46]478
479 *copy = NULL;
480
[4905]481 while (cur != NULL) {
[46]482  if ( roar_buffer_new(&new, cur->user_len) == -1 ) {
[4905]483   err = roar_error;
[46]484   roar_buffer_free(*copy);
[4905]485   roar_err_set(err);
[46]486   return -1;
487  }
488
489  if ( *copy == NULL )
490   *copy = new;
491
[48]492  roar_buffer_get_data(cur, &od);
493  roar_buffer_get_data(new, &nd);
494  memcpy(nd, od, cur->user_len);
495
[46]496  roar_buffer_add(*copy, new);
497
498  cur = cur->next;
499 }
[4905]500
[46]501 return 0;
502}
503
[7]504int roar_buffer_ring_stats (struct roar_buffer *  buf, struct roar_buffer_stats * stats) {
[4905]505 _ckbuf(0)
[7]506
507 stats->parts        = 0;
508 stats->bytes        = 0;
509 stats->memory_usage = 0;
510
[4905]511 while (buf != NULL ) {
[7]512  stats->parts++;
513  stats->bytes        += buf->user_len;
514  stats->memory_usage += buf->len + sizeof(struct roar_buffer);
515  buf = buf->next;
516 }
517
518 return 0;
519}
520
[3020]521int roar_buffer_ring_read  (struct roar_buffer *  buf, void * data, size_t * len) {
[4615]522 struct roar_buffer_ring * ring;
523 size_t havelen;
524 size_t done;
525 size_t tmp;
526
[4905]527 _ckbuf(len == NULL)
528
[3020]529 if ( buf == NULL || len == NULL )
530  return -1;
531
[4905]532 if ( data == NULL && *len != 0 ) {
533  roar_err_set(ROAR_ERROR_FAULT);
[3020]534  return -1;
[4905]535 }
[3020]536
[4905]537 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
538  roar_err_set(ROAR_ERROR_TYPEMM);
[3020]539  return -1;
[4905]540 }
[3020]541
542 if ( *len == 0 )
543  return 0;
544
545 // we may handle this later:
[4905]546 if ( *len > buf->user_len ) {
547  roar_err_set(ROAR_ERROR_NOTSUP);
[3020]548  return -1;
[4905]549 }
[3020]550
[4615]551 if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) {
552  if ( buf->meta.ring.read_pos >= buf->user_len )
553   buf->meta.ring.read_pos -= buf->user_len;
[3020]554
[4615]555  if ( (*len + buf->meta.ring.read_pos) > buf->user_len ) {
556   // wraped mode:
557   memcpy(data, buf->user_data+buf->meta.ring.read_pos, buf->user_len - buf->meta.ring.read_pos);
558   memcpy(data, buf->user_data, *len + buf->meta.ring.read_pos - buf->user_len);
559 
560   buf->meta.ring.read_pos += *len;
561   buf->meta.ring.read_pos -= buf->user_len;
562   return 0;
563  } else {
564   // unwarped mode:
565   memcpy(data, buf->user_data+buf->meta.ring.read_pos, *len);
566   buf->meta.ring.read_pos += *len;
567   return 0;
568  }
569 } else {
570  ring = &(buf->meta.ring);
571
572  if ( ring->read_pos == ring->write_pos ) {
573   *len = 0;
574   return 0;
575  } else if ( ring->read_pos < ring->write_pos ) {
576   havelen = ring->write_pos - ring->read_pos;
577
578   if ( havelen > *len )
579    havelen = *len;
580
581   memcpy(data, buf->user_data+ring->read_pos, havelen);
582   ring->read_pos += havelen;
[3020]583
[4615]584   *len = havelen;
585   return 0;
586  } else { // write_pos < read_pos
587   done = 0;
588
589   // first pass: use data up to end of buffer
590
591   havelen = buf->user_len - ring->read_pos;
592
593   if ( havelen > *len )
594    havelen = *len;
595
596   memcpy(data, buf->user_data+ring->read_pos, havelen);
597   ring->read_pos += havelen;
598
599   done += havelen;
600
601   if ( ring->read_pos == buf->user_len ) {
602    ring->read_pos = 0;
603   }
604
605   // second pass: use data from strat of buffer to write pointer
606
607   if ( *len > done ) {
608    tmp = *len - done;
609    if ( roar_buffer_ring_read(buf, data+done, &tmp) == 0 ) {
610     done += tmp;
611    }
612   }
613
614   *len = done;
615   return 0;
616  }
[3020]617 }
618
[4905]619 roar_err_set(ROAR_ERROR_UNKNOWN);
[3020]620 return -1;
621}
622
623int roar_buffer_ring_write (struct roar_buffer *  buf, void * data, size_t * len) {
[4624]624 struct roar_buffer_ring * ring;
625 size_t havelen;
626 size_t done;
627 size_t tmp;
628
[4625]629 ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
630
[4905]631 _ckbuf(len == NULL)
[3020]632
[4905]633 if ( data == NULL && *len != 0 ) {
634  roar_err_set(ROAR_ERROR_FAULT);
[3020]635  return -1;
[4905]636 }
[3020]637
[4905]638 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
639  roar_err_set(ROAR_ERROR_TYPEMM);
[3020]640  return -1;
[4905]641 }
[3020]642
643 if ( *len == 0 )
644  return 0;
645
646 // we may handle this later:
[4905]647 if ( *len > buf->user_len ) {
648  roar_err_set(ROAR_ERROR_NOTSUP);
[3020]649  return -1;
[4905]650 }
[3020]651
[4615]652 if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) {
653  if ( buf->meta.ring.write_pos >= buf->user_len )
654   buf->meta.ring.write_pos -= buf->user_len;
[3020]655
[4615]656  if ( (*len + buf->meta.ring.write_pos) > buf->user_len ) {
657   // wraped mode:
658   memcpy(buf->user_data+buf->meta.ring.write_pos, data, buf->user_len - buf->meta.ring.write_pos);
659   memcpy(buf->user_data, data, *len + buf->meta.ring.write_pos - buf->user_len);
[3020]660
[4615]661   buf->meta.ring.write_pos += *len;
662   buf->meta.ring.write_pos -= buf->user_len;
663   return 0;
664  } else {
665   // unwarped mode:
666   memcpy(buf->user_data+buf->meta.ring.write_pos, data, *len);
667   buf->meta.ring.write_pos += *len;
668   return 0;
669  }
[3020]670 } else {
[4624]671  ring = &(buf->meta.ring);
672  done = 0;
673
674  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);
675
676  if ( ring->write_pos >= ring->read_pos ) {
[4625]677   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
678
[4624]679   havelen = buf->user_len - ring->write_pos;
680
681   if ( ring->read_pos == 0 )
682    havelen--;
683
684   if ( havelen > *len )
685    havelen = *len;
686
687   memcpy(buf->user_data+ring->write_pos, data, havelen);
688
689   done += havelen;
690   ring->write_pos += havelen;
691
692   if ( ring->write_pos == buf->user_len )
693    ring->write_pos = 0;
694
695   if ( *len > done && ring->read_pos != 0 ) {
696    tmp = *len - done;
697    if ( roar_buffer_ring_write(buf, data+done, &tmp) == 0 ) {
698     done += tmp;
699    }
700   }
701
702   *len = done;
[4625]703   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len);
[4624]704   return 0;
705  } else {
[4625]706   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
707
[4624]708   // test for buffer-is-full:
709   if ( (ring->write_pos + 1) == ring->read_pos ) {
710    *len = 0;
[4625]711    ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len);
[4624]712    return 0;
713   }
714
[4625]715   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len);
716
[4624]717   havelen = ring->read_pos - ring->write_pos - 1;
718
719   if ( havelen > *len )
720    havelen = *len;
721
722   memcpy(buf->user_data+ring->write_pos, data, havelen);
723
[4625]724   ring->write_pos += havelen;
[4624]725   *len = havelen;
[4625]726
727   ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len);
[4624]728   return 0;
729  }
[3020]730 }
731
[4905]732 roar_err_set(ROAR_ERROR_UNKNOWN);
[3020]733 return -1;
734}
735
[4625]736int roar_buffer_ring_avail(struct roar_buffer *  buf, size_t * readlen, size_t * writelen) {
737 struct roar_buffer_ring * ring;
738 size_t have;
739
[4905]740 _ckbuf(0)
[4625]741
[4905]742 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
743  roar_err_set(ROAR_ERROR_TYPEMM);
[4625]744  return -1;
[4905]745 }
[4625]746
747 ring = &(buf->meta.ring);
748
749 ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p) = ?", buf, readlen, writelen);
750
751 if ( readlen != NULL ) {
752  have = 0;
753
754  if ( ring->write_pos >= ring->read_pos ) {
755   have  = ring->write_pos - ring->read_pos;
756  } else {
757   have  = buf->user_len - ring->read_pos;
758   have += ring->write_pos;
759   have -= 1;
760  }
761
762  *readlen = have;
763  ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p): readlen=%llu", buf, readlen, writelen, (unsigned long long int)have);
764 }
765
766 if ( writelen != NULL ) {
767  have = 0;
768
769  if ( ring->read_pos > ring->write_pos ) {
770   have  = ring->read_pos - ring->write_pos - 1;
771  } else {
772   have  = buf->user_len - ring->write_pos;
773   have += ring->read_pos;
774   have -= 1;
775  }
776
777  *writelen = have;
778  ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p): readlen=%llu", buf, readlen, writelen, (unsigned long long int)have);
779 }
780
781 ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p) = 0", buf, readlen, writelen);
782
783 return 0;
784}
785
[4629]786int roar_buffer_ring_reset(struct roar_buffer *  buf) {
[4905]787 _ckbuf(0)
[4629]788
[4905]789 if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) {
790  roar_err_set(ROAR_ERROR_TYPEMM);
[4629]791  return -1;
[4905]792 }
[4629]793
794 buf->meta.ring.read_pos = buf->meta.ring.write_pos = 0;
795
796 return 0;
797}
798
[0]799//ll
Note: See TracBrowser for help on using the repository browser.