1 // Copyright 2020 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
15 // Functions for encoding and decoding data in Base64 as specified by RFC 3548
16 // and RFC 4648. See https://tools.ietf.org/html/rfc4648
22 // C-compatible versions of a subset of the pw_base64 module.
27 // Returns the size of the given number of bytes when encoded as Base64. Base64
29 // Equivalent to pw::base64::EncodedSize().
30 #define PW_BASE64_ENCODED_SIZE(binary_size_bytes) \
31 (((size_t)binary_size_bytes + 2) / 3 * 4) // +2 to round up to a 3-byte group
33 // Encodes the provided data in Base64 and writes the result to the buffer.
34 // Exactly PW_BASE64_ENCODED_SIZE(binary_size_bytes) bytes will be written. The
35 // output buffer *MUST* be large enough for the encoded output!
37 // Equivalent to pw::base64::Encode().
38 void pw_Base64Encode(const void* binary_data,
39 const size_t binary_size_bytes,
42 // Evaluates to the maximum size of decoded Base64 data in bytes.
44 // Equivalent to pw::base64::MaxDecodedSize().
45 #define PW_BASE64_MAX_DECODED_SIZE(base64_size_bytes) \
46 (((size_t)base64_size_bytes) / 4 * 3)
48 // Decodes the provided Base64 data into raw binary. The output buffer *MUST* be
49 // at least PW_BASE64_MAX_DECODED_SIZE bytes large.
51 // Equivalent to pw::base64::Decode().
52 size_t pw_Base64Decode(const char* base64,
53 size_t base64_size_bytes,
56 // Returns true if the provided string is valid Base64 encoded data. Accepts
57 // either the standard (+/) or URL-safe (-_) alphabets.
59 // Equivalent to pw::base64::IsValid().
60 bool pw_Base64IsValid(const char* base64_data, size_t base64_size);
62 // C++ API, which uses the C functions internally.
67 #include <string_view>
68 #include <type_traits>
70 namespace pw::base64 {
72 // Returns the size of the given number of bytes when encoded as Base64. Base64
73 // encodes 3-byte groups into 4-character strings. The final group is padded to
74 // be 3-bytes if it only has 1 or 2.
75 constexpr size_t EncodedSize(size_t binary_size_bytes) {
76 return PW_BASE64_ENCODED_SIZE(binary_size_bytes);
79 // Encodes the provided data in Base64 and writes the result to the buffer.
80 // Encodes to the standard alphabet with + and / for characters 62 and 63.
81 // Exactly EncodedSize(binary_size_bytes) bytes will be written. The
82 // output buffer *MUST* be large enough for the encoded output! The input and
83 // output buffers MUST NOT be the same; encoding cannot occur in place.
85 // The resulting string in the output is NOT null-terminated!
86 inline void Encode(std::span<const std::byte> binary, char* output) {
87 pw_Base64Encode(binary.data(), binary.size_bytes(), output);
90 // Encodes the provided data in Base64 if the result fits in the provided
91 // buffer. Returns the number of bytes written, which will be 0 if the output
92 // buffer is too small.
93 size_t Encode(std::span<const std::byte> binary, std::span<char> output_buffer);
95 // Returns the maximum size of decoded Base64 data in bytes. base64_size_bytes
96 // must be a multiple of 4, since Base64 encodes 3-byte groups into 4-character
97 // strings. If the last 3-byte group has padding, the actual decoded size would
98 // be 1 or 2 bytes less than MaxDecodedSize.
99 constexpr size_t MaxDecodedSize(size_t base64_size_bytes) {
100 return PW_BASE64_MAX_DECODED_SIZE(base64_size_bytes);
103 // Decodes the provided Base64 data into raw binary. The output buffer *MUST* be
104 // at least MaxDecodedSize bytes large. The output buffer may be the same as the
105 // input buffer; decoding can occur in place. Returns the number of bytes that
108 // Decodes either standard (+/) or URL-safe (-_) alphabets. The data must be
109 // padded to 4-character blocks with =. This function does NOT check that the
110 // input is valid! Use IsValid or the four-argument overload to check the
112 inline size_t Decode(std::string_view base64, void* output) {
113 return pw_Base64Decode(base64.data(), base64.size(), output);
116 // Decodes the provided Base64 data, if the data is valid and fits in the output
117 // buffer. Returns the number of bytes written, which will be 0 if the data is
118 // invalid or doesn't fit.
119 size_t Decode(std::string_view base64, std::span<std::byte> output_buffer);
121 // Returns true if the provided string is valid Base64 encoded data. Accepts
122 // either the standard (+/) or URL-safe (-_) alphabets.
123 inline bool IsValid(std::string_view base64) {
124 return pw_Base64IsValid(base64.data(), base64.size());
127 } // namespace pw::base64
129 #endif // __cplusplus