-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcfc.c
66 lines (61 loc) · 1.62 KB
/
cfc.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
60
61
62
63
64
65
66
#include "cfc.h"
size_t cfc_count_bits(uint32_t i)
{
size_t result = 0;
while(i) {
++result;
i >>= 1;
}
return result;
}
void e(uint32_t k,bit_string_t *bs)
{
size_t len = cfc_count_bits(k);
//DEBUG_PRINT("e k %d len %zu cfc_count_bits(k) %d\n",k,len,cfc_count_bits(k));
while(--len) {
bit_string_append_bit(bs,0);
}
bit_string_append_bit(bs,1);
for(int i = cfc_count_bits(k) - 1; i >= 0; --i) {
bit_string_append_bit(bs, k >> i & 1);
}
}
uint32_t e_inv(bit_string_t *bs, size_t *offset)
{
uint32_t k = 0;
uint32_t tmp;
size_t len = bit_string_count_zeroes(bs,*offset) + 1;
if(len + *offset >= bs->offset)
return 0;
PRINT_DEBUG("e_inv offset %zu len %zu\n",*offset,len);
*offset += len;
for(int i = 0; i < len; ++i) {
tmp = bit_string_get_bit(bs, *offset);
k = tmp | (k << 1);
(*offset)++;
}
return k;
}
bit_string_t *cfc_encode(uint32_t l)
{
size_t l_len = cfc_count_bits(l);
bit_string_t *result = bit_string_init(cfc_count_bits(l_len) * 2 + l_len);
PRINT_DEBUG("cfc_encode l %d l_len %zu\n",l,l_len);
e(l_len,result);
for(int i = l_len - 1; i >= 0; --i) {
bit_string_append_bit(result, l >> i & 1);
}
return result;
}
size_t cfc_decode(bit_string_t *bs, size_t *offset)
{
uint32_t l = 0, tmp;
size_t l_len = e_inv(bs,offset);
for(int i = 0; i < l_len; ++i) {
tmp = bit_string_get_bit(bs,*offset);
l = tmp | (l << 1);
(*offset)++;
}
PRINT_DEBUG("cfc_decode offset %zu l %d l_len %zu\n",*offset - l_len,l,l_len);
return l;
}