summaryrefslogtreecommitdiff
path: root/src/mime/qp.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/mime/qp.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/mime/qp.cc')
-rw-r--r--src/mime/qp.cc150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/mime/qp.cc b/src/mime/qp.cc
new file mode 100644
index 0000000..78dc36f
--- /dev/null
+++ b/src/mime/qp.cc
@@ -0,0 +1,150 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mime/enc.h>
21#include <mime/pack.h>
22#include <algorithm>
23
24const charset special("=\"#$\\^`{|}~");
25//const charset special("=!\"#$@[\\]^`{|}~");
26const charset headspecial("_?");
27const charset printable=cset_printable&~special;
28const charset printhead=printable&~headspecial;
29const mstring beg_tag("=?"),end_tag("?=");
30const mstring enc_qp_tag("Q"),enc_64_tag("B");
31const int WRAPAT=76;
32const int HEADWRAP=WRAPAT-7;
33
34void decodeQP(mstream& out,const sref& in)
35{
36 const char* p=in.begin();
37 while(p<in.end()) {
38 unsigned char c=*p++;
39 if(c=='=') {
40 if(cset_ws.test(*p)) p=in(p).past_nl().data();
41 else {
42 unsigned char c1=*p++,c2=*p++;
43 out.put(hexasc(c1,c2));
44 }
45 }
46 else out.put(c);
47 }
48}
49
50void encodeQP(mstream& out,const sref& in)
51{
52 sref first,rest=in;
53 while(Splitln(first,rest)) {
54 int n=0;
55 const char* p=first.begin();
56 while(p<first.end()) {
57 unsigned char c=*p++;
58 if(printable.test(c)) {
59 if(first(p).empty()&&cset_spaces.test(c)) { cashex(out.put('='),c); n+=3; }
60 else { out.put(c); n++; }
61 }
62 else { cashex(out.put('='),c); n+=3; }
63 if(first(p).nempty()&&n>=WRAPAT) { out.put('=')<<CRLF; n=0; }
64 }
65 out<<CRLF;
66 }
67}
68
69static void decodeHQ(mstream& out,const sref& in)
70{
71 const char* p=in.begin();
72 while(p<in.end()) {
73 unsigned char c=*p++;
74 if(c=='=') {
75 unsigned char c1=*p++,c2=*p++;
76 out.put(hexasc(c1,c2));
77 }
78 else if(c=='_') out.put(' ');
79 else out.put(c);
80 }
81}
82
83static int encodeHQ(mstream& out,const sref& in)
84{
85 int enc=0;
86 const char* p=in.begin();
87 while(p<in.end()) {
88 unsigned char c=*p++;
89 if(!printable.test(c)) enc=1;
90 if(printhead.test(c)) { if(c==32) out.put('_'); else out.put(c); }
91 else cashex(out.put('='),c);
92 }
93 return enc;
94}
95
96void decodeHeader(mstream& out,mstring& mime,const sref& in)
97{
98 sref e,p=in;
99 while(p.nempty()) {
100 p=p.adv(e=p.left_first(beg_tag));
101 out<<e;
102 if(p.nempty()) {
103 p=p.adv(beg_tag.size());
104 mime=p.left_first('?');
105 p=p.adv(mime.size());
106 if(p.empty()) { out<<beg_tag<<mime; p.clear(); }
107 else {
108 p=p.popf();
109 sref enc=p.left_first('?');
110 p=p.adv(enc);
111 if(p.empty()) { out<<beg_tag<<mime<<"?"<<enc; p.clear(); }
112 else {
113 p=p.adv(e=p.popf().left_first(end_tag));
114 if(p.empty()) { out<<beg_tag<<mime<<"?"<<enc<<"?"<<e; p.clear(); }
115 else {
116 p=p.adv(end_tag.size());
117 if(eqn(enc,enc_qp_tag)) decodeHQ(out,e);
118 else if(eqn(enc,enc_64_tag)) decode64(out,e);
119 else out<<"BAD: ["<<mime<<"]["<<enc<<"]["<<e<<"]";
120 }
121 }
122 }
123 }
124 }
125}
126
127void encodeHeader(mstream& out,const sref& mime,const sref& in)
128{
129 mstring tmp;
130 swrite sw(tmp);
131 if(encodeHQ(sw,in)) {
132 int wrapat=HEADWRAP-mime.size();
133 sref e,p=tmp;
134 p=p.adv(e=p.left(std::min(wrapat,p.size())));
135 out<<beg_tag<<mime<<"?Q?"<<e<<end_tag;
136 while(p.nempty()) {
137 p=p.adv(e=p.left(std::min(wrapat,p.size())));
138 out<<"\r\n\t"<<beg_tag<<mime<<"?Q?"<<e<<end_tag;
139 }
140 }
141 else {
142 sref e,p=in;
143 p=p.adv(e=p.left(std::min(WRAPAT,p.size())));
144 out<<e;
145 while(p.nempty()) {
146 p=p.adv(e=p.left(std::min(WRAPAT,p.size())));
147 out<<"\r\n\t"<<e;
148 }
149 }
150}