File Coverage

base64.h
Criterion Covered Total %
statement 32 32 100.0
branch 17 26 65.3
condition n/a
subroutine n/a
pod n/a
total 49 58 84.4


line stmt bran cond sub pod time code
1             /*
2             * Base64 encoding function
3             *
4             * source: https://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64#C
5             *
6             */
7              
8             #ifndef BASE64_H
9             #define BASE64_H
10              
11             #include
12             #include
13              
14 11           int B64_encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize) {
15 11           const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
16 11           const uint8_t* data = (const uint8_t*)data_buf;
17 11           size_t resultIndex = 0;
18             size_t x;
19 11           uint32_t n = 0;
20 11           int padCount = dataLength % 3;
21             uint8_t n0, n1, n2, n3;
22              
23             /* increment over the length of the string, three characters at a time */
24 88 100         for (x = 0; x < dataLength; x += 3) {
25             /* these three 8-bit (ASCII) characters become one 24-bit number */
26 77           n = ((uint32_t)data[x]) << 16; // parenthesis needed, compiler depending on flags can do the
27             // shifting before conversion to uint32_t, resulting to 0
28              
29 77 50         if ((x + 1) < dataLength)
30 77           n += ((uint32_t)data[x + 1]) << 8; // parenthesis needed, compiler depending on flags can do
31             // the shifting before conversion to uint32_t, resulting
32             // to 0
33              
34 77 100         if ((x + 2) < dataLength) n += data[x + 2];
35              
36             /* this 24-bit number gets separated into four 6-bit numbers */
37 77           n0 = (uint8_t)(n >> 18) & 63;
38 77           n1 = (uint8_t)(n >> 12) & 63;
39 77           n2 = (uint8_t)(n >> 6) & 63;
40 77           n3 = (uint8_t)n & 63;
41              
42             /*
43             * if we have one byte available, then its encoding is spread
44             * out over two characters
45             */
46 77 50         if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */
47 77           result[resultIndex++] = base64chars[n0];
48 77 50         if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */
49 77           result[resultIndex++] = base64chars[n1];
50              
51             /*
52             * if we have only two bytes available, then their encoding is
53             * spread out over three chars
54             */
55 77 50         if ((x + 1) < dataLength) {
56 77 50         if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */
57 77           result[resultIndex++] = base64chars[n2];
58             }
59              
60             /*
61             * if we have all three bytes available, then their encoding is spread
62             * out over four characters
63             */
64 77 100         if ((x + 2) < dataLength) {
65 66 50         if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */
66 66           result[resultIndex++] = base64chars[n3];
67             }
68             }
69              
70             /*
71             * create and add padding that is required if we did not have a multiple of 3
72             * number of characters available
73             */
74 11 50         if (padCount > 0) {
75 22 100         for (; padCount < 3; padCount++) {
76 11 50         if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */
77 11           result[resultIndex++] = '=';
78             }
79             }
80 11 50         if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */
81 11           result[resultIndex] = 0;
82 11           return 0; /* indicate success */
83             }
84              
85             #endif /* BASE64_H */