Home | History | Annotate | Download | only in common
      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