diff options
Diffstat (limited to '')
-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; +} |