| 78 | */ |
| 79 | template<typename Input_iterator, typename Output_iterator> |
| 80 | static Output_iterator encode(Input_iterator in_begin, Input_iterator in_end, Output_iterator out, |
| 81 | alphabet alphabet = alphabet::standard) |
| 82 | { |
| 83 | constexpr auto pad = '='; |
| 84 | const char* alpha = alphabet == alphabet::url_filename_safe |
| 85 | ? "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" |
| 86 | : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 87 | |
| 88 | while (in_begin != in_end) { |
| 89 | std::uint8_t i0 = 0, i1 = 0, i2 = 0; |
| 90 | |
| 91 | // first character |
| 92 | i0 = static_cast<std::uint8_t>(*in_begin); |
| 93 | ++in_begin; |
| 94 | |
| 95 | *out = alpha[i0 >> 2 & 0x3f]; |
| 96 | ++out; |
| 97 | |
| 98 | // part of first character and second |
| 99 | if (in_begin != in_end) { |
| 100 | i1 = static_cast<std::uint8_t>(*in_begin); |
| 101 | ++in_begin; |
| 102 | |
| 103 | *out = alpha[((i0 & 0x3) << 4) | (i1 >> 4 & 0x0f)]; |
| 104 | ++out; |
| 105 | } else { |
| 106 | *out = alpha[(i0 & 0x3) << 4]; |
| 107 | ++out; |
| 108 | |
| 109 | // last padding |
| 110 | *out = pad; |
| 111 | ++out; |
| 112 | |
| 113 | // last padding |
| 114 | *out = pad; |
| 115 | ++out; |
| 116 | |
| 117 | break; |
| 118 | } |
| 119 | |
| 120 | // part of second character and third |
| 121 | if (in_begin != in_end) { |
| 122 | i2 = static_cast<std::uint8_t>(*in_begin); |
| 123 | ++in_begin; |
| 124 | |
| 125 | *out = alpha[((i1 & 0xf) << 2) | (i2 >> 6 & 0x03)]; |
| 126 | ++out; |
| 127 | } else { |
| 128 | *out = alpha[(i1 & 0xf) << 2]; |
| 129 | ++out; |
| 130 | |
| 131 | // last padding |
| 132 | *out = pad; |
| 133 | ++out; |
| 134 | |
| 135 | break; |
| 136 | } |
| 137 |
no test coverage detected