base64.hpp (3833B)
1 #ifndef _C4_BASE64_HPP_ 2 #define _C4_BASE64_HPP_ 3 4 /** @file base64.hpp encoding/decoding for base64. 5 * @see https://en.wikipedia.org/wiki/Base64 6 * @see https://www.base64encode.org/ 7 * */ 8 9 #include "c4/charconv.hpp" 10 #include "c4/blob.hpp" 11 12 namespace c4 { 13 14 15 /** check that the given buffer is a valid base64 encoding 16 * @see https://en.wikipedia.org/wiki/Base64 */ 17 C4CORE_EXPORT bool base64_valid(csubstr encoded); 18 19 20 /** base64-encode binary data. 21 * @param encoded [out] output buffer for encoded data 22 * @param data [in] the input buffer with the binary data 23 * 24 * @return the number of bytes needed to return the output (ie the 25 * required size for @p encoded). No writes occur beyond the end of 26 * the output buffer, so it is safe to do a speculative call where the 27 * encoded buffer is empty, or maybe too small. The caller should 28 * ensure that the returned size is smaller than the size of the 29 * encoded buffer. 30 * 31 * @note the result depends on endianness. If transfer between 32 * little/big endian systems is desired, the caller should normalize 33 * @p data before encoding. 34 * 35 * @see https://en.wikipedia.org/wiki/Base64 */ 36 C4CORE_EXPORT size_t base64_encode(substr encoded, cblob data); 37 38 39 /** decode the base64 encoding in the given buffer 40 * @param encoded [in] the encoded base64 41 * @param data [out] the output buffer 42 * 43 * @return the number of bytes needed to return the output (ie the 44 * required size for @p data). No writes occur beyond the end of the 45 * output buffer, so it is safe to do a speculative call where the 46 * data buffer is empty, or maybe too small. The caller should ensure 47 * that the returned size is smaller than the size of the data buffer. 48 * 49 * @note the result depends on endianness. If transfer between 50 * little/big endian systems is desired, the caller should normalize 51 * @p data after decoding. 52 * 53 * @see https://en.wikipedia.org/wiki/Base64 */ 54 C4CORE_EXPORT size_t base64_decode(csubstr encoded, blob data); 55 56 57 namespace fmt { 58 59 template<typename CharOrConstChar> 60 struct base64_wrapper_ 61 { 62 blob_<CharOrConstChar> data; 63 base64_wrapper_() : data() {} 64 base64_wrapper_(blob_<CharOrConstChar> blob) : data(blob) {} 65 }; 66 /** a tag type to mark a payload as base64-encoded */ 67 using const_base64_wrapper = base64_wrapper_<cbyte>; 68 /** a tag type to mark a payload to be encoded as base64 */ 69 using base64_wrapper = base64_wrapper_<byte>; 70 71 72 /** mark a variable to be written in base64 format */ 73 template<class ...Args> 74 C4_ALWAYS_INLINE const_base64_wrapper cbase64(Args const& C4_RESTRICT ...args) 75 { 76 return const_base64_wrapper(cblob(args...)); 77 } 78 /** mark a csubstr to be written in base64 format */ 79 C4_ALWAYS_INLINE const_base64_wrapper cbase64(csubstr s) 80 { 81 return const_base64_wrapper(cblob(s.str, s.len)); 82 } 83 /** mark a variable to be written in base64 format */ 84 template<class ...Args> 85 C4_ALWAYS_INLINE const_base64_wrapper base64(Args const& C4_RESTRICT ...args) 86 { 87 return const_base64_wrapper(cblob(args...)); 88 } 89 /** mark a csubstr to be written in base64 format */ 90 C4_ALWAYS_INLINE const_base64_wrapper base64(csubstr s) 91 { 92 return const_base64_wrapper(cblob(s.str, s.len)); 93 } 94 95 /** mark a variable to be read in base64 format */ 96 template<class ...Args> 97 C4_ALWAYS_INLINE base64_wrapper base64(Args &... args) 98 { 99 return base64_wrapper(blob(args...)); 100 } 101 /** mark a variable to be read in base64 format */ 102 C4_ALWAYS_INLINE base64_wrapper base64(substr s) 103 { 104 return base64_wrapper(blob(s.str, s.len)); 105 } 106 107 } // namespace fmt 108 109 110 /** write a variable in base64 format */ 111 inline size_t to_chars(substr buf, fmt::const_base64_wrapper b) 112 { 113 return base64_encode(buf, b.data); 114 } 115 116 /** read a variable in base64 format */ 117 inline size_t from_chars(csubstr buf, fmt::base64_wrapper *b) 118 { 119 return base64_decode(buf, b->data); 120 } 121 122 } // namespace c4 123 124 #endif /* _C4_BASE64_HPP_ */