Browse Source

implement base64_decode()

David Rose 21 years ago
parent
commit
448e2b73e8

+ 53 - 0
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

+ 1 - 0
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, 

+ 25 - 0
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);
+}

+ 3 - 0
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();