summaryrefslogtreecommitdiffstats
path: root/blob.c
blob: a25e5e8f56c0917bc2d0383603e4630abf38c812 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "blob.h"

const blob_t BLOB_NULL = { NULL, 0 };

char *blob_cstr_dup(blob_t b)
{
	char *p;

	if (blob_is_null(b))
		return NULL;

	p = malloc(b.len+1);
	if (p != NULL) {
		memcpy(p, b.ptr, b.len);
		p[b.len] = 0;
	}
	return p;
}

blob_t blob_dup(blob_t b)
{
	blob_t p;

	if (blob_is_null(b))
		return BLOB_NULL;

	p.ptr = malloc(b.len);
	if (p.ptr != NULL) {
		memcpy(p.ptr, b.ptr, b.len);
		p.len = b.len;
	} else {
		p.len = 0;
	}
	return p;
}

int blob_cmp(blob_t a, blob_t b)
{
	if (a.len != b.len)
		return a.len - b.len;
	return memcmp(a.ptr, b.ptr, a.len);
}

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);
}

void blob_push(blob_t *b, blob_t d)
{
	if (b->len >= d.len) {
		memcpy(b->ptr, d.ptr, d.len);
		b->ptr += d.len;
		b->len -= d.len;
	} else {
		*b = BLOB_NULL;
	}
}

void blob_push_int_str(blob_t *b, int val)
{
	int l;

	l = snprintf(b->ptr, b->len, "%d", val);
	b->ptr += l;
	b->len -= l;
}

void blob_push_hexdump(blob_t *to, blob_t binary)
{
	static const char *xd = "0123456789abcdef";
	char *d;
	int i;

	if (blob_is_null(*to))
		return;

	if (to->len < binary.len * 2) {
		*to = BLOB_NULL;
		return;
	}

	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;
}

blob_t blob_pull(blob_t *b, int len)
{
	blob_t r;

	if (b->len >= len) {
		r = blob_dyn(b->ptr, len);
		b->ptr += len;
		b->len -= len;
		return r;
	}
	*b = BLOB_NULL;
	return BLOB_NULL;
}

void blob_pull_skip(blob_t *b, int len)
{
	if (b->len >= len) {
		b->ptr += len;
		b->len -= len;
	} else {
		*b = BLOB_NULL;
	}
}

int blob_pull_matching(blob_t *b, blob_t e)
{
	if (b->len < e.len)
		return 0;
	if (memcmp(b->ptr, e.ptr, e.len) != 0)
		return 0;
	b->ptr += e.len;
	b->len -= e.len;
	return 1;
}