-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTLV.c
59 lines (55 loc) · 1.64 KB
/
TLV.c
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
#include "TLV.h"
#include "OK.h"
#include "PRO.h"
ok64 TLVinitshort($u8 tlv, u8 type, Bu8p stack) {
sane($ok(tlv) && Bok(stack) && TLVlong(type));
call(Bu8ppush, stack, &$head(tlv));
call($u8feed2, tlv, type | TLVaA, 0);
done;
}
ok64 TLVinitlong($u8 tlv, u8 type, Bu8p stack) {
sane($ok(tlv) && Bok(stack) && TLVlong(type));
call(Bu8ppush, stack, &$head(tlv));
u8 head[] = {type & ~TLVaA, 0, 0, 0, 0};
a$(u8c, h, head);
call($u8feedall, tlv, h);
done;
}
ok64 TLVendany($u8 tlv, u8 type, Bu8p stack) {
sane($ok(tlv) && Bok(stack) && !Bempty(stack) &&
*Btop(stack) + 2 <= $head(tlv));
u8* start = *Btop(stack);
size_t len = $head(tlv) - start;
if (TLVlong(*start)) {
test(len >= 4 + 1, FAILsanity);
len -= 4 + 1;
if (len < 0x100) {
$u8c from = {start + 1 + 4, tlv[0]};
$u8 into = {start + 1 + 1, tlv[0] - 4 + 1};
$u8move(into, from);
tlv[0] -= 4 - 1;
*start |= TLVaA;
*(start + 1) = (u8)len;
} else {
*(u32*)(start + 1) = len;
}
} else if (TLVshort(*start)) {
len -= 1 + 1;
if (len >= 0x100) {
test(len <= TLV_MAX_LEN, TLVtoolong);
test($len(tlv) >= 4 - 1, TLVnoroom);
$u8c from = {start + 1 + 1, tlv[0]};
$u8 into = {start + 1 + 4, tlv[0] + 4 - 1};
$u8move(into, from);
tlv[0] += 4 - 1;
*start &= ~TLVaA;
*(u32*)(start + 1) = len;
} else {
*(start + 1) = (u8)len;
}
} else {
fail(TLVbadrec);
}
Bu8ppop(stack);
done;
}