1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #ifndef BYTE_BUFFER_H_
7 #define BYTE_BUFFER_H_
8
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <sys/param.h>
12
13 struct byte_buffer {
14 unsigned int write_idx;
15 unsigned int read_idx;
16 unsigned int level;
17 unsigned int max_size;
18 unsigned int used_size;
19 uint8_t bytes[];
20 };
21
22 /* Create a byte buffer to hold buffer_size_bytes worth of data. */
byte_buffer_create(size_t buffer_size_bytes)23 static inline struct byte_buffer *byte_buffer_create(size_t buffer_size_bytes)
24 {
25 struct byte_buffer *buf;
26 buf = (struct byte_buffer *)
27 calloc(1, sizeof(struct byte_buffer) + buffer_size_bytes);
28 if (!buf)
29 return buf;
30 buf->max_size = buffer_size_bytes;
31 buf->used_size = buffer_size_bytes;
32 return buf;
33 }
34
byte_buffer_set_used_size(struct byte_buffer * buf,size_t used_size)35 static inline void byte_buffer_set_used_size(struct byte_buffer *buf,
36 size_t used_size)
37 {
38 buf->used_size = MIN(used_size, buf->max_size);
39 }
40
41 /* Destory a byte_buffer created with byte_buffer_create. */
byte_buffer_destroy(struct byte_buffer ** buf)42 static inline void byte_buffer_destroy(struct byte_buffer **buf)
43 {
44 free(*buf);
45 *buf = NULL;
46 }
47
buf_writable(struct byte_buffer * buf)48 static inline unsigned int buf_writable(struct byte_buffer *buf)
49 {
50 if (buf->level >= buf->used_size)
51 return 0;
52 if (buf->write_idx < buf->read_idx)
53 return buf->read_idx - buf->write_idx;
54
55 return buf->used_size - buf->write_idx;
56 }
57
buf_readable(struct byte_buffer * buf)58 static inline unsigned int buf_readable(struct byte_buffer *buf)
59 {
60 if (buf->level == 0)
61 return 0;
62
63 if (buf->read_idx < buf->write_idx)
64 return buf->write_idx - buf->read_idx;
65
66 return buf->used_size - buf->read_idx;
67 }
68
buf_queued(struct byte_buffer * buf)69 static inline unsigned int buf_queued(struct byte_buffer *buf)
70 {
71 return buf->level;
72 }
73
buf_available(const struct byte_buffer * buf)74 static inline unsigned int buf_available(const struct byte_buffer *buf)
75 {
76 return buf->used_size - buf->level;
77 }
78
buf_read_pointer(struct byte_buffer * buf)79 static inline uint8_t *buf_read_pointer(struct byte_buffer *buf)
80 {
81 return &buf->bytes[buf->read_idx];
82 }
83
buf_read_pointer_size(struct byte_buffer * buf,unsigned int * readable)84 static inline uint8_t *buf_read_pointer_size(struct byte_buffer *buf,
85 unsigned int *readable)
86 {
87 *readable = buf_readable(buf);
88 return buf_read_pointer(buf);
89 }
90
buf_increment_read(struct byte_buffer * buf,size_t inc)91 static inline void buf_increment_read(struct byte_buffer *buf, size_t inc)
92 {
93 inc = MIN(inc, buf->level);
94 buf->read_idx += inc;
95 buf->read_idx %= buf->used_size;
96 buf->level -= inc;
97 }
98
buf_write_pointer(struct byte_buffer * buf)99 static inline uint8_t *buf_write_pointer(struct byte_buffer *buf)
100 {
101 return &buf->bytes[buf->write_idx];
102 }
103
buf_write_pointer_size(struct byte_buffer * buf,unsigned int * writeable)104 static inline uint8_t *buf_write_pointer_size(struct byte_buffer *buf,
105 unsigned int *writeable)
106 {
107 *writeable = buf_writable(buf);
108 return buf_write_pointer(buf);
109 }
110
buf_increment_write(struct byte_buffer * buf,size_t inc)111 static inline void buf_increment_write(struct byte_buffer *buf, size_t inc)
112 {
113 buf->write_idx += inc;
114 buf->write_idx %= buf->used_size;
115 if (buf->level + inc < buf->used_size)
116 buf->level += inc;
117 else
118 buf->level = buf->used_size;
119 }
120
buf_reset(struct byte_buffer * buf)121 static inline void buf_reset(struct byte_buffer *buf)
122 {
123 buf->write_idx = 0;
124 buf->read_idx = 0;
125 buf->level = 0;
126 }
127
128 #endif /* BYTE_BUFFER_H_ */
129