summaryrefslogtreecommitdiffstats
path: root/libdnet-stripped/src/blob.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdnet-stripped/src/blob.c')
-rw-r--r--libdnet-stripped/src/blob.c458
1 files changed, 458 insertions, 0 deletions
diff --git a/libdnet-stripped/src/blob.c b/libdnet-stripped/src/blob.c
new file mode 100644
index 0000000..57ff0c3
--- /dev/null
+++ b/libdnet-stripped/src/blob.c
@@ -0,0 +1,458 @@
+/*
+ * blob.c
+ *
+ * Copyright (c) 2002 Dug Song <dugsong@monkey.org>
+ *
+ * $Id: blob.c 615 2006-01-08 16:06:49Z dugsong $
+ */
+
+#ifdef _WIN32
+#include "dnet_winconfig.h"
+#else
+#include "config.h"
+#endif
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dnet.h"
+
+static void *(*bl_malloc)(size_t) = malloc;
+static void *(*bl_realloc)(void *, size_t) = realloc;
+static void (*bl_free)(void *) = free;
+static int bl_size = BUFSIZ;
+
+static int fmt_D(int, int, blob_t *, va_list *);
+static int fmt_H(int, int, blob_t *, va_list *);
+static int fmt_b(int, int, blob_t *, va_list *);
+static int fmt_c(int, int, blob_t *, va_list *);
+static int fmt_d(int, int, blob_t *, va_list *);
+static int fmt_h(int, int, blob_t *, va_list *);
+static int fmt_s(int, int, blob_t *, va_list *);
+
+static void print_hexl(blob_t *);
+
+static blob_fmt_cb blob_ascii_fmt[] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, fmt_D, NULL, NULL, NULL,
+ fmt_H, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, fmt_b, fmt_c, fmt_d, NULL, NULL, NULL,
+ fmt_h, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, fmt_s, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+struct blob_printer {
+ char *name;
+ void (*print)(blob_t *);
+} blob_printers[] = {
+ { "hexl", print_hexl },
+ { NULL, NULL },
+};
+
+blob_t *
+blob_new(void)
+{
+ blob_t *b;
+
+ if ((b = bl_malloc(sizeof(*b))) != NULL) {
+ b->off = b->end = 0;
+ b->size = bl_size;
+ if ((b->base = bl_malloc(b->size)) == NULL) {
+ bl_free(b);
+ b = NULL;
+ }
+ }
+ return (b);
+}
+
+static int
+blob_reserve(blob_t *b, int len)
+{
+ void *p;
+ int nsize;
+
+ if (b->size < b->end + len) {
+ if (b->size == 0)
+ return (-1);
+
+ if ((nsize = b->end + len) > bl_size)
+ nsize = ((nsize / bl_size) + 1) * bl_size;
+
+ if ((p = bl_realloc(b->base, nsize)) == NULL)
+ return (-1);
+
+ b->base = p;
+ b->size = nsize;
+ }
+ b->end += len;
+
+ return (0);
+}
+
+int
+blob_read(blob_t *b, void *buf, int len)
+{
+ if (b->end - b->off < len)
+ len = b->end - b->off;
+
+ memcpy(buf, b->base + b->off, len);
+ b->off += len;
+
+ return (len);
+}
+
+int
+blob_write(blob_t *b, const void *buf, int len)
+{
+ if (b->off + len <= b->end ||
+ blob_reserve(b, b->off + len - b->end) == 0) {
+ memcpy(b->base + b->off, (u_char *)buf, len);
+ b->off += len;
+ return (len);
+ }
+ return (-1);
+}
+
+int
+blob_insert(blob_t *b, const void *buf, int len)
+{
+ if (blob_reserve(b, len) == 0 && b->size) {
+ if (b->end - b->off > 0)
+ memmove( b->base + b->off + len, b->base + b->off, b->end - b->off);
+ memcpy(b->base + b->off, buf, len);
+ b->off += len;
+ return (len);
+ }
+ return (-1);
+}
+
+int
+blob_delete(blob_t *b, void *buf, int len)
+{
+ if (b->off + len <= b->end && b->size) {
+ if (buf != NULL)
+ memcpy(buf, b->base + b->off, len);
+ memmove(b->base + b->off, b->base + b->off + len, b->end - (b->off + len));
+ b->end -= len;
+ return (len);
+ }
+ return (-1);
+}
+
+static int
+blob_fmt(blob_t *b, int pack, const char *fmt, va_list *ap)
+{
+ blob_fmt_cb fmt_cb;
+ char *p;
+ int len;
+
+ for (p = (char *)fmt; *p != '\0'; p++) {
+ if (*p == '%') {
+ p++;
+ if (isdigit((int) (unsigned char) *p)) {
+ len = strtol(p, &p, 10);
+ } else if (*p == '*') {
+ len = va_arg(*ap, int);
+ p++;
+ } else
+ len = 0;
+
+ if ((fmt_cb = blob_ascii_fmt[(int)*p]) == NULL)
+ return (-1);
+
+ if ((*fmt_cb)(pack, len, b, ap) < 0)
+ return (-1);
+ } else {
+ if (pack) {
+ if (b->off + 1 < b->end ||
+ blob_reserve(b, b->off + 1 - b->end) == 0)
+ b->base[b->off++] = *p;
+ else
+ return (-1);
+ } else {
+ if (b->base[b->off++] != *p)
+ return (-1);
+ }
+ }
+ }
+ return (0);
+}
+
+int
+blob_pack(blob_t *b, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ return (blob_fmt(b, 1, fmt, &ap));
+}
+
+int
+blob_unpack(blob_t *b, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ return (blob_fmt(b, 0, fmt, &ap));
+}
+
+int
+blob_seek(blob_t *b, int off, int whence)
+{
+ if (whence == SEEK_CUR)
+ off += b->off;
+ else if (whence == SEEK_END)
+ off += b->end;
+
+ if (off < 0 || off > b->end)
+ return (-1);
+
+ return ((b->off = off));
+}
+
+int
+blob_index(blob_t *b, const void *buf, int len)
+{
+ int i;
+
+ for (i = b->off; i <= b->end - len; i++) {
+ if (memcmp(b->base + i, buf, len) == 0)
+ return (i);
+ }
+ return (-1);
+}
+
+int
+blob_rindex(blob_t *b, const void *buf, int len)
+{
+ int i;
+
+ for (i = b->end - len; i >= 0; i--) {
+ if (memcmp(b->base + i, buf, len) == 0)
+ return (i);
+ }
+ return (-1);
+}
+
+int
+blob_print(blob_t *b, char *style, int len)
+{
+ struct blob_printer *bp;
+
+ for (bp = blob_printers; bp->name != NULL; bp++) {
+ if (strcmp(bp->name, style) == 0)
+ bp->print(b);
+ }
+ return (0);
+}
+
+int
+blob_sprint(blob_t *b, char *style, int len, char *dst, int size)
+{
+ return (0);
+}
+
+blob_t *
+blob_free(blob_t *b)
+{
+ if (b->size)
+ bl_free(b->base);
+ bl_free(b);
+ return (NULL);
+}
+
+int
+blob_register_alloc(size_t size, void *(bmalloc)(size_t),
+ void (*bfree)(void *), void *(*brealloc)(void *, size_t))
+{
+ bl_size = size;
+ if (bmalloc != NULL)
+ bl_malloc = bmalloc;
+ if (bfree != NULL)
+ bl_free = bfree;
+ if (brealloc != NULL)
+ bl_realloc = brealloc;
+ return (0);
+}
+
+int
+blob_register_pack(char c, blob_fmt_cb fmt_cb)
+{
+ if (blob_ascii_fmt[(int)c] == NULL) {
+ blob_ascii_fmt[(int)c] = fmt_cb;
+ return (0);
+ }
+ return (-1);
+}
+
+static int
+fmt_D(int pack, int len, blob_t *b, va_list *ap)
+{
+ if (len) return (-1);
+
+ if (pack) {
+ uint32_t n = va_arg(*ap, uint32_t);
+ n = htonl(n);
+ if (blob_write(b, &n, sizeof(n)) < 0)
+ return (-1);
+ } else {
+ uint32_t *n = va_arg(*ap, uint32_t *);
+ if (blob_read(b, n, sizeof(*n)) != sizeof(*n))
+ return (-1);
+ *n = ntohl(*n);
+ }
+ return (0);
+}
+
+static int
+fmt_H(int pack, int len, blob_t *b, va_list *ap)
+{
+ if (len) return (-1);
+
+ if (pack) {
+ uint16_t n = va_arg(*ap, int);
+ n = htons(n);
+ if (blob_write(b, &n, sizeof(n)) < 0)
+ return (-1);
+ } else {
+ uint16_t *n = va_arg(*ap, uint16_t *);
+ if (blob_read(b, n, sizeof(*n)) != sizeof(*n))
+ return (-1);
+ *n = ntohs(*n);
+ }
+ return (0);
+}
+
+static int
+fmt_b(int pack, int len, blob_t *b, va_list *ap)
+{
+ void *p = va_arg(*ap, void *);
+
+ if (len <= 0) return (-1);
+
+ if (pack)
+ return (blob_write(b, p, len));
+ else
+ return (blob_read(b, p, len));
+}
+
+static int
+fmt_c(int pack, int len, blob_t *b, va_list *ap)
+{
+ if (len) return (-1);
+
+ if (pack) {
+ uint8_t n = va_arg(*ap, int);
+ return (blob_write(b, &n, sizeof(n)));
+ } else {
+ uint8_t *n = va_arg(*ap, uint8_t *);
+ return (blob_read(b, n, sizeof(*n)));
+ }
+}
+
+static int
+fmt_d(int pack, int len, blob_t *b, va_list *ap)
+{
+ if (len) return (-1);
+
+ if (pack) {
+ uint32_t n = va_arg(*ap, uint32_t);
+ return (blob_write(b, &n, sizeof(n)));
+ } else {
+ uint32_t *n = va_arg(*ap, uint32_t *);
+ return (blob_read(b, n, sizeof(*n)));
+ }
+}
+
+static int
+fmt_h(int pack, int len, blob_t *b, va_list *ap)
+{
+ if (len) return (-1);
+
+ if (pack) {
+ uint16_t n = va_arg(*ap, int);
+ return (blob_write(b, &n, sizeof(n)));
+ } else {
+ uint16_t *n = va_arg(*ap, uint16_t *);
+ return (blob_read(b, n, sizeof(*n)));
+ }
+}
+
+static int
+fmt_s(int pack, int len, blob_t *b, va_list *ap)
+{
+ char *p = va_arg(*ap, char *);
+ char c = '\0';
+ int i, end;
+
+ if (pack) {
+ if (len > 0) {
+ if ((c = p[len - 1]) != '\0')
+ p[len - 1] = '\0';
+ } else
+ len = strlen(p) + 1;
+
+ if (blob_write(b, p, len) > 0) {
+ if (c != '\0')
+ p[len - 1] = c;
+ return (len);
+ }
+ } else {
+ if (len <= 0) return (-1);
+
+ if ((end = b->end - b->off) < len)
+ end = len;
+
+ for (i = 0; i < end; i++) {
+ if ((p[i] = b->base[b->off + i]) == '\0') {
+ b->off += i + 1;
+ return (i);
+ }
+ }
+ }
+ return (-1);
+}
+
+static void
+print_hexl(blob_t *b)
+{
+ u_int i, j, jm, len;
+ u_char *p;
+ int c;
+
+ p = b->base + b->off;
+ len = b->end - b->off;
+
+ printf("\n");
+
+ for (i = 0; i < len; i += 0x10) {
+ printf(" %04x: ", (u_int)(i + b->off));
+ jm = len - i;
+ jm = jm > 16 ? 16 : jm;
+
+ for (j = 0; j < jm; j++) {
+ printf((j % 2) ? "%02x " : "%02x", (u_int)p[i + j]);
+ }
+ for (; j < 16; j++) {
+ printf((j % 2) ? " " : " ");
+ }
+ printf(" ");
+
+ for (j = 0; j < jm; j++) {
+ c = p[i + j];
+ printf("%c", isprint(c) ? c : '.');
+ }
+ printf("\n");
+ }
+}