gloox 1.0

base64.cpp

00001 /*
00002   Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 #include "base64.h"
00015 
00016 namespace gloox
00017 {
00018 
00019   namespace Base64
00020   {
00021 
00022     static const std::string alphabet64( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );
00023     static const char pad = '=';
00024     static const char np  = (char)std::string::npos;
00025     static char table64vals[] =
00026     {
00027       62, np, np, np, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, np, np, np, np, np,
00028       np, np,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
00029       18, 19, 20, 21, 22, 23, 24, 25, np, np, np, np, np, np, 26, 27, 28, 29, 30, 31,
00030       32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
00031     };
00032 
00033     inline char table64( unsigned char c )
00034     {
00035       return ( c < 43 || c > 122 ) ? np : table64vals[c-43];
00036     }
00037 
00038     const std::string encode64( const std::string& input )
00039     {
00040       std::string encoded;
00041       char c;
00042       const std::string::size_type length = input.length();
00043 
00044       encoded.reserve( length * 2 );
00045 
00046       for( std::string::size_type i = 0; i < length; ++i )
00047       {
00048         c = static_cast<char>( ( input[i] >> 2 ) & 0x3f );
00049         encoded += alphabet64[c];
00050 
00051         c = static_cast<char>( ( input[i] << 4 ) & 0x3f );
00052         if( ++i < length )
00053           c = static_cast<char>( c | static_cast<char>( ( input[i] >> 4 ) & 0x0f ) );
00054         encoded += alphabet64[c];
00055 
00056         if( i < length )
00057         {
00058           c = static_cast<char>( ( input[i] << 2 ) & 0x3c );
00059           if( ++i < length )
00060             c = static_cast<char>( c | static_cast<char>( ( input[i] >> 6 ) & 0x03 ) );
00061           encoded += alphabet64[c];
00062         }
00063         else
00064         {
00065           ++i;
00066           encoded += pad;
00067         }
00068 
00069         if( i < length )
00070         {
00071           c = static_cast<char>( input[i] & 0x3f );
00072           encoded += alphabet64[c];
00073         }
00074         else
00075         {
00076           encoded += pad;
00077         }
00078       }
00079 
00080       return encoded;
00081     }
00082 
00083     const std::string decode64( const std::string& input )
00084     {
00085       char c, d;
00086       const std::string::size_type length = input.length();
00087       std::string decoded;
00088 
00089       decoded.reserve( length );
00090 
00091       for( std::string::size_type i = 0; i < length; ++i )
00092       {
00093         c = table64(input[i]);
00094         ++i;
00095         d = table64(input[i]);
00096         c = static_cast<char>( ( c << 2 ) | ( ( d >> 4 ) & 0x3 ) );
00097         decoded += c;
00098         if( ++i < length )
00099         {
00100           c = input[i];
00101           if( pad == c )
00102             break;
00103 
00104           c = table64(input[i]);
00105           d = static_cast<char>( ( ( d << 4 ) & 0xf0 ) | ( ( c >> 2 ) & 0xf ) );
00106           decoded += d;
00107         }
00108 
00109         if( ++i < length )
00110         {
00111           d = input[i];
00112           if( pad == d )
00113             break;
00114 
00115           d = table64(input[i]);
00116           c = static_cast<char>( ( ( c << 6 ) & 0xc0 ) | d );
00117           decoded += c;
00118         }
00119       }
00120 
00121       return decoded;
00122     }
00123 
00124   }
00125 
00126 }