From 448e2b73e8d3739189173a3dbfecf2e66fd57fa0 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 8 Dec 2004 23:01:15 +0000 Subject: [PATCH] implement base64_decode() --- panda/src/downloader/httpAuthorization.cxx | 53 ++++++++++++++++++++++ panda/src/downloader/httpAuthorization.h | 1 + panda/src/downloader/httpClient.I | 25 ++++++++++ panda/src/downloader/httpClient.h | 3 ++ 4 files changed, 82 insertions(+) diff --git a/panda/src/downloader/httpAuthorization.cxx b/panda/src/downloader/httpAuthorization.cxx index f8fca6c04f..4118878651 100644 --- a/panda/src/downloader/httpAuthorization.cxx +++ b/panda/src/downloader/httpAuthorization.cxx @@ -33,6 +33,9 @@ static const char base64_table[64] = { '4', '5', '6', '7', '8', '9', '+', '/', }; +static unsigned char base64_invert[128]; +static bool got_base64_invert = false; + //////////////////////////////////////////////////////////////////// // Function: HTTPAuthorization::Constructor // Access: Protected @@ -240,6 +243,56 @@ base64_encode(const string &s) { return result; } +//////////////////////////////////////////////////////////////////// +// Function: HTTPAuthorization::base64_decode +// Access: Public, Static +// Description: Returns the string decoded from base64. +//////////////////////////////////////////////////////////////////// +string HTTPAuthorization:: +base64_decode(const string &s) { + // Build up the invert table if this is the first time. + if (!got_base64_invert) { + int i; + for (i = 0; i < 128; i++) { + base64_invert[i] = 0xff; + } + + for (int i = 0; i < 64; i++) { + base64_invert[base64_table[i]] = i; + } + + base64_invert['='] = 0; + + got_base64_invert = true; + } + + // Collect the string 4 bytes at a time; decode this back into a + // 24-bit word and output the 3 corresponding bytes. + size_t num_words = s.size() / 4; + string result; + result.reserve(num_words * 3); + size_t p; + for (p = 0; p < s.size(); p += 4) { + unsigned int c0 = base64_invert[s[p] & 0x7f]; + unsigned int c1 = base64_invert[s[p + 1] & 0x7f]; + unsigned int c2 = base64_invert[s[p + 2] & 0x7f]; + unsigned int c3 = base64_invert[s[p + 3] & 0x7f]; + + unsigned int word = + (c0 << 18) | (c1 << 12) | (c2 << 6) | c3; + + result += (char)((word >> 16) & 0xff); + if (s[p + 2] != '=') { + result += (char)((word >> 8) & 0xff); + if (s[p + 3] != '=') { + result += (char)(word & 0xff); + } + } + } + + return result; +} + //////////////////////////////////////////////////////////////////// // Function: HTTPAuthorization::scan_quoted_or_unquoted_string // Access: Protected, Static diff --git a/panda/src/downloader/httpAuthorization.h b/panda/src/downloader/httpAuthorization.h index b80a4a5d37..ecc16409a4 100644 --- a/panda/src/downloader/httpAuthorization.h +++ b/panda/src/downloader/httpAuthorization.h @@ -67,6 +67,7 @@ public: const string &field_value); static URLSpec get_canonical_url(const URLSpec &url); static string base64_encode(const string &s); + static string base64_decode(const string &s); protected: static size_t scan_quoted_or_unquoted_string(string &result, diff --git a/panda/src/downloader/httpClient.I b/panda/src/downloader/httpClient.I index 6d08b30ca3..f30174f242 100644 --- a/panda/src/downloader/httpClient.I +++ b/panda/src/downloader/httpClient.I @@ -170,3 +170,28 @@ get_cipher_list() const { return _cipher_list; } +//////////////////////////////////////////////////////////////////// +// Function: HTTPClient::base64_encode +// Access: Published, Static +// Description: Implements HTTPAuthorization::base64_encode(). This +// is provided here just as a convenient place to +// publish it for access by the scripting language; C++ +// code should probably use HTTPAuthorization directly. +//////////////////////////////////////////////////////////////////// +INLINE string HTTPClient:: +base64_encode(const string &s) { + return HTTPAuthorization::base64_encode(s); +} + +//////////////////////////////////////////////////////////////////// +// Function: HTTPClient::base64_decode +// Access: Published, Static +// Description: Implements HTTPAuthorization::base64_decode(). This +// is provided here just as a convenient place to +// publish it for access by the scripting language; C++ +// code should probably use HTTPAuthorization directly. +//////////////////////////////////////////////////////////////////// +INLINE string HTTPClient:: +base64_decode(const string &s) { + return HTTPAuthorization::base64_decode(s); +} diff --git a/panda/src/downloader/httpClient.h b/panda/src/downloader/httpClient.h index d0ce047431..66d9b3e4e0 100644 --- a/panda/src/downloader/httpClient.h +++ b/panda/src/downloader/httpClient.h @@ -125,6 +125,9 @@ PUBLISHED: PT(HTTPChannel) get_document(const URLSpec &url); PT(HTTPChannel) get_header(const URLSpec &url); + INLINE static string base64_encode(const string &s); + INLINE static string base64_decode(const string &s); + public: SSL_CTX *get_ssl_ctx();