Annotation of src/usr.bin/sndiod/abuf.c, Revision 1.5
1.5 ! jmc 1: /* $OpenBSD: abuf.c,v 1.4 2016/01/08 16:17:31 ratchov Exp $ */
1.1 ratchov 2: /*
3: * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: /*
18: * Simple byte fifo.
19: *
20: * The abuf data is split in two parts: (1) valid data available to the reader
21: * (2) space available to the writer, which is not necessarily unused. It works
22: * as follows: the write starts filling at offset (start + used), once the data
23: * is ready, the writer adds to used the count of bytes available.
24: */
25: #include <stdio.h>
26: #include <stdlib.h>
27: #include <string.h>
28:
29: #include "abuf.h"
30: #include "utils.h"
31:
32: #ifdef DEBUG
33: void
34: abuf_log(struct abuf *buf)
35: {
36: log_putu(buf->start);
37: log_puts("+");
38: log_putu(buf->used);
39: log_puts("/");
40: log_putu(buf->len);
41: }
42: #endif
43:
44: void
45: abuf_init(struct abuf *buf, unsigned int len)
46: {
47: buf->data = xmalloc(len);
48: buf->len = len;
49: buf->used = 0;
50: buf->start = 0;
51: }
52:
53: void
54: abuf_done(struct abuf *buf)
55: {
1.4 ratchov 56: #ifdef DEBUG
1.1 ratchov 57: if (buf->used > 0) {
58: if (log_level >= 3) {
59: log_puts("deleting non-empty buffer, used = ");
60: log_putu(buf->used);
61: log_puts("\n");
62: }
63: }
64: #endif
65: xfree(buf->data);
66: buf->data = (void *)0xdeadbeef;
67: }
68:
69: /*
70: * return the reader pointer and the number of bytes available
71: */
72: unsigned char *
73: abuf_rgetblk(struct abuf *buf, int *rsize)
74: {
1.3 ratchov 75: int count;
1.1 ratchov 76:
77: count = buf->len - buf->start;
78: if (count > buf->used)
79: count = buf->used;
80: *rsize = count;
81: return buf->data + buf->start;
82: }
83:
84: /*
1.5 ! jmc 85: * discard "count" bytes at the start position.
1.1 ratchov 86: */
87: void
88: abuf_rdiscard(struct abuf *buf, int count)
89: {
90: #ifdef DEBUG
91: if (count < 0 || count > buf->used) {
92: log_puts("abuf_rdiscard: bad count = ");
93: log_putu(count);
94: log_puts("\n");
95: panic();
96: }
97: #endif
98: buf->used -= count;
99: buf->start += count;
100: if (buf->start >= buf->len)
101: buf->start -= buf->len;
102: }
103:
104: /*
105: * advance the writer pointer by "count" bytes
106: */
107: void
108: abuf_wcommit(struct abuf *buf, int count)
109: {
110: #ifdef DEBUG
111: if (count < 0 || count > (buf->len - buf->used)) {
112: log_puts("abuf_wcommit: bad count = ");
113: log_putu(count);
114: log_puts("\n");
115: panic();
116: }
117: #endif
118: buf->used += count;
119: }
120:
121: /*
122: * get writer pointer and the number of bytes writable
123: */
124: unsigned char *
125: abuf_wgetblk(struct abuf *buf, int *rsize)
126: {
127: int end, avail, count;
128:
129: end = buf->start + buf->used;
130: if (end >= buf->len)
131: end -= buf->len;
132: avail = buf->len - buf->used;
133: count = buf->len - end;
134: if (count > avail)
135: count = avail;
136: *rsize = count;
137: return buf->data + end;
138: }