diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-07-14 13:27:21 +0300 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-07-14 13:27:21 +0300 |
commit | 8d1eeb58e450ef4a81497c3233a929350af3e467 (patch) | |
tree | d2dcec64c9449ea431fb259410e1136479e21bc8 /src/blob.c | |
parent | ab37bd0b0c0da340222f8420ec2ee6ccdd13ce24 (diff) | |
download | apk-tools-8d1eeb58e450ef4a81497c3233a929350af3e467.tar.gz apk-tools-8d1eeb58e450ef4a81497c3233a929350af3e467.tar.bz2 apk-tools-8d1eeb58e450ef4a81497c3233a929350af3e467.tar.xz apk-tools-8d1eeb58e450ef4a81497c3233a929350af3e467.zip |
blob: some helpers to replace snprintf
snprintf is dog slow. make the blob stuff have some helper functions
so we can use them in code paths that are executed often.
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; } |