File Coverage

src/panda/encode/base64.cc
Criterion Covered Total %
statement 41 43 95.3
branch 27 36 75.0
condition n/a
subroutine n/a
pod n/a
total 68 79 86.0


line stmt bran cond sub pod time code
1             #include
2             #include
3              
4             namespace panda { namespace encode {
5              
6             using std::int64_t;
7              
8             static const int EQ = 254; /* padding */
9             static const int XX = 255; /* illegal char */
10             static const int INVALID = XX;
11              
12             static const char basis64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13             static const char basis64url[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
14             static const unsigned char index64[256] = {
15             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
16             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
17             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,62,XX,63,
18             52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,EQ,XX,XX,
19             XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
20             15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,63,
21             XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
22             41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
23              
24             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
25             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
26             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
27             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
28             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
29             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
30             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
31             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
32             };
33              
34 4           size_t encode_base64 (const string_view source, char* dest, bool url_mode, bool use_pad) {
35 4           char* ptr = dest;
36 4 100         const char* basis = url_mode ? basis64url : basis64;
37 4           const char* str = source.data();
38              
39 267 100         for (int64_t len = source.length(); len > 0; len -= 3) {
40 263           unsigned char c1 = *str++;
41 263 100         unsigned char c2 = len > 1 ? *str++ : '\0';
42 263           *ptr++ = basis[c1>>2];
43 263           *ptr++ = basis[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
44 263 100         if (len > 2) {
45 260           unsigned char c3 = *str++;
46 260           *ptr++ = basis[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
47 260           *ptr++ = basis[c3 & 0x3F];
48 3 50         } else if (len == 2) {
49 0           *ptr++ = basis[(c2 & 0xF) << 2];
50 0 0         if (use_pad) *ptr++ = '=';
51 3 100         } else if (use_pad) {
52 1           *ptr++ = '=';
53 1           *ptr++ = '=';
54             }
55             }
56 4           return ptr - dest;
57             }
58              
59 4           size_t decode_base64 (const string_view source, char* dest) {
60 4           const unsigned char* str = (const unsigned char*)source.data();
61 4           const unsigned char* const end = str + source.length();
62 4           char* ptr = dest;
63              
64 264 100         while (str < end) {
65             unsigned char c[4];
66 263           int i = 0;
67 785           do {
68 1048           unsigned char uc = index64[*str++];
69 1048 50         if (uc != INVALID) c[i++] = uc;
70 1048 100         if (str == end) {
71 4 100         if (i < 4) {
72 5 50         if (i < 2) goto thats_it;
73 2 50         if (i == 2) c[2] = EQ;
74 2           c[3] = EQ;
75             }
76 4           break;
77             }
78 1044 100         } while (i < 4);
79              
80 263 50         if (c[0] == EQ || c[1] == EQ) break;
    50          
81 263           *ptr++ = (c[0] << 2) | ((c[1] & 0x30) >> 4);
82 263 100         if (c[2] == EQ) break;
83 260           *ptr++ = ((c[1] & 0x0F) << 4) | ((c[2] & 0x3C) >> 2);
84 260 50         if (c[3] == EQ) break;
85 260           *ptr++ = ((c[2] & 0x03) << 6) | c[3];
86             }
87              
88             thats_it:
89 4           return ptr - dest;
90             }
91              
92             }}