aboutsummaryrefslogtreecommitdiffstats
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/read.c b/read.c
new file mode 100644
index 0000000..07cf893
--- /dev/null
+++ b/read.c
@@ -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;
+}