summaryrefslogtreecommitdiffstats
path: root/libmail/qp.C
diff options
context:
space:
mode:
Diffstat (limited to 'libmail/qp.C')
-rw-r--r--libmail/qp.C144
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