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. */ 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 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. */ 39 static inline void byte_buffer_destroy(struct byte_buffer *buf) 40 { 41 free(buf); 42 } 43 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 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 65 static inline unsigned int buf_queued_bytes(struct byte_buffer *buf) 66 { 67 return buf->level; 68 } 69 70 static inline unsigned int buf_available_bytes(const struct byte_buffer *buf) 71 { 72 return buf->used_size - buf->level; 73 } 74 75 static inline uint8_t *buf_read_pointer(struct byte_buffer *buf) 76 { 77 return &buf->bytes[buf->read_idx]; 78 } 79 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 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 95 static inline uint8_t *buf_write_pointer(struct byte_buffer *buf) 96 { 97 return &buf->bytes[buf->write_idx]; 98 } 99 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 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 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