--- title: "Base64" --- {{< callout type="info">}} Headers: `base64.h` Common definitions `base64_encoder.h` Encoder classes `base64_decoder.h` Decoder classes From: `20.38.17` {{< /callout >}} Encodes and decodes data to and from Base64 format. The codecs are stream based. Data is fed in one element, or block of elements, at a time and the encoded or decoded result is written to the codec's internal output buffer. The result can be obtained in one of two ways: - If the internal buffer is large enough to hold the entire result, it can be read directly from the codec via `begin()`/`end()` or `span()`. - Otherwise a callback may be supplied that is called with a span of the output data each time the internal buffer becomes full, and once more with an empty span to signal that the final block has been processed. A separate codec class is supplied for each supported Base64 variant. ## Encoder The encoder classes are declared in `base64_encoder.h`. They all derive from `etl::ibase64_encoder`, which provides the interface described below. | Class | Variant | Padding | | :--- | :--- | :--- | | `etl::base64_rfc2152_encoder` | RFC-2152 | No | | `etl::base64_rfc3501_encoder` | RFC-3501 | No | | `etl::base64_rfc4648_encoder` | RFC-4648 | No | | `etl::base64_rfc4648_padding_encoder` | RFC-4648 | Yes | | `etl::base64_rfc4648_url_encoder` | RFC-4648-URL | No | | `etl::base64_rfc4648_url_padding_encoder` | RFC-4648-URL | Yes | ### Template parameters `Buffer_Size` The size of the internal output buffer, in characters. Defaults to `etl::base64::Min_Encode_Buffer_Size` (4). Must be a non-zero multiple of `etl::base64::Min_Encode_Buffer_Size`. ### Member types ```cpp typedef etl::span span_type; typedef etl::delegate callback_type; ``` ### Constructors ```cpp base64_rfcXXXX_encoder() ``` **Description** Constructs an encoder with no callback. The encoded result is read from the internal output buffer. --- ```cpp base64_rfcXXXX_encoder(callback_type callback) ``` **Description** Constructs an encoder with a callback. The callback is called with a span of the encoded data each time the internal buffer becomes full, and with an empty span once the final block has been flushed. ### Encoding ```cpp template bool encode(T value) ``` **Description** Encodes a single 8 bit value. Enabled if `etl::is_integral` is `true` and `etl::integral_limits::bits == 8`. **Return** `false` if the output buffer overflowed, otherwise `true`. --- ```cpp template bool encode(TInputIterator input_begin, size_t input_length) ``` **Description** Encodes `input_length` 8 bit values starting at `input_begin`. **Return** `false` if the output buffer overflowed, otherwise `true`. --- ```cpp template bool encode(TInputIterator input_begin, TInputIterator input_end) ``` **Description** Encodes the 8 bit values in the range `input_begin` to `input_end`. **Return** `false` if the output buffer overflowed, otherwise `true`. --- ```cpp template bool encode_final(TInputIterator input_begin, size_t input_length) ``` **Description** Encodes `input_length` 8 bit values starting at `input_begin`, then flushes the final block. Equivalent to `encode()` followed by `flush()`. **Return** `false` if the output buffer overflowed, otherwise `true`. --- ```cpp template bool encode_final(TInputIterator input_begin, TInputIterator input_end) ``` **Description** Encodes the 8 bit values in the range `input_begin` to `input_end`, then flushes the final block. Equivalent to `encode()` followed by `flush()`. **Return** `false` if the output buffer overflowed, otherwise `true`. --- ```cpp bool flush() ``` **Description** Encodes any remaining buffered input, including any required padding, and marks the end of the data. If a callback has been set it is called with any remaining data and then with an empty span. Must be called once all of the input has been passed to `encode()`. Not required when `encode_final()` is used. **Return** `false` if the output buffer overflowed, otherwise `true`. --- ```cpp void restart() ``` **Description** Resets the encoder so that it can be reused to encode a new set of data. ### Reading the result These functions return a useful value only when no callback has been set. The internal buffer must be large enough to hold the entire encoded result. ```cpp const char* begin() const const char* cbegin() const ``` **Return** A pointer to the beginning of the encoded data in the internal buffer. --- ```cpp const char* end() const const char* cend() const ``` **Return** A pointer to the end of the encoded data in the internal buffer. --- ```cpp size_t size() const ``` **Return** The number of encoded characters currently held in the internal buffer. --- ```cpp size_t max_size() const ``` **Return** The maximum size of the internal output buffer (`Buffer_Size`). --- ```cpp span_type span() const ``` **Return** A span over the encoded data in the internal buffer. ### Status ```cpp bool overflow() const ``` **Return** `true` if the output buffer has overflowed. --- ```cpp bool error() const ``` **Return** `true` if an error has been detected. For the encoder this is equivalent to `overflow()`. ### Static functions ```cpp static size_t safe_output_buffer_size(size_t input_length) ``` **Return** The internal buffer size required to encode `input_length` bytes in a single pass. Use this as the `Buffer_Size` template argument when the whole result is to be read from the internal buffer. ## Decoder The decoder classes are declared in `base64_decoder.h`. They all derive from `etl::ibase64_decoder`, which provides the interface described below. | Class | Variant | Padding | | :--- | :--- | :--- | | `etl::base64_rfc2152_decoder` | RFC-2152 | No | | `etl::base64_rfc3501_decoder` | RFC-3501 | No | | `etl::base64_rfc4648_decoder` | RFC-4648 | No | | `etl::base64_rfc4648_padding_decoder` | RFC-4648 | Yes | | `etl::base64_rfc4648_url_decoder` | RFC-4648-URL | No | | `etl::base64_rfc4648_url_padding_decoder` | RFC-4648-URL | Yes | ### Template parameters `Buffer_Size` The size of the internal output buffer, in bytes. Defaults to `etl::base64::Min_Decode_Buffer_Size` (3). Must be greater than or equal to `etl::base64::Min_Decode_Buffer_Size`. ### Member types ```cpp typedef etl::span span_type; typedef etl::delegate callback_type; ``` ### Constructors ```cpp base64_rfcXXXX_decoder() ``` **Description** Constructs a decoder with no callback. The decoded result is read from the internal output buffer. --- ```cpp base64_rfcXXXX_decoder(callback_type callback) ``` **Description** Constructs a decoder with a callback. The callback is called with a span of the decoded data each time the internal buffer becomes full, and with an empty span once the final block has been flushed. ### Decoding ```cpp template bool decode(T value) ``` **Description** Decodes a single Base64 character. Enabled if `etl::is_integral` is `true` and `etl::integral_limits::bits == 8`. **Return** `false` if an error was detected, otherwise `true`. --- ```cpp template bool decode(TInputIterator input_begin, TInputIterator input_end) ``` **Description** Decodes the Base64 characters in the range `input_begin` to `input_end`. **Return** `false` if an error was detected, otherwise `true`. --- ```cpp template bool decode(TInputIterator input_begin, size_t input_length) ``` **Description** Decodes `input_length` Base64 characters starting at `input_begin`. **Return** `false` if an error was detected, otherwise `true`. --- ```cpp template bool decode_final(TInputIterator input_begin, TInputIterator input_end) ``` **Description** Decodes the Base64 characters in the range `input_begin` to `input_end`, then flushes the final block. Equivalent to `decode()` followed by `flush()`. **Return** `false` if an error was detected, otherwise `true`. --- ```cpp template bool decode_final(TInputIterator input_begin, size_t input_length) ``` **Description** Decodes `input_length` Base64 characters starting at `input_begin`, then flushes the final block. Equivalent to `decode()` followed by `flush()`. **Return** `false` if an error was detected, otherwise `true`. --- ```cpp bool flush() ``` **Description** Decodes any remaining buffered input and marks the end of the data. If a callback has been set it is called with any remaining data and then with an empty span. Must be called once all of the input has been passed to `decode()`. Not required when `decode_final()` is used. **Return** `false` if an error was detected, otherwise `true`. --- ```cpp void restart() ``` **Description** Resets the decoder so that it can be reused to decode a new set of data. ### Reading the result These functions return a useful value only when no callback has been set. The internal buffer must be large enough to hold the entire decoded result. ```cpp const unsigned char* begin() const const unsigned char* cbegin() const ``` **Return** A pointer to the beginning of the decoded data in the internal buffer. --- ```cpp const unsigned char* end() const const unsigned char* cend() const ``` **Return** A pointer to the end of the decoded data in the internal buffer. --- ```cpp size_t size() const ``` **Return** The number of decoded bytes currently held in the internal buffer. --- ```cpp size_t buffer_size() const ``` **Return** The maximum size of the internal output buffer (`Buffer_Size`). --- ```cpp span_type span() const ``` **Return** A span over the decoded data in the internal buffer. ### Status ```cpp bool overflow() const ``` **Return** `true` if the output buffer has overflowed. --- ```cpp bool invalid_data() const ``` **Return** `true` if an invalid Base64 character was encountered. --- ```cpp bool error() const ``` **Return** `true` if an error has been detected. Equivalent to `overflow() || invalid_data()`. ### Static functions ```cpp static size_t safe_output_buffer_size(size_t input_length) ``` **Return** The internal buffer size required to decode `input_length` Base64 characters in a single pass. Use this as the `Buffer_Size` template argument when the whole result is to be read from the internal buffer. ## Examples ### Encode - reading the result from the internal buffer ```cpp // The data to encode. "Hello World!" constexpr size_t Input_Length = 12U; const etl::array input = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 }; // An encoder whose internal buffer is large enough to hold the entire result. using encoder_type = etl::base64_rfc4648_encoder::safe_output_buffer_size(Input_Length)>; encoder_type encoder; // Encode all of the input and flush the final block. encoder.encode_final(input.begin(), input.end()); // Copy the result out of the encoder's internal buffer. etl::string<16> encoded(encoder.begin(), encoder.end()); // encoded == "SGVsbG8gV29ybGQh" ``` --- ### Encode - streaming the result through a callback ```cpp etl::string<16> encoded; // Called with each chunk of encoded data as the internal buffer fills, // and finally with an empty span to signal the end of the data. auto append = [&encoded](const etl::span& chunk) { encoded.append(chunk.begin(), chunk.end()); }; etl::base64_rfc4648_encoder<>::callback_type callback = append; // A minimum size encoder that streams its output through the callback. etl::base64_rfc4648_encoder<> encoder(callback); encoder.encode_final(input.begin(), input.end()); // encoded == "SGVsbG8gV29ybGQh" ``` --- ### Decode - reading the result from the internal buffer ```cpp const etl::string<16> encoded = "SGVsbG8gV29ybGQh"; // A decoder whose internal buffer is large enough to hold the entire result. using decoder_type = etl::base64_rfc4648_decoder::safe_output_buffer_size(16U)>; decoder_type decoder; // Decode all of the input and flush the final block. decoder.decode_final(encoded.begin(), encoded.end()); // Copy the result out of the decoder's internal buffer. etl::vector output(decoder.begin(), decoder.end()); // output == { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, // 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 }; // "Hello World!" ```