duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

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_ */