LCOV - code coverage report
Current view: top level - util - base64.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 94.1 % 34 32
Test Date: 2026-04-21 17:49:55 Functions: 100.0 % 4 4

            Line data    Source code
       1              : #ifndef THINGER_UTIL_BASE64_HPP
       2              : #define THINGER_UTIL_BASE64_HPP
       3              : 
       4              : #include <string>
       5              : #include <cstdint>
       6              : #include <array>
       7              : 
       8              : namespace thinger::util {
       9              : 
      10              : class base64 {
      11              : private:
      12              :     static constexpr const char encode_table[] =
      13              :         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      14              :         "abcdefghijklmnopqrstuvwxyz"
      15              :         "0123456789+/";
      16              : 
      17           14 :     static const std::array<uint8_t, 256>& get_decode_table() {
      18              :         static const auto table = [] {
      19              :             std::array<uint8_t, 256> t{};
      20              :             t.fill(0xFF);
      21              :             for (uint8_t i = 0; i < 64; ++i) {
      22              :                 t[static_cast<uint8_t>(encode_table[i])] = i;
      23              :             }
      24              :             return t;
      25              :         }();
      26           14 :         return table;
      27              :     }
      28              : 
      29              :     static bool is_base64(uint8_t c) {
      30              :         return get_decode_table()[c] != 0xFF;
      31              :     }
      32              : 
      33              : public:
      34           38 :     static std::string encode(const std::string& input) {
      35           38 :         return encode(reinterpret_cast<const unsigned char*>(input.data()), input.size());
      36              :     }
      37              : 
      38          114 :     static std::string encode(const unsigned char* data, size_t len) {
      39          114 :         std::string result;
      40          114 :         result.reserve(((len + 2) / 3) * 4);
      41              : 
      42          874 :         for (size_t i = 0; i < len; i += 3) {
      43          760 :             uint32_t n = static_cast<uint32_t>(data[i]) << 16;
      44          760 :             if (i + 1 < len) n |= static_cast<uint32_t>(data[i + 1]) << 8;
      45          760 :             if (i + 2 < len) n |= static_cast<uint32_t>(data[i + 2]);
      46              : 
      47          760 :             result += encode_table[(n >> 18) & 0x3F];
      48          760 :             result += encode_table[(n >> 12) & 0x3F];
      49          760 :             result += (i + 1 < len) ? encode_table[(n >> 6) & 0x3F] : '=';
      50          760 :             result += (i + 2 < len) ? encode_table[n & 0x3F] : '=';
      51              :         }
      52              : 
      53          114 :         return result;
      54            0 :     }
      55              : 
      56           14 :     static std::string decode(const std::string& input) {
      57           14 :         const auto& table = get_decode_table();
      58           14 :         std::string result;
      59           14 :         result.reserve(input.size() * 3 / 4);
      60              : 
      61           14 :         uint32_t buf = 0;
      62           14 :         int bits = 0;
      63              : 
      64          252 :         for (char c : input) {
      65          244 :             if (c == '=' || c == '\0') break;
      66              : 
      67          238 :             uint8_t val = table[static_cast<uint8_t>(c)];
      68          238 :             if (val == 0xFF) continue;
      69              : 
      70          238 :             buf = (buf << 6) | val;
      71          238 :             bits += 6;
      72              : 
      73          238 :             if (bits >= 8) {
      74          176 :                 bits -= 8;
      75          176 :                 result += static_cast<char>((buf >> bits) & 0xFF);
      76              :             }
      77              :         }
      78              : 
      79           14 :         return result;
      80            0 :     }
      81              : };
      82              : 
      83              : } // namespace thinger::util
      84              : 
      85              : #endif // THINGER_UTIL_BASE64_HPP
        

Generated by: LCOV version 2.0-1