#pragma once namespace saw { namespace encode { struct Base64 {}; } template<> class data { public: using Schema = schema::String; private: std::string data_; public: data() = default; data(std::string data__): data_{std::move(data__)} {} uint64_t size() const { return data_.size(); } char& at(uint64_t i){ return data_.at(i); } const char& at(uint64_t i) const { return data_.at(i); } std::string stl_string() const { return data_; } bool operator==(const data& rhs) const { return data_ == rhs.data_; } }; namespace impl { constexpr char base64_char_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; } template<> class codec { public: using Schema = schema::String; private: public: template static error_or encode(const data& from, data& to){ std::string b64_str; try { uint64_t unpadded_len = (from.size() * 4u + 2u) / 3u; uint64_t padded_len = ( unpadded_len + 3u ) & ~3u; b64_str.resize(padded_len); }catch(const std::exception&){ return make_error(); } uint64_t j{0u}, k{0u}; std::array s{}; for(uint64_t i = 0u; i < from.size(); ++i){ s[j] = from.at(i); ++j; if(j==3){ b64_str.at(k) = impl::base64_char_map[(s[0u] & 0xFC) >> 2]; b64_str.at(k+1u) = impl::base64_char_map[((s[0u] & 0x03) << 4) | ((s[1] & 0xF0) >> 4)]; b64_str.at(k+2u) = impl::base64_char_map[((s[1u] & 0x0F) << 2) | ((s[2] & 0xC0) >> 6)]; b64_str.at(k+3u) = impl::base64_char_map[(s[2u] & 0x3F)]; j = 0u; k+=4u; } } if(j > 0){ if( j == 1u ){ s[1u] = 0u; } b64_str.at(k+0u) = impl::base64_char_map[(s[0u] & 0xFF) >> 2]; b64_str.at(k+1u) = impl::base64_char_map[((s[0u] & 0x03)<<4) + ((s[1u]&0xF0)>>4)]; if(j == 2u){ b64_str[k+2u] = impl::base64_char_map[ ((s[1u]&0x0F)<<2) ]; }else { b64_str[k+2u] = '='; } b64_str[k+3u] = '='; } to = {std::move(b64_str)}; return void_t{}; } template static error_or decode(data& from, data& to){ return make_error(); /* uint64_t b64_len = from.size(); if((b64_len % 4) != 0){ return make_error("B64 is not padded"); } uint64_t section_len = b64_len / 4u; std::string to_str; for(uint64_t i = 0u; i < section_len; ++i){ uint64_t j = 4u*i; std::array to_bits{0,0,0}; std::array from_bits{ from.at(j).get(), from.at(j+1u).get(), from.at(j+2u).get(), from.at(j+3u).get() }; for(char iter : from_bits){ if(!is_base64(iter)){ return make_error("Not a base64 char"); } } to_bits[0] = char_array } to = {std::move(to_str)}; return saw::make_void(); */ } }; }