/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Lightweight buffered reading library.
 *
 * Copyright 2019 Google LLC.
 */
#ifndef __API_IO__
#define __API_IO__

#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/types.h>

struct io {
	/* File descriptor being read/ */
	int fd;
	/* Size of the read buffer. */
	unsigned int buf_len;
	/* Pointer to storage for buffering read. */
	char *buf;
	/* End of the storage. */
	char *end;
	/* Currently accessed data pointer. */
	char *data;
	/* Read timeout, 0 implies no timeout. */
	int timeout_ms;
	/* Set true on when the end of file on read error. */
	bool eof;
};

static inline void io__init(struct io *io, int fd,
			    char *buf, unsigned int buf_len)
{
	io->fd = fd;
	io->buf_len = buf_len;
	io->buf = buf;
	io->end = buf;
	io->data = buf;
	io->timeout_ms = 0;
	io->eof = false;
}

/* Read from fd filling the buffer. Called when io->data == io->end. */
static inline int io__fill_buffer(struct io *io)
{
	ssize_t n;

	if (io->eof)
		return -1;

	if (io->timeout_ms != 0) {
		struct pollfd pfds[] = {
			{
				.fd = io->fd,
				.events = POLLIN,
			},
		};

		n = poll(pfds, 1, io->timeout_ms);
		if (n == 0)
			errno = ETIMEDOUT;
		if (n > 0 && !(pfds[0].revents & POLLIN)) {
			errno = EIO;
			n = -1;
		}
		if (n <= 0) {
			io->eof = true;
			return -1;
		}
	}
	n = read(io->fd, io->buf, io->buf_len);

	if (n <= 0) {
		io->eof = true;
		return -1;
	}
	io->data = &io->buf[0];
	io->end = &io->buf[n];
	return 0;
}

/* Reads one character from the "io" file with similar semantics to fgetc. */
static inline int io__get_char(struct io *io)
{
	if (io->data == io->end) {
		int ret = io__fill_buffer(io);

		if (ret)
			return ret;
	}
	return *io->data++;
}

/* Read a hexadecimal value with no 0x prefix into the out argument hex. If the
 * first character isn't hexadecimal returns -2, io->eof returns -1, otherwise
 * returns the character after the hexadecimal value which may be -1 for eof.
 * If the read value is larger than a u64 the high-order bits will be dropped.
 */
static inline int io__get_hex(struct io *io, __u64 *hex)
{
	bool first_read = true;

	*hex = 0;
	while (true) {
		int ch = io__get_char(io);

		if (ch < 0)
			return ch;
		if (ch >= '0' && ch <= '9')
			*hex = (*hex << 4) | (ch - '0');
		else if (ch >= 'a' && ch <= 'f')
			*hex = (*hex << 4) | (ch - 'a' + 10);
		else if (ch >= 'A' && ch <= 'F')
			*hex = (*hex << 4) | (ch - 'A' + 10);
		else if (first_read)
			return -2;
		else
			return ch;
		first_read = false;
	}
}

/* Read a positive decimal value with out argument dec. If the first character
 * isn't a decimal returns -2, io->eof returns -1, otherwise returns the
 * character after the decimal value which may be -1 for eof. If the read value
 * is larger than a u64 the high-order bits will be dropped.
 */
static inline int io__get_dec(struct io *io, __u64 *dec)
{
	bool first_read = true;

	*dec = 0;
	while (true) {
		int ch = io__get_char(io);

		if (ch < 0)
			return ch;
		if (ch >= '0' && ch <= '9')
			*dec = (*dec * 10) + ch - '0';
		else if (first_read)
			return -2;
		else
			return ch;
		first_read = false;
	}
}

/* Read up to and including the first delim. */
static inline ssize_t io__getdelim(struct io *io, char **line_out, size_t *line_len_out, int delim)
{
	char buf[128];
	int buf_pos = 0;
	char *line = NULL, *temp;
	size_t line_len = 0;
	int ch = 0;

	/* TODO: reuse previously allocated memory. */
	free(*line_out);
	while (ch != delim) {
		ch = io__get_char(io);

		if (ch < 0)
			break;

		if (buf_pos == sizeof(buf)) {
			temp = realloc(line, line_len + sizeof(buf));
			if (!temp)
				goto err_out;
			line = temp;
			memcpy(&line[line_len], buf, sizeof(buf));
			line_len += sizeof(buf);
			buf_pos = 0;
		}
		buf[buf_pos++] = (char)ch;
	}
	temp = realloc(line, line_len + buf_pos + 1);
	if (!temp)
		goto err_out;
	line = temp;
	memcpy(&line[line_len], buf, buf_pos);
	line[line_len + buf_pos] = '\0';
	line_len += buf_pos;
	*line_out = line;
	*line_len_out = line_len;
	return line_len;
err_out:
	free(line);
	*line_out = NULL;
	return -ENOMEM;
}

static inline ssize_t io__getline(struct io *io, char **line_out, size_t *line_len_out)
{
	return io__getdelim(io, line_out, line_len_out, /*delim=*/'\n');
}

#endif /* __API_IO__ */
