Skip to content

Commit

Permalink
[Code refactoring] - Base64 code clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanel committed Apr 20, 2024
1 parent 0fb1a1b commit 1770c8b
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions src/tech/include/base64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,35 @@

#include <algorithm>
#include <array>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <span>

#include "cct_string.hpp"

namespace cct {

namespace details {
inline void B64Encode(std::span<const char> binData, char *out, char *endOut) {
int bitsCollected = 0;
unsigned int accumulator = 0;
inline void B64EncodeImpl(std::span<const char> binData, char *out, char *endOut) {
int bitsCollected{};
uint32_t accumulator{};

static constexpr const char *const kB64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static constexpr const char kB64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static constexpr auto kB64NbBits = 6;
static constexpr decltype(accumulator) kMask6 = (1U << kB64NbBits) - 1U;

for (char ch : binData) {
accumulator = (accumulator << 8) | (ch & 0xFFU);
bitsCollected += 8;
while (bitsCollected >= 6) {
bitsCollected -= 6;
*out = kB64Table[(accumulator >> bitsCollected) & 0x3FU];
++out;
for (uint8_t ch : binData) {
accumulator = (accumulator << CHAR_BIT) | ch;
bitsCollected += CHAR_BIT;
while (bitsCollected >= kB64NbBits) {
bitsCollected -= kB64NbBits;
*out++ = kB64Table[(accumulator >> bitsCollected) & kMask6];
}
}
if (bitsCollected > 0) {
accumulator <<= 6 - bitsCollected;
*out = kB64Table[accumulator & 0x3FU];
++out;
accumulator <<= kB64NbBits - bitsCollected;
*out++ = kB64Table[accumulator & kMask6];
}

std::fill(out, endOut, '=');
Expand All @@ -39,26 +42,26 @@ constexpr auto B64EncodedLen(auto binDataLen) { return static_cast<std::size_t>(

[[nodiscard]] inline string B64Encode(std::span<const char> binData) {
string ret(details::B64EncodedLen(binData.size()), 0);
details::B64Encode(binData, ret.data(), ret.data() + ret.size());
details::B64EncodeImpl(binData, ret.data(), ret.data() + ret.size());
return ret;
}
string B64Encode(const char *) = delete;

template <std::size_t N>
[[nodiscard]] auto B64Encode(const char (&binData)[N]) {
std::array<char, details::B64EncodedLen(N)> ret;
details::B64Encode(binData, ret.data(), ret.data() + ret.size());
details::B64EncodeImpl(binData, ret.data(), ret.data() + ret.size());
return ret;
}

template <std::size_t N>
[[nodiscard]] auto B64Encode(const std::array<char, N> &binData) {
std::array<char, details::B64EncodedLen(N)> ret;
details::B64Encode(binData, ret.data(), ret.data() + ret.size());
details::B64EncodeImpl(binData, ret.data(), ret.data() + ret.size());
return ret;
}

[[nodiscard]] string B64Decode(std::span<const char> ascData);
string B64Decode(const char *) = delete;

} // namespace cct
} // namespace cct

0 comments on commit 1770c8b

Please sign in to comment.