diff --git a/include/eepp/system.hpp b/include/eepp/system.hpp index 66238a653..34ed01319 100644 --- a/include/eepp/system.hpp +++ b/include/eepp/system.hpp @@ -24,5 +24,6 @@ #include #include #include +#include #endif diff --git a/include/eepp/system/base64.hpp b/include/eepp/system/base64.hpp new file mode 100644 index 000000000..bd05a1dc5 --- /dev/null +++ b/include/eepp/system/base64.hpp @@ -0,0 +1,43 @@ +#ifndef EE_SYSTEM_BASE64_HPP +#define EE_SYSTEM_BASE64_HPP + +#include +#include +#include +#include +#include + +namespace EE { namespace System { + +class EE_API Base64 { + public: + /** Encode binary data into base64 digits with MIME style === pads + ** @return The final length of the output */ + static int Encode( size_t in_len, const unsigned char *in, size_t out_len, char *out ); + + /** Decode base64 digits with MIME style === pads into binary data + ** @return The final length of the output */ + static int Decode( size_t in_len, const char *in, size_t out_len, unsigned char *out ); + + /** Encodes a string into a base64 string + ** @return True if encoding was successful */ + static bool Encode( const std::string& in, std::string& out ); + + /** Decodes a base64 string to a string + ** @return True if encoding was successful */ + static bool Decode( const std::string& in, std::string& out ); + + /** @return A safe encoding output length for an input of the length indicated */ + static inline int EncodeSafeOutLen( size_t in_len ) { + return in_len / 3 * 4 + 4 + 1; + } + + /** @return A safe decoding output length for an input of the length indicated */ + static inline int DecodeSafeOutLen( size_t in_len ) { + return in_len / 4 * 3 + 1; + } +}; + +}} + +#endif diff --git a/projects/linux/ee.files b/projects/linux/ee.files index a2340611f..4162364be 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -680,3 +680,5 @@ ../../src/eepp/window/backend/SDL2/wminfo.hpp ../../include/eepp/network/uri.hpp ../../src/eepp/network/uri.cpp +../../include/eepp/system/base64.hpp +../../src/eepp/system/base64.cpp diff --git a/src/eepp/system/base64.cpp b/src/eepp/system/base64.cpp new file mode 100644 index 000000000..224e8b683 --- /dev/null +++ b/src/eepp/system/base64.cpp @@ -0,0 +1,120 @@ +#include + +namespace EE { namespace System { + +/* base64.c : base-64 / MIME encode/decode */ +/* PUBLIC DOMAIN - Jon Mayo - November 13, 2003 */ +/* $Id: base64.c 156 2007-07-12 23:29:10Z orange $ */ + +/* decode a base64 string in one shot */ +int Base64::Decode(size_t in_len, const char *in, size_t out_len, unsigned char *out) { + static const Uint8 base64dec_tab[256] = { + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + }; + + unsigned ii, io; + Uint32 v; + unsigned rem; + + for(io=0,ii=0,v=0,rem=0;ii=8) { + rem-=8; + if(io>=out_len) return -1; /* truncation is failure */ + out[io++]=(v>>rem)&255; + } + } + if(rem>=8) { + rem-=8; + if(io>=out_len) return -1; /* truncation is failure */ + out[io++]=(v>>rem)&255; + } + return io; +} + +int Base64::Encode(size_t in_len, const unsigned char *in, size_t out_len, char *out) { + static const Uint8 base64enc_tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + unsigned ii, io; + Uint32 v; + unsigned rem; + + for(io=0,ii=0,v=0,rem=0;ii=6) { + rem-=6; + if(io>=out_len) return -1; /* truncation is failure */ + out[io++]=base64enc_tab[(v>>rem)&63]; + } + } + if(rem) { + v<<=(6-rem); + if(io>=out_len) return -1; /* truncation is failure */ + out[io++]=base64enc_tab[v&63]; + } + while(io&3) { + if(io>=out_len) return -1; /* truncation is failure */ + out[io++]='='; + } + if(io>=out_len) return -1; /* no room for null terminator */ + out[io]=0; + return io; +} + +bool Base64::Encode(const std::string & in, std::string & out) { + size_t b64len = EncodeSafeOutLen( in.size() ); + + if ( out.size() < b64len ) { + out.resize( b64len ); + } + + int len = Encode( in.size(), (const unsigned char*)in.c_str(), out.size(), (char*)&out[0] ); + + if ( -1 != len ) { + out.resize( len ); + } + + return -1 != len; +} + +bool Base64::Decode(const std::string & in, std::string & out) { + size_t d64len = DecodeSafeOutLen( in.size() ); + + if ( out.size() < d64len ) { + out.resize( d64len ); + } + + int len = Decode( in.size(), in.c_str(), out.size(), (unsigned char*)&out[0] ); + + if ( -1 != len && (size_t)len != d64len ) { + out.resize( len ); + } + + return -1 != len; +} + +}}