/* Encoding functions */
/****************************************************************************/
+static const char __qp_special[128] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
typedef size_t (encoder_t)(char *, const char *, ssize_t, const char *);
static size_t
if (c == ' ') {
*s++ = '_';
} else
- if (c & 0x80 || c < 0x20 || c == '_' || strchr (MimeSpecials, c)) {
+ if (c & 0x80 || __qp_special[c]) {
*s++ = '=';
*s++ = __m_b36chars_upper[c >> 4];
*s++ = __m_b36chars_upper[c & 0xf];
encoder_t **encoder, ssize_t *wlen)
{
char buf1[ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 1];
- iconv_t cd;
- const char *ib;
- char *ob, *p;
- ssize_t ibl, obl;
- int count, len, len_b, len_q;
+ ssize_t obl = sizeof(buf1) - m_strlen(tocode);
+ char *ob;
if (fromcode) {
- cd = mutt_iconv_open (tocode, fromcode, 0);
- assert (cd != (iconv_t) (-1));
- ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - m_strlen(tocode);
+ const char *ib = d;
+ ssize_t ibl = dlen;
+ iconv_t cd = mutt_iconv_open(tocode, fromcode, 0);
+
+ assert (cd != (iconv_t)(-1));
+
+ ob = buf1;
+
if (my_iconv(cd, &ib, &ibl, &ob, &obl) < 0
|| my_iconv(cd, 0, 0, &ob, &obl) < 0)
{
- assert (errno == E2BIG);
- iconv_close (cd);
- assert (ib > d);
+ assert (errno == E2BIG && ib > d);
+ iconv_close(cd);
return (ib - d == dlen) ? dlen : ib - d + 1;
}
iconv_close (cd);
- }
- else {
- if (dlen > ssizeof(buf1) - m_strlen(tocode))
- return ssizeof(buf1) - m_strlen(tocode) + 1;
- memcpy (buf1, d, dlen);
+ } else {
+ if (dlen > obl)
+ return obl + 1;
+ memcpy(buf1, d, dlen);
ob = buf1 + dlen;
}
- count = 0;
- for (p = buf1; p < ob; p++) {
- unsigned char c = *p;
+ {
+ const char *p;
+ int count, len, len_b, len_q;
- assert (strchr (MimeSpecials, '?'));
- if (c >= 0x7f || c < 0x20 || *p == '_' ||
- (c != ' ' && strchr (MimeSpecials, *p)))
- ++count;
- }
+ count = 0;
+ for (p = buf1; p < ob; p++) {
+ count += (*p & 0x80 || __qp_special[(int)*p]);
+ }
- len = ENCWORD_LEN_MIN - 2 + m_strlen(tocode);
- len_b = len + (((ob - buf1) + 2) / 3) * 4;
- len_q = len + (ob - buf1) + 2 * count;
+ len = ENCWORD_LEN_MIN - 2 + m_strlen(tocode);
+ len_b = len + (((ob - buf1) + 2) / 3) * 4;
+ len_q = len + (ob - buf1) + 2 * count;
- /* Apparently RFC 1468 says to use B encoding for iso-2022-jp. */
- if (!ascii_strcasecmp (tocode, "ISO-2022-JP"))
- len_q = ENCWORD_LEN_MAX + 1;
+ /* Apparently RFC 1468 says to use B encoding for iso-2022-jp. */
+ if (!ascii_strcasecmp(tocode, "ISO-2022-JP"))
+ len_q = ENCWORD_LEN_MAX + 1;
- if (len_b < len_q && len_b <= ENCWORD_LEN_MAX) {
- *encoder = b_encoder;
- *wlen = len_b;
- return 0;
- }
- else if (len_q <= ENCWORD_LEN_MAX) {
- *encoder = q_encoder;
- *wlen = len_q;
- return 0;
+ if (len_b < len_q && len_b <= ENCWORD_LEN_MAX) {
+ *encoder = b_encoder;
+ *wlen = len_b;
+ return 0;
+ } else
+ if (len_q <= ENCWORD_LEN_MAX) {
+ *encoder = q_encoder;
+ *wlen = len_q;
+ return 0;
+ } else {
+ return dlen;
+ }
}
- else
- return dlen;
}
/*