1 /*
2 * MOC - music on console
3 * Copyright (C) 2005 Damian Pietras <daper@daper.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 */
11
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #include <assert.h>
17 #include <string.h>
18
19 #include "common.h"
20 #include "fifo_buf.h"
21
22 /* Initialize the fifo_buf structure with empty buffer of the given size. */
fifo_buf_init(struct fifo_buf * b,const size_t size)23 void fifo_buf_init (struct fifo_buf *b, const size_t size)
24 {
25 assert (b != NULL);
26 assert (size > 0);
27
28 b->buf = (char *)xmalloc (size);
29 b->size = size;
30 b->pos = 0;
31 b->fill = 0;
32 }
33
34 /* Destroy the buffer object. */
fifo_buf_destroy(struct fifo_buf * b)35 void fifo_buf_destroy (struct fifo_buf *b)
36 {
37 assert (b != NULL);
38
39 free (b->buf);
40 b->buf = NULL;
41 }
42
43 /* Put data into the buffer. Returns number of bytes actually put. */
fifo_buf_put(struct fifo_buf * b,const char * data,size_t size)44 size_t fifo_buf_put (struct fifo_buf *b, const char *data, size_t size)
45 {
46 size_t written = 0;
47
48 assert (b != NULL);
49 assert (b->buf != NULL);
50
51 while (b->fill < b->size && written < size) {
52 size_t write_from;
53 size_t to_write;
54
55 if (b->pos + b->fill < b->size) {
56 write_from = b->pos + b->fill;
57 to_write = b->size - (b->pos + b->fill);
58 }
59 else {
60 write_from = b->fill - b->size + b->pos;
61 to_write = b->size - b->fill;
62 }
63
64 if (to_write > size - written)
65 to_write = size - written;
66
67 memcpy (b->buf + write_from, data + written, to_write);
68 b->fill += to_write;
69 written += to_write;
70 }
71
72 return written;
73 }
74
75 /* Copy data from the beginning of the buffer to the user buffer. Returns the
76 * number of bytes copied. */
fifo_buf_peek(struct fifo_buf * b,char * user_buf,size_t user_buf_size)77 size_t fifo_buf_peek (struct fifo_buf *b, char *user_buf,
78 size_t user_buf_size)
79 {
80 size_t user_buf_pos = 0, written = 0;
81 ssize_t left, pos;
82
83 assert (b != NULL);
84 assert (b->buf != NULL);
85
86 left = b->fill;
87 pos = b->pos;
88
89 while (left && written < user_buf_size) {
90 size_t to_copy = pos + left <= b->size
91 ? left : b->size - pos;
92
93 if (to_copy > user_buf_size - written)
94 to_copy = user_buf_size - written;
95
96 memcpy (user_buf + user_buf_pos, b->buf + pos, to_copy);
97 user_buf_pos += to_copy;
98 written += to_copy;
99
100 left -= to_copy;
101 pos += to_copy;
102 if (pos == b->size)
103 pos = 0;
104 }
105
106 return written;
107 }
108
fifo_buf_get(struct fifo_buf * b,char * user_buf,size_t user_buf_size)109 size_t fifo_buf_get (struct fifo_buf *b, char *user_buf,
110 size_t user_buf_size)
111 {
112 size_t user_buf_pos = 0, written = 0;
113
114 assert (b != NULL);
115 assert (b->buf != NULL);
116
117 while (b->fill && written < user_buf_size) {
118 size_t to_copy = b->pos + b->fill <= b->size
119 ? b->fill : b->size - b->pos;
120
121 if (to_copy > user_buf_size - written)
122 to_copy = user_buf_size - written;
123
124 memcpy (user_buf + user_buf_pos, b->buf + b->pos, to_copy);
125 user_buf_pos += to_copy;
126 written += to_copy;
127
128 b->fill -= to_copy;
129 b->pos += to_copy;
130 if (b->pos == b->size)
131 b->pos = 0;
132 }
133
134 return written;
135 }
136
137 /* Get the amount of free space in the buffer. */
fifo_buf_get_space(const struct fifo_buf * b)138 size_t fifo_buf_get_space (const struct fifo_buf *b)
139 {
140 assert (b != NULL);
141 assert (b->buf != NULL);
142
143 return b->size - b->fill;
144
145 }
146
fifo_buf_get_fill(const struct fifo_buf * b)147 size_t fifo_buf_get_fill (const struct fifo_buf *b)
148 {
149 assert (b != NULL);
150 return b->fill;
151 }
152
fifo_buf_get_size(const struct fifo_buf * b)153 size_t fifo_buf_get_size (const struct fifo_buf *b)
154 {
155 assert (b != NULL);
156 return b->size;
157 }
158
fifo_buf_clear(struct fifo_buf * b)159 void fifo_buf_clear (struct fifo_buf *b)
160 {
161 assert (b != NULL);
162 b->fill = 0;
163 }
164