• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <stdint.h>
7 #include <stdlib.h>
8 #include <sys/param.h>
9 
10 struct byte_buffer {
11 	unsigned int write_idx;
12 	unsigned int read_idx;
13 	unsigned int level;
14 	unsigned int max_size;
15 	unsigned int used_size;
16 	uint8_t bytes[];
17 };
18 
19 /* Create a byte buffer to hold buffer_size_bytes worth of data. */
byte_buffer_create(size_t buffer_size_bytes)20 static inline struct byte_buffer *byte_buffer_create(size_t buffer_size_bytes)
21 {
22 	struct byte_buffer *buf;
23 	buf = (struct byte_buffer *)
24 		calloc(1, sizeof(struct byte_buffer) + buffer_size_bytes);
25 	if (!buf)
26 		return buf;
27 	buf->max_size = buffer_size_bytes;
28 	buf->used_size = buffer_size_bytes;
29 	return buf;
30 }
31 
byte_buffer_set_used_size(struct byte_buffer * buf,size_t used_size)32 static inline void byte_buffer_set_used_size(struct byte_buffer *buf,
33 					     size_t used_size)
34 {
35 	buf->used_size = MIN(used_size, buf->max_size);
36 }
37 
38 /* Destory a byte_buffer created with byte_buffer_create. */
byte_buffer_destroy(struct byte_buffer * buf)39 static inline void byte_buffer_destroy(struct byte_buffer *buf)
40 {
41 	free(buf);
42 }
43 
buf_writable_bytes(struct byte_buffer * buf)44 static inline unsigned int buf_writable_bytes(struct byte_buffer *buf)
45 {
46 	if (buf->level >= buf->used_size)
47 		return 0;
48 	if (buf->write_idx < buf->read_idx)
49 		return buf->read_idx - buf->write_idx;
50 
51 	return buf->used_size - buf->write_idx;
52 }
53 
buf_readable_bytes(struct byte_buffer * buf)54 static inline unsigned int buf_readable_bytes(struct byte_buffer *buf)
55 {
56 	if (buf->level == 0)
57 		return 0;
58 
59 	if (buf->read_idx < buf->write_idx)
60 		return buf->write_idx - buf->read_idx;
61 
62 	return buf->used_size - buf->read_idx;
63 }
64 
buf_queued_bytes(struct byte_buffer * buf)65 static inline unsigned int buf_queued_bytes(struct byte_buffer *buf)
66 {
67 	return buf->level;
68 }
69 
buf_available_bytes(const struct byte_buffer * buf)70 static inline unsigned int buf_available_bytes(const struct byte_buffer *buf)
71 {
72 	return buf->used_size - buf->level;
73 }
74 
buf_read_pointer(struct byte_buffer * buf)75 static inline uint8_t *buf_read_pointer(struct byte_buffer *buf)
76 {
77 	return &buf->bytes[buf->read_idx];
78 }
79 
buf_read_pointer_size(struct byte_buffer * buf,unsigned int * readable)80 static inline uint8_t *buf_read_pointer_size(struct byte_buffer *buf,
81 					     unsigned int *readable)
82 {
83 	*readable = buf_readable_bytes(buf);
84 	return buf_read_pointer(buf);
85 }
86 
buf_increment_read(struct byte_buffer * buf,size_t inc)87 static inline void buf_increment_read(struct byte_buffer *buf, size_t inc)
88 {
89 	inc = MIN(inc, buf->level);
90 	buf->read_idx += inc;
91 	buf->read_idx %= buf->used_size;
92 	buf->level -= inc;
93 }
94 
buf_write_pointer(struct byte_buffer * buf)95 static inline uint8_t *buf_write_pointer(struct byte_buffer *buf)
96 {
97 	return &buf->bytes[buf->write_idx];
98 }
99 
buf_write_pointer_size(struct byte_buffer * buf,unsigned int * writeable)100 static inline uint8_t *buf_write_pointer_size(struct byte_buffer *buf,
101 					      unsigned int *writeable)
102 {
103 	*writeable = buf_writable_bytes(buf);
104 	return buf_write_pointer(buf);
105 }
106 
buf_increment_write(struct byte_buffer * buf,size_t inc)107 static inline void buf_increment_write(struct byte_buffer *buf, size_t inc)
108 {
109 	buf->write_idx += inc;
110 	buf->write_idx %= buf->used_size;
111 	if (buf->level + inc < buf->used_size)
112 		buf->level += inc;
113 	else
114 		buf->level = buf->used_size;
115 }
116 
buf_reset(struct byte_buffer * buf)117 static inline void buf_reset(struct byte_buffer *buf)
118 {
119 	buf->write_idx = 0;
120 	buf->read_idx = 0;
121 	buf->level = 0;
122 }
123