11 #include <restinio/exception.hpp> 13 #include <restinio/utils/impl/bitops.hpp> 15 #include <fmt/format.h> 16 #include <fmt/ostream.h> 42 return 1 == is_base64_char_lut<
unsigned char >()[
43 static_cast<
unsigned char>(c) ];
49 auto throw_invalid_string = [&]{
51 fmt::format(
"invalid base64 string '{}'", str ) };
57 throw_invalid_string();
59 for(
const auto & ch : str )
61 if( !is_base64_char( ch ) && ch !=
'=' )
62 throw_invalid_string();
69 return static_cast<uint_type_t>(
static_cast<
unsigned char>(ch));
72 template<
unsigned int Shift>
84 const auto at = [&str](
auto index) {
return uch(str[index]); };
86 const auto alphabet_char = [](
auto ch) {
87 return static_cast<
char>(
88 base64_alphabet<
unsigned char >()[
89 static_cast<
unsigned char>(ch) ]);
92 constexpr std::size_t group_size = 3u;
93 const auto remaining = str.size() % group_size;
95 result.reserve( (str.size()/group_size + (remaining ? 1:0)) * 4 );
98 for(; i < str.size() - remaining; i += group_size )
100 uint_type_t bs = (at(i) << 16) | (at(i+1) << 8) | at(i+2);
102 result.push_back( alphabet_char( sixbits_char<18>(bs) ) );
103 result.push_back( alphabet_char( sixbits_char<12>(bs) ) );
104 result.push_back( alphabet_char( sixbits_char<6>(bs) ) );
105 result.push_back( alphabet_char( sixbits_char<0>(bs) ) );
115 ((at(i) << 16) | (at(i+1) << 8));
117 result.push_back( alphabet_char( sixbits_char<18>(bs) ) );
118 result.push_back( alphabet_char( sixbits_char<12>(bs) ) );
120 if( (bs >> 8) & 0xFFu )
121 result.push_back( alphabet_char( sixbits_char<6>(bs) ) );
123 result.push_back(
'=');
126 result.push_back( alphabet_char( sixbits_char<0>(bs) ) );
128 result.push_back(
'=');
137 constexpr std::size_t group_size = 4;
141 check_string_is_base64( str );
142 result.reserve( (str.size() / group_size) * 3 );
144 const unsigned char *
const decode_table = base64_decode_lut<
unsigned char >();
146 const auto at = [&str](
auto index) {
147 return static_cast<
unsigned char>(str[index]);
150 for( size_t i = 0 ; i < str.size(); i += group_size)
155 bs |= decode_table[ at(i) ];
157 bs |= decode_table[ at(i+1) ];
159 bs |= str[i+2] !=
'=' ? decode_table[ at(i+2) ] : 0;
161 bs |= str[i+3] !=
'=' ? decode_table[ at(i+3) ] : 0;
164 using ::restinio::utils::impl::bitops::n_bits_from;
166 result.push_back( n_bits_from<
char, 16 >(bs) );
167 const auto c2 = n_bits_from<
char, 8 >(bs);
169 result.push_back( c2 );
170 const auto c3 = n_bits_from<
char, 0 >(bs);
172 result.push_back( c3 );
char sixbits_char(uint_type_t bs)
string_view_t from_string< string_view_t >(string_view_t s)
Get a value from string_view.
std::string decode(string_view_t str)
void check_string_is_base64(string_view_t str)
bool is_base64_char(char c)
std::string encode(string_view_t str)
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...