From: Nathan Wagner Date: Tue, 26 Feb 2019 05:51:17 +0000 (+0000) Subject: add buffer lib files X-Git-Tag: v0.7.0~13 X-Git-Url: https://pd.if.org/git/?p=zpackage;a=commitdiff_plain;h=290e4a5a70804333d0d0060035292ebe1cc758cd add buffer lib files --- diff --git a/lib/buffer.c b/lib/buffer.c new file mode 100644 index 0000000..adf7ab8 --- /dev/null +++ b/lib/buffer.c @@ -0,0 +1,277 @@ +#define _POSIX_C_SOURCE 200809L + +#include +#include +#include +#include +#include + +#include "buffer.h" + +void zpm_buffer_init(struct zpm_buffer *buffer) { + buffer->buffer = 0; + buffer->len = 0; + buffer->size = 0; + buffer->error = 0; +} + +void zpm_buffer_compact(struct zpm_buffer *b) { + void *new; + + if (b->error || b->size == b->len) { + return; + } + + errno = 0; + new = realloc(b->buffer, b->len); + + if (new == NULL) { + b->error = errno; + return; + } + + b->buffer = new; + return; +} + +/* makes sure there's at least need bytes free */ +void zpm_buffer_expand(struct zpm_buffer *buf, size_t need) { + size_t want; + + if (buf->error) { + return; + } + + want = buf->len + need; + + if (want <= buf->size) { + return; + } + + errno = 0; + char *new = realloc(buf->buffer, want); + if (new) { + buf->buffer = new; + buf->size = want; + memset(buf->buffer + buf->len, 0, buf->size - buf->len); + } else { + buf->error = errno; + } +} + +void zpm_buffer_free(struct zpm_buffer *buffer) { + /* TODO only zero out memory if it's "secure" buffer */ + if (buffer->buffer && buffer->len) { + memset(buffer->buffer, 0, buffer->len); + } + free(buffer->buffer); + zpm_buffer_init(buffer); +} + +void zpm_buffer_set(struct zpm_buffer *buffer, int ch) { + /* TODO only zero out memory if it's "secure" buffer */ + if (buffer->buffer && buffer->size) { + memset(buffer->buffer, ch, buffer->size); + } +} + +void zpm_buffer_appendvf(struct zpm_buffer *buf, const char *fmt, va_list ap) { + int len; + va_list ar; + + va_copy(ar, ap); + len = vsnprintf(0, 0, fmt, ar); + va_end(ar); + + zpm_buffer_expand(buf, len+1); + vsprintf(buf->buffer + buf->len, fmt, ap); +} + +void zpm_buffer_appendf(struct zpm_buffer *buf, const char *fmt, ...) { + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(0, 0, fmt, ap); + va_end(ap); + zpm_buffer_expand(buf, len+1); + va_start(ap, fmt); + vsprintf(buf->buffer + buf->len, fmt, ap); + va_end(ap); +} + +void zpm_buffer_append(struct zpm_buffer *buffer, const unsigned char *bytes, size_t n) { + zpm_buffer_expand(buffer, n); + + if (buffer->error || !bytes) { + return; + } + + memcpy(buffer->buffer + buffer->len, bytes, n); + buffer->len += n; +} + +void zpm_buffer_append_str(struct zpm_buffer *buf, const char *s) { + zpm_buffer_append(buf, (const unsigned char *)s, strlen(s)); +} + +void zpm_buffer_append16(struct zpm_buffer *buffer, uint16_t n) { + zpm_buffer_expand(buffer, 2); + + if (buffer->error) { + return; + } + + buffer->buffer[buffer->len++] = (n >> 8) & 0xff; + buffer->buffer[buffer->len++] = n & 0xff; +} + +void zpm_buffer_append24(struct zpm_buffer *buffer, uint32_t n) { + zpm_buffer_expand(buffer, 3); + + if (buffer->error) { + return; + } + + buffer->buffer[buffer->len++] = (n >> 16) & 0xff; + buffer->buffer[buffer->len++] = (n >> 8) & 0xff; + buffer->buffer[buffer->len++] = n & 0xff; +} + +void zpm_buffer_append_byte(struct zpm_buffer *buffer, uint8_t n) { + zpm_buffer_expand(buffer, 1); + + if (buffer->error) { + return; + } + + buffer->buffer[buffer->len++] = n & 0xff; +} + +void zpm_buffer_write16(struct zpm_buffer *buffer, uint16_t n, size_t at) { + if (at+2 > buffer->size) { + zpm_buffer_expand(buffer, at+2 - buffer->size); + } + + if (buffer->error) { + return; + } + + buffer->buffer[at] = (n >> 8) & 0xff; + buffer->buffer[at+1] = n & 0xff; + + if (at+2 > buffer->len) { + buffer->len = at + 2; + } +} + +uint16_t zpm_buffer_read16(struct zpm_buffer *buffer, size_t at) { + uint16_t res = 0; + + if (buffer->error || at+2 < buffer->len) { + return 0; + } + + res = (buffer->buffer[at] << 8) + buffer->buffer[at+1]; + return res; +} + +uint64_t zpm_buffer_readbe(struct zpm_buffer *buffer, int bytes, size_t at) { + uint16_t res = 0; + int i; + + if (buffer->error || at+bytes < buffer->len) { + return 0; + } + + for (i=0; ibuffer[at+i]; + } + + return res; +} + +void zpm_buffer_writebe(struct zpm_buffer *buffer, int bytes, size_t at, uint64_t val) { + int i; + if (at+bytes > buffer->size) { + zpm_buffer_expand(buffer, at+bytes - buffer->size); + } + + if (buffer->error) { + return; + } + + for (i=bytes-1; i>=0; i--) { + buffer->buffer[at+i] = val & 0xff; + val >>= 8; + } + + return; +} + +void zpm_buffer_shift(struct zpm_buffer *buffer, size_t n) { + if (buffer->error) { + return; + } + + if (buffer->len < n) { + n = buffer->len; + } + + if (n) { + memmove(buffer->buffer, buffer->buffer + n, buffer->len - n); + memset(buffer->buffer + buffer->len - n, 0, n); +#if 0 + fprintf(stderr, "memmove(%p, %p, %zu)\n", buffer->buffer, + buffer->buffer+n, buffer->len - n); + fprintf(stderr, "memset(%p, %d, %zu)\n", buffer->buffer+n, + 0, n); +#endif + + buffer->len -= n; + } +} + +/* make room at the beginning */ +void zpm_buffer_unshift(struct zpm_buffer *buffer, size_t n) { + zpm_buffer_expand(buffer, n); + + if (buffer->error) { + return; + } + + memmove(buffer->buffer + n, buffer->buffer, n); + memset(buffer->buffer, 0, n); +} + +#if 0 +uint32_t zpm_buffer_next3(struct zpm_buffer_reader *rb) { + uint32_t r; + + r = zpm_buffer_readbe(rb, 3, rb->cursor); + rb->cursor += 3; + return r; +} + +uint16_t zpm_buffer_next2(struct zpm_buffer_reader *rb) { + uint16_t r; + + r = zpm_buffer_readbe(rb, 2, rb->cursor); + rb->cursor += 2; + return r; +} + +uint8_t zpm_buffer_next(struct zpm_buffer_reader *rb) { + uint16_t r; + + r = zpm_buffer_readbe(rb, 2, rb->cursor); + rb->cursor += 2; + +} + +void zpm_buffer_nextn(struct zpm_buffer_reader *rb, unsigned char *b, size_t n) { + zpm_buffer_read(rb, b, n, rb->cursor); + rb->cursor += n; +} +#endif diff --git a/lib/buffer.h b/lib/buffer.h new file mode 100644 index 0000000..7a849d8 --- /dev/null +++ b/lib/buffer.h @@ -0,0 +1,53 @@ +#ifndef ZPM_BUFFER_H_ +#define ZPM_BUFFER_H_ 1 + +#include +#include +#include + +/* flags: + * 0x1 secure: zero memory when used + * 0x2 fixed: buffer doesn't belong to you, and size says how big it is + * 0x4 + */ +struct zpm_buffer { + char *buffer; + size_t len; + size_t size; + int32_t error; + uint32_t flags; +}; + +struct zpm_buffer_reader { + struct zpm_buffer b; + size_t cursor; +}; + +uint32_t zpm_buffer_next3(struct zpm_buffer_reader *rb); +uint16_t zpm_buffer_next2(struct zpm_buffer_reader *rb); +uint8_t zpm_buffer_next(struct zpm_buffer_reader *rb); +void zpm_buffer_nextn(struct zpm_buffer_reader *rb, unsigned char *b, size_t n); + +void zpm_buffer_init(struct zpm_buffer *b); + +/* makes sure there's at least need bytes free */ +void zpm_buffer_expand(struct zpm_buffer *b, size_t need); +void zpm_buffer_free(struct zpm_buffer *b); +void zpm_buffer_set(struct zpm_buffer *buffer, int ch); +void zpm_buffer_compact(struct zpm_buffer *b); +void zpm_buffer_append(struct zpm_buffer *b, const unsigned char *bytes, size_t n); +void zpm_buffer_appendf(struct zpm_buffer *b, const char *fmt, ...); +void zpm_buffer_appendvf(struct zpm_buffer *b, const char *fmt, va_list ap); +void zpm_buffer_append_str(struct zpm_buffer *b, const char *s); +void zpm_buffer_append16(struct zpm_buffer *b, uint16_t n); +void zpm_buffer_append24(struct zpm_buffer *b, uint32_t n); +void zpm_buffer_append_byte(struct zpm_buffer *b, uint8_t n); +void zpm_buffer_shift(struct zpm_buffer *b, size_t n); +void zpm_buffer_write16(struct zpm_buffer *b, uint16_t n, size_t at); +void zpm_buffer_writebe(struct zpm_buffer *b, int bytes, size_t at, uint64_t val); +uint64_t zpm_buffer_readbe(struct zpm_buffer *b, int bytes, size_t at); + +/* make room at the beginning */ +void zpm_buffer_unshift(struct zpm_buffer *b, size_t n); + +#endif