summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2009-09-30 23:32:28 -0400
committerEliot Horowitz <eliot@10gen.com>2009-09-30 23:32:28 -0400
commitf7bfd1192ceea9a5fb0e9b62905a8145c0d12eb6 (patch)
treee7a3e319dbc1fdff82512f304be010cedf301890 /util
parentfdd776a50a43c1a25e6114632a5e7990920b7e4f (diff)
downloadmongo-f7bfd1192ceea9a5fb0e9b62905a8145c0d12eb6.tar.gz
base64 decode
Diffstat (limited to 'util')
-rw-r--r--util/base64.cpp81
-rw-r--r--util/base64.h7
2 files changed, 72 insertions, 16 deletions
diff --git a/util/base64.cpp b/util/base64.cpp
index 3a44745111f..15b9cbbc3d3 100644
--- a/util/base64.cpp
+++ b/util/base64.cpp
@@ -21,18 +21,38 @@
namespace mongo {
namespace base64 {
+
+ class Alphabet {
+ public:
+ Alphabet(){
+ encode =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "+/";
+
+ decode = (char*)malloc(257);
+ memset( decode , 0 , 256 );
+ for ( int i=0; i<64; i++ ){
+ decode[ encode[i] ] = i;
+ }
- const char * alphabet =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789"
- "+/";
+ test();
+ }
+ ~Alphabet(){
+ delete( decode );
+ }
- void testAlphabet(){
- assert( strlen( alphabet ) == 64 );
- for ( int i=0; i<26; i++ )
- assert( alphabet[i] == toupper( alphabet[i+26] ) );
- }
+ void test(){
+ assert( strlen( encode ) == 64 );
+ for ( int i=0; i<26; i++ )
+ assert( encode[i] == toupper( encode[i+26] ) );
+ }
+
+
+ const char * encode;
+ char * decode;
+ } alphabet;
void encode( stringstream& ss , const char * data , int size ){
@@ -41,28 +61,28 @@ namespace mongo {
const char * start = data + i;
// byte 0
- ss << alphabet[start[0]>>2];
+ ss << alphabet.encode[start[0]>>2];
// byte 1
char temp = ( start[0] & 0x3 ) << 4;
if ( left == 1 ){
- ss << alphabet[temp];
+ ss << alphabet.encode[temp];
break;
}
temp |= start[1] >> 4;
- ss << alphabet[temp];
+ ss << alphabet.encode[temp];
// byte 2
temp = ( start[1] & 0xF ) << 2;
if ( left == 2 ){
- ss << alphabet[temp];
+ ss << alphabet.encode[temp];
break;
}
temp |= start[2] >> 6;
- ss << alphabet[temp];
+ ss << alphabet.encode[temp];
// byte 3
- ss << alphabet[start[2] & 0x3f];
+ ss << alphabet.encode[start[2] & 0x3f];
}
int mod = size % 3;
@@ -80,6 +100,35 @@ namespace mongo {
encode( ss , data ,size );
return ss.str();
}
+
+ string encode( const string& s ){
+ return encode( s.c_str() , s.size() );
+ }
+
+
+ void decode( stringstream& ss , const string& s ){
+ uassert( "invalid base64" , s.size() % 4 == 0 );
+ const char * data = s.c_str();
+ int size = s.size();
+
+ char buf[4];
+ buf[3] = 0;
+ for ( int i=0; i<size; i+=4){
+ memset( buf , 0 , 4 );
+ const char * start = data + i;
+ buf[0] = ( alphabet.decode[start[0]] << 2 ) | ( alphabet.decode[start[1]] >> 4 );
+ buf[1] = ( alphabet.decode[start[1]] << 4 ) | ( alphabet.decode[start[2]] >> 2 );
+ buf[2] = ( alphabet.decode[start[2]] << 6 ) | ( alphabet.decode[start[3]] );
+
+ ss << buf;
+ }
+ }
+
+ string decode( const string& s ){
+ stringstream ss;
+ decode( ss , s );
+ return ss.str();
+ }
}
}
diff --git a/util/base64.h b/util/base64.h
index 416b2ce9502..305e45af1c8 100644
--- a/util/base64.h
+++ b/util/base64.h
@@ -20,8 +20,15 @@
namespace mongo {
namespace base64 {
+
void encode( stringstream& ss , void * data , int size );
string encode( const char * data , int size );
+ string encode( const string& s );
+
+ void decode( stringstream& ss , const string& s );
+ string decode( const string& s );
+
+
void testAlphabet();
}
}