diff options
Diffstat (limited to 'src/blob.c')
-rw-r--r-- | src/blob.c | 127 |
1 files changed, 91 insertions, 36 deletions
@@ -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; } |