2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
10 #include <sys/param.h>
20 size_t current
; /* index of next byte to read */
21 size_t avail
; /* number of bytes in */
22 unsigned char data
[0];
24 #define ASSERT(op) if (!(op)) debugger("ASSERT: " #op " in " __FILE__ ":" __FUNCTION__)
26 #define ASSERT(op) if (!(op)) panic("ASSERT: %s in %s:%s", #op, __FILE__, __FUNCTION__)
29 void rb_init(struct ring_buffer
*rb
, size_t size
)
36 void rb_clear(struct ring_buffer
*rb
)
42 size_t rb_can_write(struct ring_buffer
*rb
)
46 return (rb
->size
- rb
->avail
);
49 size_t rb_can_read(struct ring_buffer
*rb
)
56 size_t rb_write(struct ring_buffer
*rb
, void *data
, size_t len
)
58 size_t index
, towrite
, written
;
61 index
= (rb
->current
+ rb
->avail
) % rb
->size
;
62 towrite
= rb_can_write(rb
);
63 towrite
= MIN(len
, towrite
);
66 len
= rb
->size
- index
;
67 len
= MIN(len
, towrite
);
68 memcpy(((char *)rb
->data
)+index
, data
, len
);
73 len
= MIN(towrite
, rb_can_write(rb
));
75 memcpy(((char *)rb
->data
)+index
, ((char *)data
)+written
, len
);
79 ASSERT(rb
->avail
<= rb
->size
);
83 size_t rb_read(struct ring_buffer
*rb
, void *data
, size_t len
)
85 size_t index
, toread
, got
;
89 toread
= rb_can_read(rb
);
90 toread
= MIN(len
, toread
);
93 len
= rb
->size
- index
;
94 len
= MIN(len
, toread
);
95 memcpy(data
, ((char *)rb
->data
)+index
, len
);
101 len
= MIN(toread
, rb_can_read(rb
));
103 memcpy(((char *)data
)+got
, ((char *)rb
->data
)+index
, len
);
108 ASSERT(rb
->avail
<= rb
->size
);
116 struct ring_buffer rb
;
122 rb_init(&myrb
.rb
, 10);
123 while ((got
= read(0, buffer
, 10))) {
125 len
= rb_write(&myrb
.rb
, buffer
, got
);
126 olen
= rb_read(&myrb
.rb
, obuffer
, 10);
127 write(1, obuffer
, olen
);