00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <cstdlib>
00011 #include <cstdio>
00012 #include <pion/PionAlgorithms.hpp>
00013 #include <boost/assert.hpp>
00014
00015 namespace pion {
00016
00017
00018 bool algo::base64_decode(const std::string &input, std::string &output)
00019 {
00020 static const char nop = -1;
00021 static const char decoding_data[] = {
00022 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00023 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00024 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop, 62, nop,nop,nop, 63,
00025 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,nop,nop, nop,nop,nop,nop,
00026 nop, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
00027 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,nop, nop,nop,nop,nop,
00028 nop,26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00029 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,nop, nop,nop,nop,nop,
00030 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00031 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00032 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00033 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00034 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00035 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00036 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
00037 nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop
00038 };
00039
00040 unsigned int input_length=input.size();
00041 const char * input_ptr = input.data();
00042
00043
00044 output.clear();
00045 output.reserve(((input_length+2)/3)*4);
00046
00047
00048
00049
00050 for (unsigned int i=0; i<input_length;i++) {
00051 char base64code0;
00052 char base64code1;
00053 char base64code2 = 0;
00054 char base64code3;
00055
00056 base64code0 = decoding_data[static_cast<int>(input_ptr[i])];
00057 if(base64code0==nop)
00058 return false;
00059 if(!(++i<input_length))
00060 return false;
00061 base64code1 = decoding_data[static_cast<int>(input_ptr[i])];
00062 if(base64code1==nop)
00063 return false;
00064
00065 output += ((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
00066
00067 if(++i<input_length) {
00068 char c = input_ptr[i];
00069 if(c =='=') {
00070 BOOST_ASSERT( (base64code1 & 0x0f)==0);
00071 return true;
00072 }
00073 base64code2 = decoding_data[static_cast<int>(input_ptr[i])];
00074 if(base64code2==nop)
00075 return false;
00076
00077 output += ((base64code1 << 4) & 0xf0) | ((base64code2 >> 2) & 0x0f);
00078 }
00079
00080 if(++i<input_length) {
00081 char c = input_ptr[i];
00082 if(c =='=') {
00083 BOOST_ASSERT( (base64code2 & 0x03)==0);
00084 return true;
00085 }
00086 base64code3 = decoding_data[static_cast<int>(input_ptr[i])];
00087 if(base64code3==nop)
00088 return false;
00089
00090 output += (((base64code2 << 6) & 0xc0) | base64code3 );
00091 }
00092
00093 }
00094
00095 return true;
00096 }
00097
00098 bool algo::base64_encode(const std::string &input, std::string &output)
00099 {
00100 static const char encoding_data[] =
00101 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00102
00103 unsigned int input_length=input.size();
00104 const char * input_ptr = input.data();
00105
00106
00107 output.clear();
00108 output.reserve(((input_length+2)/3)*4);
00109
00110
00111
00112
00113 for (unsigned int i=0; i<input_length;i++) {
00114 int base64code0=0;
00115 int base64code1=0;
00116 int base64code2=0;
00117 int base64code3=0;
00118
00119 base64code0 = (input_ptr[i] >> 2) & 0x3f;
00120 output += encoding_data[base64code0];
00121 base64code1 = (input_ptr[i] << 4 ) & 0x3f;
00122
00123 if (++i < input_length) {
00124 base64code1 |= (input_ptr[i] >> 4) & 0x0f;
00125 output += encoding_data[base64code1];
00126 base64code2 = (input_ptr[i] << 2) & 0x3f;
00127
00128 if (++i < input_length) {
00129 base64code2 |= (input_ptr[i] >> 6) & 0x03;
00130 base64code3 = input_ptr[i] & 0x3f;
00131 output += encoding_data[base64code2];
00132 output += encoding_data[base64code3];
00133 } else {
00134 output += encoding_data[base64code2];
00135 output += '=';
00136 }
00137 } else {
00138 output += encoding_data[base64code1];
00139 output += '=';
00140 output += '=';
00141 }
00142 }
00143
00144 return true;
00145 }
00146
00147 std::string algo::url_decode(const std::string& str)
00148 {
00149 char decode_buf[3];
00150 std::string result;
00151 result.reserve(str.size());
00152
00153 for (std::string::size_type pos = 0; pos < str.size(); ++pos) {
00154 switch(str[pos]) {
00155 case '+':
00156
00157 result += ' ';
00158 break;
00159 case '%':
00160
00161 if (pos + 2 < str.size()) {
00162 decode_buf[0] = str[++pos];
00163 decode_buf[1] = str[++pos];
00164 decode_buf[2] = '\0';
00165 result += static_cast<char>( strtol(decode_buf, 0, 16) );
00166 } else {
00167
00168 result += '%';
00169 }
00170 break;
00171 default:
00172
00173 result += str[pos];
00174 }
00175 };
00176
00177 return result;
00178 }
00179
00180 std::string algo::url_encode(const std::string& str)
00181 {
00182 char encode_buf[4];
00183 std::string result;
00184 encode_buf[0] = '%';
00185 result.reserve(str.size());
00186
00187
00188
00189
00190 for (std::string::size_type pos = 0; pos < str.size(); ++pos) {
00191 switch(str[pos]) {
00192 default:
00193 if (str[pos] > 32 && str[pos] < 127) {
00194
00195 result += str[pos];
00196 break;
00197 }
00198
00199 case ' ':
00200 case '$': case '&': case '+': case ',': case '/': case ':':
00201 case ';': case '=': case '?': case '@': case '"': case '<':
00202 case '>': case '#': case '%': case '{': case '}': case '|':
00203 case '\\': case '^': case '~': case '[': case ']': case '`':
00204
00205 sprintf(encode_buf+1, "%.2X", (unsigned char)(str[pos]));
00206 result += encode_buf;
00207 break;
00208 }
00209 };
00210
00211 return result;
00212 }
00213
00214 }