Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Source for quickdump plugin
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 1648 : static bool varintRead (FILE * file, kdb_unsigned_long_long_t * result)
11 : {
12 : kdb_octet_t varintBuf[9];
13 1648 : kdb_octet_t * varint = varintBuf;
14 :
15 1648 : int c = fgetc (file);
16 1648 : if (c == EOF)
17 : {
18 : return -1;
19 : }
20 :
21 1648 : varintBuf[0] = c;
22 :
23 1648 : unsigned int ctz = ffs (varint[0]);
24 : unsigned int len, cnt, i;
25 : kdb_unsigned_long_long_t num;
26 :
27 1648 : if (ctz == 0)
28 : {
29 : len = 8;
30 : cnt = 8;
31 : i = 0;
32 : }
33 : else
34 : {
35 1614 : len = ctz;
36 1614 : cnt = len - 1;
37 1614 : i = 1;
38 : }
39 :
40 :
41 1648 : if (fread (&varintBuf[1], sizeof (kdb_octet_t), cnt, file) < cnt)
42 : {
43 : return false;
44 : }
45 :
46 1648 : if (ctz == 0)
47 : {
48 : varint++;
49 : num = 0;
50 : }
51 : else
52 : {
53 1614 : num = varint[0] >> len;
54 : }
55 :
56 :
57 1086 : for (; i < len; ++i)
58 : {
59 1086 : unsigned int shift = i * 8u - ctz;
60 1086 : num |= (kdb_unsigned_long_long_t) varint[i] << shift;
61 : }
62 :
63 1648 : *result = num;
64 1648 : return true;
65 : }
66 :
67 1650 : static bool varintWrite (FILE * file, kdb_unsigned_long_long_t num)
68 : {
69 : kdb_octet_t varint[9];
70 :
71 1650 : unsigned int len = 64 - __builtin_clzll (num | 1u);
72 1650 : len = 1 + (len - 1) / 7;
73 :
74 1650 : if (len > 8)
75 : {
76 34 : len = 9;
77 34 : varint[0] = 0;
78 : }
79 : else
80 : {
81 1616 : num = ((num << 1u) | 1u) << (len - 1);
82 1616 : varint[0] = num & 0xFFu;
83 1616 : num >>= 8u;
84 : }
85 :
86 2736 : for (unsigned int i = 1; i < len; ++i)
87 : {
88 1086 : varint[i] = num & 0xFFu;
89 1086 : num >>= 8u;
90 : }
91 :
92 1650 : return fwrite (varint, sizeof (kdb_octet_t), len, file) == len;
93 : }
|