ovs-vswitchd: Get rid of call to process_init().
[sliver-openvswitch.git] / lib / byteq.c
1 /* Copyright (c) 2008, 2009, 2012, 2013 Nicira, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <config.h>
17 #include "byteq.h"
18 #include <errno.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include "util.h"
22
23 /* Initializes 'q' as an empty byteq that uses the 'size' bytes of 'buffer' to
24  * store data.  'size' must be a power of 2.
25  *
26  * The caller must ensure that 'buffer' remains available to the byteq as long
27  * as 'q' is in use. */
28 void
29 byteq_init(struct byteq *q, uint8_t *buffer, size_t size)
30 {
31     ovs_assert(is_pow2(size));
32     q->buffer = buffer;
33     q->size = size;
34     q->head = q->tail = 0;
35 }
36
37 /* Returns the number of bytes current queued in 'q'. */
38 int
39 byteq_used(const struct byteq *q)
40 {
41     return q->head - q->tail;
42 }
43
44 /* Returns the number of bytes that can be added to 'q' without overflow. */
45 int
46 byteq_avail(const struct byteq *q)
47 {
48     return q->size - byteq_used(q);
49 }
50
51 /* Returns true if no bytes are queued in 'q',
52  * false if at least one byte is queued.  */
53 bool
54 byteq_is_empty(const struct byteq *q)
55 {
56     return !byteq_used(q);
57 }
58
59 /* Returns true if 'q' has no room to queue additional bytes,
60  * false if 'q' has room for at least one more byte.  */
61 bool
62 byteq_is_full(const struct byteq *q)
63 {
64     return !byteq_avail(q);
65 }
66
67 /* Adds 'c' at the head of 'q', which must not be full. */
68 void
69 byteq_put(struct byteq *q, uint8_t c)
70 {
71     ovs_assert(!byteq_is_full(q));
72     *byteq_head(q) = c;
73     q->head++;
74 }
75
76 /* Adds the 'n' bytes in 'p' at the head of 'q', which must have at least 'n'
77  * bytes of free space. */
78 void
79 byteq_putn(struct byteq *q, const void *p_, size_t n)
80 {
81     const uint8_t *p = p_;
82     ovs_assert(byteq_avail(q) >= n);
83     while (n > 0) {
84         size_t chunk = MIN(n, byteq_headroom(q));
85         memcpy(byteq_head(q), p, chunk);
86         byteq_advance_head(q, chunk);
87         p += chunk;
88         n -= chunk;
89     }
90 }
91
92 /* Appends null-terminated string 's' to the head of 'q', which must have
93  * enough space.  The null terminator is not added to 'q'. */
94 void
95 byteq_put_string(struct byteq *q, const char *s)
96 {
97     byteq_putn(q, s, strlen(s));
98 }
99
100 /* Removes a byte from the tail of 'q' and returns it.  'q' must not be
101  * empty. */
102 uint8_t
103 byteq_get(struct byteq *q)
104 {
105     uint8_t c;
106     ovs_assert(!byteq_is_empty(q));
107     c = *byteq_tail(q);
108     q->tail++;
109     return c;
110 }
111
112 /* Writes as much of 'q' as possible to 'fd'.  Returns 0 if 'q' is fully
113  * drained by the write, otherwise a positive errno value (e.g. EAGAIN if a
114  * socket or tty buffer filled up). */
115 int
116 byteq_write(struct byteq *q, int fd)
117 {
118     while (!byteq_is_empty(q)) {
119         ssize_t n = write(fd, byteq_tail(q), byteq_tailroom(q));
120         if (n > 0) {
121             byteq_advance_tail(q, n);
122         } else {
123             ovs_assert(n < 0);
124             return errno;
125         }
126     }
127     return 0;
128 }
129
130 /* Reads as much possible from 'fd' into 'q'.  Returns 0 if 'q' is completely
131  * filled up by the read, EOF if end-of-file was reached before 'q' was filled,
132  * and otherwise a positive errno value (e.g. EAGAIN if a socket or tty buffer
133  * was drained). */
134 int
135 byteq_read(struct byteq *q, int fd)
136 {
137     while (!byteq_is_full(q)) {
138         ssize_t n = read(fd, byteq_head(q), byteq_headroom(q));
139         if (n > 0) {
140             byteq_advance_head(q, n);
141         } else {
142             return !n ? EOF : errno;
143         }
144     }
145     return 0;
146 }
147
148 /* Returns the number of contiguous bytes of in-use space starting at the tail
149  * of 'q'. */
150 int
151 byteq_tailroom(const struct byteq *q)
152 {
153     int used = byteq_used(q);
154     int tail_to_end = q->size - (q->tail & (q->size - 1));
155     return MIN(used, tail_to_end);
156 }
157
158 /* Returns the first in-use byte of 'q', the point at which data is removed
159  * from 'q'. */
160 const uint8_t *
161 byteq_tail(const struct byteq *q)
162 {
163     return &q->buffer[q->tail & (q->size - 1)];
164 }
165
166 /* Removes 'n' bytes from the tail of 'q', which must have at least 'n' bytes
167  * of tailroom. */
168 void
169 byteq_advance_tail(struct byteq *q, unsigned int n)
170 {
171     ovs_assert(byteq_tailroom(q) >= n);
172     q->tail += n;
173 }
174
175 /* Returns the byte after the last in-use byte of 'q', the point at which new
176  * data will be added to 'q'. */
177 uint8_t *
178 byteq_head(struct byteq *q)
179 {
180     return &q->buffer[q->head & (q->size - 1)];
181 }
182
183 /* Returns the number of contiguous bytes of free space starting at the head
184  * of 'q'. */
185 int
186 byteq_headroom(const struct byteq *q)
187 {
188     int avail = byteq_avail(q);
189     int head_to_end = q->size - (q->head & (q->size - 1));
190     return MIN(avail, head_to_end);
191 }
192
193 /* Adds to 'q' the 'n' bytes after the last currently in-use byte of 'q'.  'q'
194  * must have at least 'n' bytes of headroom. */
195 void
196 byteq_advance_head(struct byteq *q, unsigned int n)
197 {
198     ovs_assert(byteq_headroom(q) >= n);
199     q->head += n;
200 }