summaryrefslogtreecommitdiffstats
path: root/blob.c
diff options
context:
space:
mode:
Diffstat (limited to 'blob.c')
-rw-r--r--blob.c69
1 files changed, 62 insertions, 7 deletions
diff --git a/blob.c b/blob.c
index a25e5e8..377ec62 100644
--- a/blob.c
+++ b/blob.c
@@ -1,6 +1,18 @@
#include "blob.h"
const blob_t BLOB_NULL = { NULL, 0 };
+static const char *xd = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+static inline int dx(int c)
+{
+ if (likely(c >= '0' && c <= '9'))
+ return c - '0';
+ if (likely(c >= 'a' && c <= 'f'))
+ return c - 'a' + 0xa;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 0xa;
+ return -1;
+}
char *blob_cstr_dup(blob_t b)
{
@@ -45,7 +57,7 @@ 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);
+ return BLOB_PTR_LEN(buffer.ptr, left.ptr - buffer.ptr);
}
void blob_push(blob_t *b, blob_t d)
@@ -59,13 +71,22 @@ void blob_push(blob_t *b, blob_t d)
}
}
-void blob_push_int_str(blob_t *b, int val)
+void blob_push_uint(blob_t *to, unsigned int value, int radix)
{
- int l;
+ char buf[64];
+ char *ptr = &buf[sizeof(buf)-1];
+
+ if (value == 0) {
+ blob_push(to, BLOB_STR("0"));
+ return;
+ }
+
+ while (value != 0) {
+ *(ptr--) = xd[value % radix];
+ value /= radix;
+ }
- l = snprintf(b->ptr, b->len, "%d", val);
- b->ptr += l;
- b->len -= l;
+ blob_push(to, BLOB_PTR_PTR(ptr+1, &buf[sizeof(buf)-1]));
}
void blob_push_hexdump(blob_t *to, blob_t binary)
@@ -95,7 +116,7 @@ blob_t blob_pull(blob_t *b, int len)
blob_t r;
if (b->len >= len) {
- r = blob_dyn(b->ptr, len);
+ r = BLOB_PTR_LEN(b->ptr, len);
b->ptr += len;
b->len -= len;
return r;
@@ -125,3 +146,37 @@ int blob_pull_matching(blob_t *b, blob_t e)
return 1;
}
+unsigned int blob_pull_uint(blob_t *b, int radix)
+{
+ unsigned int val;
+ int ch;
+
+ val = 0;
+ while (b->len && b->ptr[0] != 0) {
+ ch = dx(b->ptr[0]);
+ if (ch < 0 || ch >= radix)
+ break;
+ val *= radix;
+ val += ch;
+
+ b->ptr++;
+ b->len--;
+ }
+
+ return val;
+}
+
+blob_t blob_pull_cspn(blob_t *b, const blob_t reject)
+{
+ blob_t t = *b;
+ int i;
+
+ for (i = 0; i < t.len; i++) {
+ if (memchr(reject.ptr, t.ptr[i], reject.len) != NULL) {
+ *b = BLOB_PTR_LEN(t.ptr + i, t.len - i);
+ return BLOB_PTR_LEN(t.ptr, i);
+ }
+ }
+ *b = BLOB_NULL;
+ return t;
+}