From 7049fc0af8bd2a8484963c0805ae82a1bcc470b6 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 16 May 2016 19:56:23 +0200 Subject: [PATCH] Base64 encoder and decoder upgraded to operate with any string now --- include/WinStd/Base64.h | 69 ++++++++++++++++++++++++++++++++++++----- src/Base64.cpp | 57 ---------------------------------- 2 files changed, 62 insertions(+), 64 deletions(-) diff --git a/include/WinStd/Base64.h b/include/WinStd/Base64.h index 0724a201..5a0f45fe 100644 --- a/include/WinStd/Base64.h +++ b/include/WinStd/Base64.h @@ -40,18 +40,46 @@ namespace winstd class base64_enc { public: - base64_enc() : num(0) {}; + inline base64_enc() : num(0) {}; /// - /// Encodes one block of information + /// Encodes one block of information, and _appends_ it to the output /// /// \param[out] out Output /// \param[in ] data Data to encode /// \param[in ] size Length of `data` in bytes /// \param[in ] is_last Is this the last block of data? /// - void encode(_Out_ std::string &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true); + template + inline void encode(_Out_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true) + { + assert(data || !size); + + size_t i = 0, j = 0; + + // Convert data character by character. + for (;;) { + if (num >= 3) { + encode(out, buf); + num = 0; + j += 4; + } + + if (i >= size) + break; + + buf[num++] = ((unsigned char*)data)[i++]; + } + + // If this is the last block, flush the buffer. + if (is_last && num) { + encode(out, buf, num); + num = 0; + j += 4; + } + } + /// @@ -77,7 +105,8 @@ namespace winstd protected: - static inline void encode(_Inout_ std::string &out, _In_ const unsigned char buf[3]) + template + static inline void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_ const unsigned char buf[3]) { out += lookup[ buf[0] >> 2 ]; out += lookup[((buf[0] << 4) | (buf[1] >> 4)) & 0x3f]; @@ -86,7 +115,8 @@ namespace winstd } - static inline void encode(_Inout_ std::string &out, _In_count_(size) const unsigned char buf[3], _In_ size_t size) + template + static inline void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_count_(size) const unsigned char buf[3], _In_ size_t size) { if (size > 0) { out += lookup[buf[0] >> 2]; @@ -126,14 +156,39 @@ namespace winstd /// - /// Decodes one block of information + /// Decodes one block of information, and _appends_ it to the output /// /// \param[out] out Output /// \param[in ] data Data to decode /// \param[in ] size Length of `data` in bytes /// \param[in ] is_last Was this the last block of data? /// - void decode(_Out_ std::vector &out, _Out_ bool &is_last, _In_z_count_(size) const char *data, _In_ size_t size); + template + inline void decode(_Out_ std::vector &out, _Out_ bool &is_last, _In_z_count_(size) const T *data, _In_ size_t size) + { + size_t i = 0, j = 0, nibbles; + + is_last = false; + + for (;;) { + if (num >= 4) { + // Buffer full; decode it. + nibbles = decode(out, buf); + j += nibbles; + num = 0; + if (nibbles < 3) { + is_last = true; + break; + } + } + + if (i >= size || !data[i]) + break; + + if ((buf[num] = lookup[(unsigned char)data[i++]]) != 255) + num++; + } + } /// diff --git a/src/Base64.cpp b/src/Base64.cpp index 4c3c07fe..e0463f48 100644 --- a/src/Base64.cpp +++ b/src/Base64.cpp @@ -33,35 +33,6 @@ const char winstd::base64_enc::lookup[64] = { }; -void winstd::base64_enc::encode(_Out_ std::string &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last) -{ - assert(data || !size); - - size_t i = 0, j = 0; - - // Convert data character by character. - for (;;) { - if (num >= 3) { - encode(out, buf); - num = 0; - j += 4; - } - - if (i >= size) - break; - - buf[num++] = ((unsigned char*)data)[i++]; - } - - // If this is the last block, flush the buffer. - if (is_last && num) { - encode(out, buf, num); - num = 0; - j += 4; - } -} - - ////////////////////////////////////////////////////////////////////// // winstd::base64_dec ////////////////////////////////////////////////////////////////////// @@ -85,31 +56,3 @@ const unsigned char winstd::base64_dec::lookup[256] = { /* E */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, /* F */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; - - -void winstd::base64_dec::decode(_Out_ std::vector &out, _Out_ bool &is_last, _In_z_count_(size) const char *data, _In_ size_t size) -{ - size_t i = 0, j = 0; - size_t nibbles; - - is_last = false; - - for (;;) { - if (num >= 4) { - // Buffer full; decode it. - nibbles = decode(out, buf); - j += nibbles; - num = 0; - if (nibbles < 3) { - is_last = true; - break; - } - } - - if (i >= size || !data[i]) - break; - - if ((buf[num] = lookup[(unsigned char)data[i++]]) != 255) - num++; - } -}