summaryrefslogtreecommitdiff
path: root/src/blob.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/blob.c')
-rw-r--r--src/blob.c127
1 files changed, 91 insertions, 36 deletions
diff --git a/src/blob.c b/src/blob.c
index 9f253cb..cbcb312 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -151,62 +151,117 @@ static inline int dx(int c)
return -1;
}
-unsigned int apk_blob_parse_uint(apk_blob_t *blob, int base)
+void apk_blob_push_blob(apk_blob_t *to, apk_blob_t literal)
{
- unsigned int val;
- int ch;
-
- val = 0;
- while (blob->len && blob->ptr[0] != 0) {
- ch = dx(blob->ptr[0]);
- if (ch < 0 || ch >= base)
- break;
- val *= base;
- val += ch;
+ if (APK_BLOB_IS_NULL(*to))
+ return;
- blob->ptr++;
- blob->len--;
+ if (to->len < literal.len) {
+ *to = APK_BLOB_NULL;
+ return;
}
- return val;
+ memcpy(to->ptr, literal.ptr, literal.len);
+ to->ptr += literal.len;
+ to->len -= literal.len;
}
-int apk_blob_parse_char(apk_blob_t *blob)
+static const char *xd = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+void apk_blob_push_uint(apk_blob_t *to, unsigned int value, int radix)
{
- int r;
+ char buf[64];
+ char *ptr = &buf[sizeof(buf)-1];
- if (blob->len == 0 || blob->ptr == NULL)
- return -1;
- r = blob->ptr[0];
- blob->ptr++;
- blob->len--;
+ if (value == 0) {
+ apk_blob_push_blob(to, APK_BLOB_STR("0"));
+ return;
+ }
+
+ while (value != 0) {
+ *(ptr--) = xd[value % radix];
+ value /= radix;
+ }
- return r;
+ apk_blob_push_blob(to, APK_BLOB_PTR_PTR(ptr+1, &buf[sizeof(buf)-1]));
}
-int apk_hexdump_parse(apk_blob_t to, apk_blob_t from)
+void apk_blob_push_hexdump(apk_blob_t *to, apk_blob_t binary)
{
+ char *d;
int i;
- if (to.len * 2 != from.len)
- return -1;
+ if (APK_BLOB_IS_NULL(*to))
+ return;
- for (i = 0; i < from.len / 2; i++)
- to.ptr[i] = (dx(from.ptr[i*2]) << 4) + dx(from.ptr[i*2+1]);
+ if (to->len < binary.len * 2) {
+ *to = APK_BLOB_NULL;
+ return;
+ }
- return 0;
+ 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;
}
-int apk_hexdump_format(int tolen, char *to, apk_blob_t from)
+void apk_blob_pull_char(apk_blob_t *b, int expected)
{
- static const char *xd = "0123456789abcdef";
- int i;
+ if (APK_BLOB_IS_NULL(*b))
+ return;
+ if (b->len < 1 || b->ptr[0] != expected) {
+ *b = APK_BLOB_NULL;
+ return;
+ }
+ b->ptr ++;
+ b->len --;
+}
+
+unsigned int apk_blob_pull_uint(apk_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;
- for (i = 0; i < from.len && i*2+2 < tolen; i++) {
- to[i*2+0] = xd[(from.ptr[i] >> 4) & 0xf];
- to[i*2+1] = xd[from.ptr[i] & 0xf];
+ b->ptr++;
+ b->len--;
}
- to[i*2] = 0;
- return i*2;
+ return val;
+}
+
+void apk_blob_pull_hexdump(apk_blob_t *b, apk_blob_t to)
+{
+ char *s, *d;
+ int i, r1, r2;
+
+ if (APK_BLOB_IS_NULL(*b))
+ return;
+
+ if (to.len > b->len * 2)
+ goto err;
+
+ for (i = 0, s = b->ptr, d = to.ptr; i < to.len; i++) {
+ r1 = dx(*(s++));
+ if (r1 < 0)
+ goto err;
+ r2 = dx(*(s++));
+ if (r2 < 0)
+ goto err;
+ *(d++) = (r1 << 4) + r2;
+ }
+ b->ptr = s;
+ b->len -= to.len * 2;
+ return;
+err:
+ *b = APK_BLOB_NULL;
}