1 /* 2 ** Copyright 2002-2009, Double Precision Inc. 3 ** 4 ** See COPYING for distribution information. 5 */ 6 #include "libmail_config.h" 7 8 #include "qp.H" 9 10 #include <string.h> 11 12 using namespace std; 13 xdigit(char c)14static inline int xdigit(char c) 15 { 16 static const char xdigits[]="0123456789ABCDEFabcdef"; 17 18 const char *p=strchr(xdigits, c); 19 20 if (p == NULL) 21 return -1; 22 23 int n= p - xdigits; 24 25 if (n >= 16) 26 n -= 6; 27 return n; 28 } 29 decodeqp()30mail::decodeqp::decodeqp() 31 : decodeBuffer("") 32 { 33 } 34 ~decodeqp()35mail::decodeqp::~decodeqp() 36 { 37 } 38 decode(string text)39void mail::decodeqp::decode(string text) 40 { 41 string decodedString=""; 42 43 text=decodeBuffer + text; 44 45 // Just decode as much as possible, and leave the rest for next time. 46 47 string::iterator b=text.begin(), e=text.end(), c=b; 48 49 while (b != e) 50 { 51 // Look for the next = 52 53 for (c=b; c != e; c++) 54 if (*c == '=') 55 break; 56 57 decodedString += string(b, c); 58 59 if (c == e) // Got everything. 60 { 61 b=c; 62 break; 63 } 64 65 b=c++; 66 67 if (c == e) 68 break; 69 70 if (*c == '\r') 71 c++; 72 73 if (c == e) 74 break; 75 76 if (*c == '\n') 77 { 78 c++; 79 b=c; 80 continue; 81 } 82 83 int a1=xdigit(*c++); 84 85 if (a1 < 0) 86 { 87 b=c; 88 continue; 89 } 90 91 if (c == e) 92 break; 93 94 int a2=xdigit(*c++); 95 96 if (a2 < 0) 97 { 98 b=c; 99 continue; 100 } 101 102 decodedString += (char)(a1 * 16 + a2); 103 104 b=c; 105 } 106 107 decodeBuffer=string(b, e); // Leftovers 108 109 decoded(decodedString); 110 } 111 112 #if 0 113 114 class testqp : public mail::decodeqp { 115 116 void decoded(string buffer) 117 { 118 cout << buffer; 119 } 120 }; 121 122 int main(int argc, char **argv) 123 { 124 testqp qp; 125 126 int argn; 127 128 for (argn=1; argn < argc; argn++) 129 { 130 string s=argv[argn]; 131 132 size_t p; 133 134 while ((p=s.find('~')) != std::string::npos) 135 s[p]='\n'; 136 137 qp.decode(s); 138 } 139 140 cout << endl; 141 142 return (0); 143 } 144 #endif 145