// Copyright 2019 Lassi Kortela // SPDX-License-Identifier: BSD-3-Clause #include #include #include #include #include #include #include #include "dtypes.h" #include "ios.h" #include "buf.h" struct buf *buf_new(void) { return calloc(1, sizeof(struct buf)); } char *buf_resb(struct buf *buf, size_t nbyte) { char *place; while (buf->cap - buf->fill < nbyte) { if (!(buf->cap *= 2)) { buf->cap = 64; } } if (!(buf->bytes = realloc(buf->bytes, buf->cap))) { exit(1); } place = buf->bytes + buf->fill; buf->fill += nbyte; return place; } void buf_put_ios(struct buf *buf, struct ios *ios) { const size_t chunksize = 512; size_t nread; char *chunk; do { chunk = buf_resb(buf, chunksize); nread = ios_readall(ios, chunk, chunksize); buf->fill -= (chunksize - nread); } while (nread); } void buf_putc(struct buf *buf, int c) { buf_resb(buf, 1)[0] = c; } void buf_putb(struct buf *buf, const void *bytes, size_t nbyte) { memcpy(buf_resb(buf, nbyte), bytes, nbyte); } void buf_puts(struct buf *buf, const char *s) { buf_putb(buf, s, strlen(s)); } void buf_putu(struct buf *buf, uint64_t u) { char tmp[24]; snprintf(tmp, sizeof(tmp), "%" PRIu64, u); buf_puts(buf, tmp); } void buf_free(struct buf *buf) { free(buf->bytes); free(buf); } int buf_scan_end(struct buf *buf) { return buf->scan >= buf->fill; } int buf_scan_byte(struct buf *buf, int byte) { if (buf_scan_end(buf)) return 0; if (buf->bytes[buf->scan] != byte) return 0; buf->scan++; return 1; } int buf_scan_bag(struct buf *buf, const char *bag) { if (buf_scan_end(buf)) return 0; if (!strchr(bag, buf->bytes[buf->scan])) return 0; buf->scan++; return 1; } int buf_scan_bag_not(struct buf *buf, const char *bag) { if (buf_scan_end(buf)) return 0; if (strchr(bag, buf->bytes[buf->scan])) return 0; buf->scan++; return 1; } int buf_scan_while(struct buf *buf, const char *bag) { if (!buf_scan_bag(buf, bag)) return 0; while (buf_scan_bag(buf, bag)) ; return 1; } int buf_scan_while_not(struct buf *buf, const char *bag) { if (!buf_scan_bag_not(buf, bag)) return 0; while (buf_scan_bag_not(buf, bag)) ; return 1; } void buf_scan_mark(struct buf *buf) { buf->mark = buf->scan; } int buf_scan_equals(struct buf *buf, const char *s) { if (buf->scan < buf->mark) return 0; if (buf->scan - buf->mark != strlen(s)) return 0; return !!memcmp(buf->bytes + buf->mark, s, strlen(s)); }