MCPcopy Create free account
hub / github.com/FastFlowLM/FastFlowLM / decode_into

Function decode_into

src/include/base64.hpp:566–678  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

564
565template <class OutputBuffer>
566inline OutputBuffer decode_into(std::string_view base64Text) {
567 typedef typename OutputBuffer::value_type output_value_type;
568 static_assert(std::is_same_v<output_value_type, char> ||
569 std::is_same_v<output_value_type, signed char> ||
570 std::is_same_v<output_value_type, unsigned char> ||
571 std::is_same_v<output_value_type, std::byte>);
572 if (base64Text.empty()) {
573 return OutputBuffer();
574 }
575
576 if ((base64Text.size() & 3) != 0) {
577 throw std::runtime_error{
578 "Invalid base64 encoded data - Size not divisible by 4"};
579 }
580
581 const size_t numPadding =
582 std::count(base64Text.rbegin(), base64Text.rbegin() + 4, '=');
583 if (numPadding > 2) {
584 throw std::runtime_error{
585 "Invalid base64 encoded data - Found more than 2 padding signs"};
586 }
587
588 const size_t decodedsize = (base64Text.size() * 3 >> 2) - numPadding;
589 OutputBuffer decoded(decodedsize, '.');
590
591 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&base64Text[0]);
592 char* currDecoding = reinterpret_cast<char*>(&decoded[0]);
593
594 for (size_t i = (base64Text.size() >> 2) - (numPadding != 0); i; --i) {
595 const uint8_t t1 = *bytes++;
596 const uint8_t t2 = *bytes++;
597 const uint8_t t3 = *bytes++;
598 const uint8_t t4 = *bytes++;
599
600 const uint32_t d1 = detail::decode_table_0[t1];
601 const uint32_t d2 = detail::decode_table_1[t2];
602 const uint32_t d3 = detail::decode_table_2[t3];
603 const uint32_t d4 = detail::decode_table_3[t4];
604
605 const uint32_t temp = d1 | d2 | d3 | d4;
606
607 if (temp >= detail::bad_char) {
608 throw std::runtime_error{
609 "Invalid base64 encoded data - Invalid character"};
610 }
611
612 // Use bit_cast instead of union and type punning to avoid
613 // undefined behaviour risk:
614 // https://en.wikipedia.org/wiki/Type_punning#Use_of_union
615 const std::array<char, 4> tempBytes =
616 detail::bit_cast<std::array<char, 4>, uint32_t>(temp);
617
618 *currDecoding++ = tempBytes[detail::decidx0];
619 *currDecoding++ = tempBytes[detail::decidx1];
620 *currDecoding++ = tempBytes[detail::decidx2];
621 }
622
623 switch (numPadding) {

Callers

nothing calls this directly

Calls 3

countFunction · 0.50
emptyMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected