KIMAP

rfccodecs.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * rfccodecs.cpp - handler for various rfc/mime encodings
4  * SPDX-FileCopyrightText: 2000 s [email protected]
5  *
6  * SPDX-License-Identifier: LGPL-2.0-or-later
7  *
8  *********************************************************************/
9 /**
10  * @file
11  * This file is part of the IMAP support library and defines the
12  * RfcCodecs class.
13  *
14  * @brief
15  * Defines the RfcCodecs class.
16  *
17  * @author Sven Carstens
18  */
19 
20 #include "rfccodecs.h"
21 
22 #include <ctype.h>
23 #include <sys/types.h>
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 
28 #include <QByteArray>
29 #include <QLatin1Char>
30 
31 using namespace KIMAP;
32 
33 // This part taken from rfc 2192 IMAP URL Scheme. C. Newman. September 1997.
34 // adapted to QT-Toolkit by Sven Carstens <[email protected]> 2000
35 
36 //@cond PRIVATE
37 static const unsigned char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
38 #define UNDEFINED 64
39 #define MAXLINE 76
40 static const char especials[17] = "()<>@,;:\"/[]?.= ";
41 
42 /* UTF16 definitions */
43 #define UTF16MASK 0x03FFUL
44 #define UTF16SHIFT 10
45 #define UTF16BASE 0x10000UL
46 #define UTF16HIGHSTART 0xD800UL
47 #define UTF16HIGHEND 0xDBFFUL
48 #define UTF16LOSTART 0xDC00UL
49 #define UTF16LOEND 0xDFFFUL
50 //@endcond
51 
52 //-----------------------------------------------------------------------------
54 {
55  unsigned char c;
56  unsigned char i;
57  unsigned char bitcount;
58  unsigned long ucs4;
59  unsigned long utf16;
60  unsigned long bitbuf;
61  unsigned char base64[256];
62  unsigned char utf8[6];
63  unsigned int srcPtr = 0;
64  QByteArray dst;
65  QByteArray src = inSrc;
66  uint srcLen = inSrc.length();
67 
68  /* initialize modified base64 decoding table */
69  memset(base64, UNDEFINED, sizeof(base64));
70  for (i = 0; i < sizeof(base64chars); ++i) {
71  base64[(int)base64chars[i]] = i;
72  }
73 
74  /* loop until end of string */
75  while (srcPtr < srcLen) {
76  c = src[srcPtr++];
77  /* deal with literal characters and &- */
78  if (c != '&' || src[srcPtr] == '-') {
79  /* encode literally */
80  dst += c;
81  /* skip over the '-' if this is an &- sequence */
82  if (c == '&') {
83  srcPtr++;
84  }
85  } else {
86  /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
87  bitbuf = 0;
88  bitcount = 0;
89  ucs4 = 0;
90  while ((c = base64[(unsigned char)src[srcPtr]]) != UNDEFINED) {
91  ++srcPtr;
92  bitbuf = (bitbuf << 6) | c;
93  bitcount += 6;
94  /* enough bits for a UTF-16 character? */
95  if (bitcount >= 16) {
96  bitcount -= 16;
97  utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
98  /* convert UTF16 to UCS4 */
99  if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
100  ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
101  continue;
102  } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
103  ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
104  } else {
105  ucs4 = utf16;
106  }
107  /* convert UTF-16 range of UCS4 to UTF-8 */
108  if (ucs4 <= 0x7fUL) {
109  utf8[0] = ucs4;
110  i = 1;
111  } else if (ucs4 <= 0x7ffUL) {
112  utf8[0] = 0xc0 | (ucs4 >> 6);
113  utf8[1] = 0x80 | (ucs4 & 0x3f);
114  i = 2;
115  } else if (ucs4 <= 0xffffUL) {
116  utf8[0] = 0xe0 | (ucs4 >> 12);
117  utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
118  utf8[2] = 0x80 | (ucs4 & 0x3f);
119  i = 3;
120  } else {
121  utf8[0] = 0xf0 | (ucs4 >> 18);
122  utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
123  utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
124  utf8[3] = 0x80 | (ucs4 & 0x3f);
125  i = 4;
126  }
127  /* copy it */
128  for (c = 0; c < i; ++c) {
129  dst += utf8[c];
130  }
131  }
132  }
133  /* skip over trailing '-' in modified UTF-7 encoding */
134  if (src[srcPtr] == '-') {
135  ++srcPtr;
136  }
137  }
138  }
139  return dst;
140 }
141 
143 {
145 }
146 
147 //-----------------------------------------------------------------------------
148 
150 {
151  int len = src.length();
152  QByteArray result;
153  result.reserve(2 * len);
154  for (int i = 0; i < len; i++) {
155  if (src[i] == '"' || src[i] == '\\') {
156  result += '\\';
157  }
158  result += src[i];
159  }
160  result.squeeze();
161  return result;
162 }
163 
165 {
166  uint len = src.length();
167  QString result;
168  result.reserve(2 * len);
169  for (unsigned int i = 0; i < len; i++) {
170  if (src[i] == QLatin1Char('"') || src[i] == QLatin1Char('\\')) {
171  result += QLatin1Char('\\');
172  }
173  result += src[i];
174  }
175  // result.squeeze(); - unnecessary and slow
176  return result;
177 }
178 
179 //-----------------------------------------------------------------------------
181 {
183 }
184 
186 {
187  unsigned int utf8pos;
188  unsigned int utf8total;
189  unsigned int c;
190  unsigned int utf7mode;
191  unsigned int bitstogo;
192  unsigned int utf16flag;
193  unsigned int ucs4;
194  unsigned int bitbuf;
195  QByteArray src = inSrc;
196  QByteArray dst;
197 
198  int srcPtr = 0;
199  utf7mode = 0;
200  utf8total = 0;
201  bitstogo = 0;
202  utf8pos = 0;
203  bitbuf = 0;
204  ucs4 = 0;
205  while (srcPtr < src.length()) {
206  c = (unsigned char)src[srcPtr++];
207  /* normal character? */
208  if (c >= ' ' && c <= '~') {
209  /* switch out of UTF-7 mode */
210  if (utf7mode) {
211  if (bitstogo) {
212  dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
213  bitstogo = 0;
214  }
215  dst += '-';
216  utf7mode = 0;
217  }
218  dst += c;
219  /* encode '&' as '&-' */
220  if (c == '&') {
221  dst += '-';
222  }
223  continue;
224  }
225  /* switch to UTF-7 mode */
226  if (!utf7mode) {
227  dst += '&';
228  utf7mode = 1;
229  }
230  /* Encode US-ASCII characters as themselves */
231  if (c < 0x80) {
232  ucs4 = c;
233  utf8total = 1;
234  } else if (utf8total) {
235  /* save UTF8 bits into UCS4 */
236  ucs4 = (ucs4 << 6) | (c & 0x3FUL);
237  if (++utf8pos < utf8total) {
238  continue;
239  }
240  } else {
241  utf8pos = 1;
242  if (c < 0xE0) {
243  utf8total = 2;
244  ucs4 = c & 0x1F;
245  } else if (c < 0xF0) {
246  utf8total = 3;
247  ucs4 = c & 0x0F;
248  } else {
249  /* NOTE: can't convert UTF8 sequences longer than 4 */
250  utf8total = 4;
251  ucs4 = c & 0x03;
252  }
253  continue;
254  }
255  /* loop to split ucs4 into two utf16 chars if necessary */
256  utf8total = 0;
257  do {
258  if (ucs4 >= UTF16BASE) {
259  ucs4 -= UTF16BASE;
260  bitbuf = (bitbuf << 16) | ((ucs4 >> UTF16SHIFT) + UTF16HIGHSTART);
261  ucs4 = (ucs4 & UTF16MASK) + UTF16LOSTART;
262  utf16flag = 1;
263  } else {
264  bitbuf = (bitbuf << 16) | ucs4;
265  utf16flag = 0;
266  }
267  bitstogo += 16;
268  /* spew out base64 */
269  while (bitstogo >= 6) {
270  bitstogo -= 6;
271  dst += base64chars[(bitstogo ? (bitbuf >> bitstogo) : bitbuf) & 0x3F];
272  }
273  } while (utf16flag);
274  }
275  /* if in UTF-7 mode, finish in ASCII */
276  if (utf7mode) {
277  if (bitstogo) {
278  dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
279  }
280  dst += '-';
281  }
282  return quoteIMAP(dst);
283 }
KIMAP_EXPORT QString encodeImapFolderName(const QString &src)
Converts an Unicode IMAP mailbox to a QString which can be used in IMAP communication.
Definition: rfccodecs.cpp:180
KIMAP2_EXPORT QByteArray encodeImapFolderName(const QByteArray &src)
Converts an Unicode IMAP mailbox to a QByteArray which can be used in IMAP communication.
Definition: rfccodecs.cpp:185
QString fromUtf8(const char *str, int size)
void squeeze()
KIMAP_EXPORT QByteArray quoteIMAP(const QByteArray &src)
Replaces " with \" and \ with \ " and \ characters.
Definition: rfccodecs.cpp:149
KIMAP2_EXPORT QByteArray decodeImapFolderName(const QByteArray &inSrc)
Converts an UTF-7 encoded IMAP mailbox to a QByteArray.
Definition: rfccodecs.cpp:53
void reserve(int size)
QByteArray toUtf8() const const
int length() const const
KIMAP_EXPORT QString decodeImapFolderName(const QString &inSrc)
Converts an UTF-7 encoded IMAP mailbox to a Unicode QString.
Definition: rfccodecs.cpp:142
const char * constData() const const
void reserve(int size)
int length() const const
KIMAP2_EXPORT QByteArray quoteIMAP(const QByteArray &src)
Replaces " with \" and \ with \ " and \ characters.
Definition: rfccodecs.cpp:149
Provides handlers for various RFC/MIME encodings.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Dec 5 2023 04:10:03 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.