summaryrefslogtreecommitdiffstats
path: root/blob.c
diff options
context:
space:
mode:
Diffstat (limited to 'blob.c')
-rw-r--r--blob.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/blob.c b/blob.c
new file mode 100644
index 0000000..a25e5e8
--- /dev/null
+++ b/blob.c
@@ -0,0 +1,127 @@
+#include "blob.h"
+
+const blob_t BLOB_NULL = { NULL, 0 };
+
+char *blob_cstr_dup(blob_t b)
+{
+ char *p;
+
+ if (blob_is_null(b))
+ return NULL;
+
+ p = malloc(b.len+1);
+ if (p != NULL) {
+ memcpy(p, b.ptr, b.len);
+ p[b.len] = 0;
+ }
+ return p;
+}
+
+blob_t blob_dup(blob_t b)
+{
+ blob_t p;
+
+ if (blob_is_null(b))
+ return BLOB_NULL;
+
+ p.ptr = malloc(b.len);
+ if (p.ptr != NULL) {
+ memcpy(p.ptr, b.ptr, b.len);
+ p.len = b.len;
+ } else {
+ p.len = 0;
+ }
+ return p;
+}
+
+int blob_cmp(blob_t a, blob_t b)
+{
+ if (a.len != b.len)
+ return a.len - b.len;
+ return memcmp(a.ptr, b.ptr, a.len);
+}
+
+blob_t blob_pushed(blob_t buffer, blob_t left)
+{
+ if (buffer.ptr + buffer.len != left.ptr + left.len)
+ return BLOB_NULL;
+ return blob_dyn(buffer.ptr, left.ptr - buffer.ptr);
+}
+
+void blob_push(blob_t *b, blob_t d)
+{
+ if (b->len >= d.len) {
+ memcpy(b->ptr, d.ptr, d.len);
+ b->ptr += d.len;
+ b->len -= d.len;
+ } else {
+ *b = BLOB_NULL;
+ }
+}
+
+void blob_push_int_str(blob_t *b, int val)
+{
+ int l;
+
+ l = snprintf(b->ptr, b->len, "%d", val);
+ b->ptr += l;
+ b->len -= l;
+}
+
+void blob_push_hexdump(blob_t *to, blob_t binary)
+{
+ static const char *xd = "0123456789abcdef";
+ char *d;
+ int i;
+
+ if (blob_is_null(*to))
+ return;
+
+ if (to->len < binary.len * 2) {
+ *to = BLOB_NULL;
+ return;
+ }
+
+ for (i = 0, d = to->ptr; i < binary.len; i++) {
+ *(d++) = xd[(binary.ptr[i] >> 4) & 0xf];
+ *(d++) = xd[binary.ptr[i] & 0xf];
+ }
+ to->ptr = d;
+ to->len -= binary.len * 2;
+}
+
+blob_t blob_pull(blob_t *b, int len)
+{
+ blob_t r;
+
+ if (b->len >= len) {
+ r = blob_dyn(b->ptr, len);
+ b->ptr += len;
+ b->len -= len;
+ return r;
+ }
+ *b = BLOB_NULL;
+ return BLOB_NULL;
+}
+
+void blob_pull_skip(blob_t *b, int len)
+{
+ if (b->len >= len) {
+ b->ptr += len;
+ b->len -= len;
+ } else {
+ *b = BLOB_NULL;
+ }
+}
+
+int blob_pull_matching(blob_t *b, blob_t e)
+{
+ if (b->len < e.len)
+ return 0;
+ if (memcmp(b->ptr, e.ptr, e.len) != 0)
+ return 0;
+ b->ptr += e.len;
+ b->len -= e.len;
+ return 1;
+}
+