diff options
Diffstat (limited to 'read.c')
| -rw-r--r-- | read.c | 78 | 
1 files changed, 78 insertions, 0 deletions
| @@ -0,0 +1,78 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int +feedbuffer(int fd, struct buffer *buffer, const char *fname) +{ +	ssize_t r; +	if (buffer->offset == buffer->size) +		buffer->buf = erealloc(buffer->buf, buffer->size += 8096); +again: +	r = read(fd, &buffer->buf[buffer->offset], buffer->size - buffer->offset); +	if (r <= 0) { +		if (!r) +			return 1; +		if (errno == EINTR) +			goto again; +		weprintf("%s:", fname); +		return -1; +	} +	buffer->offset += (size_t)r; +	return 0; +} + + +void +shiftbuffer(struct algorithm *algorithms, size_t nalgorithms, struct buffer *buffer) +{ +	size_t i, consumed = SIZE_MAX; +	for (i = 0; i < nalgorithms; i++) +		consumed = MIN(consumed, algorithms[i].offset); +	if (!consumed) +		return; +	for (i = 0; i < nalgorithms; i++) +		algorithms[i].offset -= consumed; +	memmove(&buffer->buf[0], &buffer->buf[consumed], buffer->ready -= consumed); +	memmove(&buffer->buf[buffer->ready], &buffer->buf[buffer->procoff], buffer->offset - buffer->procoff); +	buffer->offset -= buffer->procoff - buffer->ready; +	buffer->procoff = buffer->ready; +} + + +int +unhex(struct buffer *buffer) +{ +	size_t i = buffer->procoff; +	char a, b; + +	for (;;) { +		while (i < buffer->offset && isspace(buffer->buf[i])) +			i++; +		if (i == buffer->offset) +			break; + +		buffer->procoff = i; +		if (!isxdigit(buffer->buf[i])) +			return -1; +		a = buffer->buf[i++]; + +		while (i < buffer->offset && isspace(buffer->buf[i])) +			i++; +		if (i == buffer->offset) +			break; + +		if (!isxdigit(buffer->buf[i])) +			return -1; +		b = buffer->buf[i++]; +		buffer->procoff = i; + +		a = (char)((a & 15) + (a > '9' ? 9 : 0)); +		b = (char)((b & 15) + (b > '9' ? 9 : 0)); +		a <<= 4; +		a |= b; +		buffer->buf[buffer->ready++] = a; +	} + +	return 0; +} | 
