This source file includes following definitions.
- mbfl_filt_conv_qprintenc
- mbfl_filt_conv_qprintenc_flush
- mbfl_filt_conv_qprintdec
- mbfl_filt_conv_qprintdec_flush
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "mbfilter.h"
35 #include "mbfilter_qprint.h"
36 #include "unicode_prop.h"
37
38 static const char *mbfl_encoding_qprint_aliases[] = {"qprint", NULL};
39
40 const mbfl_encoding mbfl_encoding_qprint = {
41 mbfl_no_encoding_qprint,
42 "Quoted-Printable",
43 "Quoted-Printable",
44 (const char *(*)[])&mbfl_encoding_qprint_aliases,
45 NULL,
46 MBFL_ENCTYPE_ENC_STRM | MBFL_ENCTYPE_GL_UNSAFE
47 };
48
49 const struct mbfl_convert_vtbl vtbl_8bit_qprint = {
50 mbfl_no_encoding_8bit,
51 mbfl_no_encoding_qprint,
52 mbfl_filt_conv_common_ctor,
53 mbfl_filt_conv_common_dtor,
54 mbfl_filt_conv_qprintenc,
55 mbfl_filt_conv_qprintenc_flush };
56
57 const struct mbfl_convert_vtbl vtbl_qprint_8bit = {
58 mbfl_no_encoding_qprint,
59 mbfl_no_encoding_8bit,
60 mbfl_filt_conv_common_ctor,
61 mbfl_filt_conv_common_dtor,
62 mbfl_filt_conv_qprintdec,
63 mbfl_filt_conv_qprintdec_flush };
64
65
66 #define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
67
68
69
70
71
72 int mbfl_filt_conv_qprintenc(int c, mbfl_convert_filter *filter)
73 {
74 int s, n;
75
76 switch (filter->status & 0xff) {
77 case 0:
78 filter->cache = c;
79 filter->status++;
80 break;
81 default:
82 s = filter->cache;
83 filter->cache = c;
84 n = (filter->status & 0xff00) >> 8;
85
86 if (s == 0) {
87 CK((*filter->output_function)(s, filter->data));
88 filter->status &= ~0xff00;
89 break;
90 }
91
92 if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0) {
93 if (s == 0x0a || (s == 0x0d && c != 0x0a)) {
94 CK((*filter->output_function)(0x0d, filter->data));
95 CK((*filter->output_function)(0x0a, filter->data));
96 filter->status &= ~0xff00;
97 break;
98 } else if (s == 0x0d) {
99 break;
100 }
101 }
102
103 if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0 && n >= 72) {
104 CK((*filter->output_function)(0x3d, filter->data));
105 CK((*filter->output_function)(0x0d, filter->data));
106 CK((*filter->output_function)(0x0a, filter->data));
107 filter->status &= ~0xff00;
108 }
109
110 if (s <= 0 || s >= 0x80 || s == 0x3d
111 || ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) != 0 &&
112 (mbfl_charprop_table[s] & MBFL_CHP_MMHQENC) != 0)) {
113
114 CK((*filter->output_function)(0x3d, filter->data));
115 n = (s >> 4) & 0xf;
116 if (n < 10) {
117 n += 48;
118 } else {
119 n += 55;
120 }
121 CK((*filter->output_function)(n, filter->data));
122 n = s & 0xf;
123 if (n < 10) {
124 n += 48;
125 } else {
126 n += 55;
127 }
128 CK((*filter->output_function)(n, filter->data));
129 if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0) {
130 filter->status += 0x300;
131 }
132 } else {
133 CK((*filter->output_function)(s, filter->data));
134 if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0) {
135 filter->status += 0x100;
136 }
137 }
138 break;
139 }
140
141 return c;
142 }
143
144 int mbfl_filt_conv_qprintenc_flush(mbfl_convert_filter *filter)
145 {
146
147 (*filter->filter_function)('\0', filter);
148 filter->status &= ~0xffff;
149 filter->cache = 0;
150 return 0;
151 }
152
153
154
155
156 int mbfl_filt_conv_qprintdec(int c, mbfl_convert_filter *filter)
157 {
158 int n, m;
159
160 static int hex2code_map[] = {
161 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
162 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
163 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
164 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
165 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
166 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
167 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
168 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
169 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
170 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
171 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
172 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
173 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
174 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
175 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
176 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
177 };
178
179 switch (filter->status) {
180 case 1:
181 if (hex2code_map[c & 0xff] >= 0) {
182 filter->cache = c;
183 filter->status = 2;
184 } else if (c == 0x0d) {
185 filter->status = 3;
186 } else if (c == 0x0a) {
187 filter->status = 0;
188 } else {
189 CK((*filter->output_function)(0x3d, filter->data));
190 CK((*filter->output_function)(c, filter->data));
191 filter->status = 0;
192 }
193 break;
194 case 2:
195 m = hex2code_map[c & 0xff];
196 if (m < 0) {
197 CK((*filter->output_function)(0x3d, filter->data));
198 CK((*filter->output_function)(filter->cache, filter->data));
199 n = c;
200 } else {
201 n = hex2code_map[filter->cache] << 4 | m;
202 }
203 CK((*filter->output_function)(n, filter->data));
204 filter->status = 0;
205 break;
206 case 3:
207 if (c != 0x0a) {
208 CK((*filter->output_function)(c, filter->data));
209 }
210 filter->status = 0;
211 break;
212 default:
213 if (c == 0x3d) {
214 filter->status = 1;
215 } else {
216 CK((*filter->output_function)(c, filter->data));
217 }
218 break;
219 }
220
221 return c;
222 }
223
224 int mbfl_filt_conv_qprintdec_flush(mbfl_convert_filter *filter)
225 {
226 int status, cache;
227
228 status = filter->status;
229 cache = filter->cache;
230 filter->status = 0;
231 filter->cache = 0;
232
233 if (status == 1) {
234 CK((*filter->output_function)(0x3d, filter->data));
235 } else if (status == 2) {
236 CK((*filter->output_function)(0x3d, filter->data));
237 CK((*filter->output_function)(cache, filter->data));
238 }
239
240 return 0;
241 }
242
243
244