summaryrefslogtreecommitdiff
path: root/src/blob.c
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-07-14 13:27:21 +0300
committerTimo Teras <timo.teras@iki.fi>2009-07-14 13:27:21 +0300
commit8d1eeb58e450ef4a81497c3233a929350af3e467 (patch)
treed2dcec64c9449ea431fb259410e1136479e21bc8 /src/blob.c
parentab37bd0b0c0da340222f8420ec2ee6ccdd13ce24 (diff)
downloadapk-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.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;
}