inline void Base64Decode()

in GLTFSDK/Inc/GLTFSDK/ResourceReaderUtils.h [111:169]


        inline void Base64Decode(Base64StringView encodedData, Base64BufferView decodedData, size_t bytesToSkip)
        {
            if (encodedData.GetByteCount() != (decodedData.bufferByteLength + bytesToSkip))
            {
                throw GLTFException("The specified decode buffer's size is incorrect");
            }

            static const std::vector<uint8_t> decodeTable = GetDecodeTable();

            uint32_t block = 0U;
            uint32_t blockBits = 0U;

            uint8_t* decodedBytePtr = static_cast<uint8_t*>(decodedData.buffer);

            for (const auto encodedChar : encodedData)
            {
                // For platforms where char is unsigned (encodedChar < 0) results in a tautology warning.
                // Only do that test on platforms where char is signed.
                if ((std::numeric_limits<char>::is_signed && (static_cast<signed char>(encodedChar) < 0)) || (static_cast<size_t>(encodedChar) >= decodeTable.size()))
                {
                    throw GLTFException("Invalid base64 character");
                }

                const auto decodedChar = decodeTable[encodedChar];

                if (decodedChar == std::numeric_limits<uint8_t>::max())
                {
                    throw GLTFException("Invalid base64 character");
                }

                // Each character of a base64 string encodes 6 bits of data so left shift any remaining
                // bits to accomodate another character's worth of data before performing a bitwise OR
                block <<= 6U;
                block |= decodedChar & 0x3F;

                // Keep track of how many bits of the 'block' variable are currently used
                blockBits += 6U;

                // If there are 8 or more bits stored in 'block' then write a single byte to the output buffer
                if (blockBits >= 8U)
                {
                    blockBits -= 8U;

                    if (bytesToSkip > 0)
                    {
                        bytesToSkip--;
                    }
                    else
                    {
                        // Right shift the decoded data stored in 'block' so that the byte of
                        // data to be written to the output buffer occupies the low-order byte
                        *(decodedBytePtr++) = (block >> blockBits) & 0xFF;
                    }

                    // Generate a bitmask that discards only the byte just written to the output buffer during the bitwise AND
                    block &= (1 << blockBits) - 1;
                }
            }
        }