/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef BYTE_BUFFER_H_
#define BYTE_BUFFER_H_

#include <stdint.h>
#include <stdlib.h>
#include <sys/param.h>

struct byte_buffer {
	unsigned int write_idx;
	unsigned int read_idx;
	unsigned int level;
	unsigned int max_size;
	unsigned int used_size;
	uint8_t bytes[];
};

/* Create a byte buffer to hold buffer_size_bytes worth of data. */
static inline struct byte_buffer *byte_buffer_create(size_t buffer_size_bytes)
{
	struct byte_buffer *buf;
	buf = (struct byte_buffer *)calloc(1, sizeof(struct byte_buffer) +
						      buffer_size_bytes);
	if (!buf)
		return buf;
	buf->max_size = buffer_size_bytes;
	buf->used_size = buffer_size_bytes;
	return buf;
}

static inline void byte_buffer_set_used_size(struct byte_buffer *buf,
					     size_t used_size)
{
	buf->used_size = MIN(used_size, buf->max_size);
}

/* Destory a byte_buffer created with byte_buffer_create. */
static inline void byte_buffer_destroy(struct byte_buffer **buf)
{
	free(*buf);
	*buf = NULL;
}

static inline unsigned int buf_writable(struct byte_buffer *buf)
{
	if (buf->level >= buf->used_size)
		return 0;
	if (buf->write_idx < buf->read_idx)
		return buf->read_idx - buf->write_idx;

	return buf->used_size - buf->write_idx;
}

static inline unsigned int buf_readable(struct byte_buffer *buf)
{
	if (buf->level == 0)
		return 0;

	if (buf->read_idx < buf->write_idx)
		return buf->write_idx - buf->read_idx;

	return buf->used_size - buf->read_idx;
}

/* Adjust readable size to given value. Use with caution. */
static inline unsigned int buf_adjust_readable(struct byte_buffer *buf,
					       size_t readable)
{
	buf->level = MIN(readable, buf->used_size);
	buf->write_idx = (buf->read_idx + buf->level) % buf->used_size;
	return 0;
}

static inline unsigned int buf_queued(struct byte_buffer *buf)
{
	return buf->level;
}

static inline unsigned int buf_available(const struct byte_buffer *buf)
{
	return buf->used_size - buf->level;
}

static inline uint8_t *buf_read_pointer(struct byte_buffer *buf)
{
	return &buf->bytes[buf->read_idx];
}

static inline uint8_t *buf_read_pointer_size(struct byte_buffer *buf,
					     unsigned int *readable)
{
	*readable = buf_readable(buf);
	return buf_read_pointer(buf);
}

static inline void buf_increment_read(struct byte_buffer *buf, size_t inc)
{
	inc = MIN(inc, buf->level);
	buf->read_idx += inc;
	buf->read_idx %= buf->used_size;
	buf->level -= inc;
}

static inline uint8_t *buf_write_pointer(struct byte_buffer *buf)
{
	return &buf->bytes[buf->write_idx];
}

static inline uint8_t *buf_write_pointer_size(struct byte_buffer *buf,
					      unsigned int *writeable)
{
	*writeable = buf_writable(buf);
	return buf_write_pointer(buf);
}

static inline void buf_increment_write(struct byte_buffer *buf, size_t inc)
{
	buf->write_idx += inc;
	buf->write_idx %= buf->used_size;
	if (buf->level + inc < buf->used_size)
		buf->level += inc;
	else
		buf->level = buf->used_size;
}

static inline void buf_reset(struct byte_buffer *buf)
{
	buf->write_idx = 0;
	buf->read_idx = 0;
	buf->level = 0;
}

#endif /* BYTE_BUFFER_H_ */
