Forgot to adjust default window size
[claws.git] / src / common / quoted-printable.c
blobdd0a6bb594e61b58548e9b5f083b457f02b9fe58
1 /*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
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 3 of the License, or
8 * (at your option) any later version.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <glib.h>
21 #include <ctype.h>
23 #include "utils.h"
25 #define MAX_LINELEN 76
27 #define IS_LBREAK(p) \
28 (*(p) == '\0' || *(p) == '\n' || (*(p) == '\r' && *((p) + 1) == '\n'))
30 #define SOFT_LBREAK_IF_REQUIRED(n) \
31 if (len + (n) > MAX_LINELEN || \
32 (len + (n) == MAX_LINELEN && (!IS_LBREAK(inp + 1)))) { \
33 *outp++ = '='; \
34 *outp++ = '\n'; \
35 len = 0; \
38 void qp_encode_line(gchar *out, const guchar *in)
40 const guchar *inp = in;
41 gchar *outp = out;
42 guchar ch;
43 gint len = 0;
45 while (*inp != '\0') {
46 ch = *inp;
48 if (IS_LBREAK(inp)) {
49 *outp++ = '\n';
50 len = 0;
51 if (*inp == '\r')
52 inp++;
53 inp++;
54 } else if (ch == '\t' || ch == ' ') {
55 if (IS_LBREAK(inp + 1)) {
56 SOFT_LBREAK_IF_REQUIRED(3);
57 *outp++ = '=';
58 get_hex_str(outp, ch);
59 outp += 2;
60 len += 3;
61 inp++;
62 } else {
63 SOFT_LBREAK_IF_REQUIRED(1);
64 *outp++ = *inp++;
65 len++;
67 } else if ((ch >= 33 && ch <= 60) || (ch >= 62 && ch <= 126)) {
68 SOFT_LBREAK_IF_REQUIRED(1);
69 *outp++ = *inp++;
70 len++;
71 } else {
72 SOFT_LBREAK_IF_REQUIRED(3);
73 *outp++ = '=';
74 get_hex_str(outp, ch);
75 outp += 2;
76 len += 3;
77 inp++;
81 if (len > 0)
82 *outp++ = '\n';
84 *outp = '\0';
87 gint qp_decode_line(gchar *str)
89 gchar *inp = str, *outp = str;
91 while (*inp != '\0') {
92 if (*inp == '=') {
93 if (inp[1] && inp[2] &&
94 get_hex_value((guchar *)outp, inp[1], inp[2])
95 == TRUE) {
96 inp += 3;
97 } else if (inp[1] == '\0' || g_ascii_isspace(inp[1])) {
98 /* soft line break */
99 break;
100 } else {
101 /* broken QP string */
102 *outp = *inp++;
104 } else {
105 *outp = *inp++;
107 outp++;
110 *outp = '\0';
112 return outp - str;
115 gint qp_decode_const(gchar *out, gint avail, const gchar *str)
117 const gchar *inp = str;
118 gchar *outp = out;
120 while (*inp != '\0' && avail > 0) {
121 if (*inp == '=') {
122 if (inp[1] && inp[2] &&
123 get_hex_value((guchar *)outp, inp[1], inp[2])
124 == TRUE) {
125 inp += 3;
126 } else if (inp[1] == '\0' || g_ascii_isspace(inp[1])) {
127 /* soft line break */
128 break;
129 } else {
130 /* broken QP string */
131 *outp = *inp++;
133 } else {
134 *outp = *inp++;
136 outp++;
137 avail--;
140 *outp = '\0';
142 return outp - out;
145 gint qp_decode_q_encoding(guchar *out, const gchar *in, gint inlen)
147 const gchar *inp = in;
148 guchar *outp = out;
150 if (inlen < 0)
151 inlen = G_MAXINT;
153 while (inp - in < inlen && *inp != '\0') {
154 if (*inp == '=' && inp + 3 - in <= inlen) {
155 if (get_hex_value(outp, inp[1], inp[2]) == TRUE) {
156 inp += 3;
157 } else {
158 *outp = *inp++;
160 } else if (*inp == '_') {
161 *outp = ' ';
162 inp++;
163 } else {
164 *outp = *inp++;
166 outp++;
169 *outp = '\0';
171 return outp - out;
174 gint qp_get_q_encoding_len(const guchar *str)
176 const guchar *inp = str;
177 gint len = 0;
179 while (*inp != '\0') {
180 if (*inp == 0x20)
181 len++;
182 else if (*inp == '=' || *inp == '?' || *inp == '_' ||
183 *inp < 32 || *inp > 127 || g_ascii_isspace(*inp))
184 len += 3;
185 else
186 len++;
188 inp++;
191 return len;
194 void qp_q_encode(gchar *out, const guchar *in)
196 const guchar *inp = in;
197 gchar *outp = out;
199 while (*inp != '\0') {
200 if (*inp == 0x20)
201 *outp++ = '_';
202 else if (*inp == '=' || *inp == '?' || *inp == '_' ||
203 *inp < 32 || *inp > 127 || g_ascii_isspace(*inp)) {
204 *outp++ = '=';
205 get_hex_str(outp, *inp);
206 outp += 2;
207 } else
208 *outp++ = *inp;
210 inp++;
213 *outp = '\0';