diff options
Diffstat (limited to 'libmail/qp.C')
| -rw-r--r-- | libmail/qp.C | 144 | 
1 files changed, 144 insertions, 0 deletions
| diff --git a/libmail/qp.C b/libmail/qp.C new file mode 100644 index 0000000..0d30a45 --- /dev/null +++ b/libmail/qp.C @@ -0,0 +1,144 @@ +/* +** Copyright 2002-2009, Double Precision Inc. +** +** See COPYING for distribution information. +*/ +#include "libmail_config.h" + +#include "qp.H" + +#include <string.h> + +using namespace std; + +static inline int xdigit(char c) +{ +	static const char xdigits[]="0123456789ABCDEFabcdef"; + +	const char *p=strchr(xdigits, c); + +	if (p == NULL) +		return -1; + +	int n= p - xdigits; + +	if (n >= 16) +		n -= 6; +	return n; +} + +mail::decodeqp::decodeqp() +	: decodeBuffer("") +{ +} + +mail::decodeqp::~decodeqp() +{ +} + +void mail::decodeqp::decode(string text) +{ +	string decodedString=""; + +	text=decodeBuffer + text; + +	// Just decode as much as possible, and leave the rest for next time. + +	string::iterator b=text.begin(), e=text.end(), c=b; + +	while (b != e) +	{ +		// Look for the next = + +		for (c=b; c != e; c++) +			if (*c == '=') +				break; + +		decodedString += string(b, c); + +		if (c == e) // Got everything. +		{ +			b=c; +			break; +		} + +		b=c++; + +		if (c == e) +			break; + +		if (*c == '\r') +			c++; + +		if (c == e) +			break; + +		if (*c == '\n') +		{ +			c++; +			b=c; +			continue; +		} + +		int a1=xdigit(*c++); + +		if (a1 < 0) +		{ +			b=c; +			continue; +		} + +		if (c == e) +			break; + +		int a2=xdigit(*c++); + +		if (a2 < 0) +		{ +			b=c; +			continue; +		} + +		decodedString += (char)(a1 * 16 + a2); + +		b=c; +	} + +	decodeBuffer=string(b, e); // Leftovers + +	decoded(decodedString); +} + +#if 0 + +class testqp : public mail::decodeqp { + +	void decoded(string buffer) +	{ +		cout << buffer; +	} +}; + +int main(int argc, char **argv) +{ +	testqp qp; + +	int argn; + +	for (argn=1; argn < argc; argn++) +	{ +		string s=argv[argn]; + +		size_t p; + +		while ((p=s.find('~')) != std::string::npos) +			s[p]='\n'; + +		qp.decode(s); +	} + +	cout << endl; + +	return (0); +} +#endif | 
