hrev43382 adds 1 changeset to branch 'master' old head: 6d870a6ce71f52eb9a0fb48794a161cfa73c509b new head: 4bd5da8275d63d37a5862d2e276c89fb3759285f ---------------------------------------------------------------------------- 1 files changed, 108 insertions(+), 102 deletions(-) src/kits/mail/mail_encoding.c | 210 +++++++++++++++++++------------------ ############################################################################ Revision: hrev43382 Commit: 4bd5da8275d63d37a5862d2e276c89fb3759285f URL: http://cgit.haiku-os.org/haiku/commit/?id=4bd5da8 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Sat Dec 3 00:08:55 2011 UTC Minor cleanup, no functional change. ---------------------------------------------------------------------------- diff --git a/src/kits/mail/mail_encoding.c b/src/kits/mail/mail_encoding.c index 2213dcc..6aff122 100644 --- a/src/kits/mail/mail_encoding.c +++ b/src/kits/mail/mail_encoding.c @@ -1,25 +1,37 @@ +/* + * Copyright 2011, Haiku, Inc. All rights reserved. + * Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved. + */ + + #include <ctype.h> #include <string.h> +#include <SupportDefs.h> + #include <mail_encoding.h> -#define DEC(Char) (((Char) - ' ') & 077) -typedef unsigned char uchar; +#define DEC(c) (((c) - ' ') & 077) + -char base64_alphabet[64] = { //----Fast lookup table - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', +static const char kBase64Alphabet[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; -const char hex_alphabet[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; +static const char kHexAlphabet[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8','9','A','B','C','D','E','F'}; -_EXPORT ssize_t -encode(mail_encoding encoding, char *out, const char *in, off_t length, int headerMode) +ssize_t +encode(mail_encoding encoding, char *out, const char *in, off_t length, + int headerMode) { switch (encoding) { case base64: @@ -35,13 +47,14 @@ encode(mail_encoding encoding, char *out, const char *in, off_t length, int head default: return -1; } - + return -1; } - -_EXPORT ssize_t -decode(mail_encoding encoding, char *out, const char *in, off_t length, int underscore_is_space) + +ssize_t +decode(mail_encoding encoding, char *out, const char *in, off_t length, + int underscoreIsSpace) { switch (encoding) { case base64: @@ -54,7 +67,7 @@ decode(mail_encoding encoding, char *out, const char *in, off_t length, int unde memcpy(out, in, length); return length; case quoted_printable: - return decode_qp(out, in, length, underscore_is_space); + return decode_qp(out, in, length, underscoreIsSpace); default: break; } @@ -63,39 +76,37 @@ decode(mail_encoding encoding, char *out, const char *in, off_t length, int unde } -_EXPORT ssize_t -max_encoded_length(mail_encoding encoding, off_t cur_length) +ssize_t +max_encoded_length(mail_encoding encoding, off_t length) { switch (encoding) { case base64: { - double result; - result = cur_length; - result *= 1.33333333333333; - result += (result / BASE64_LINELENGTH)*2 + 20; + double result = length * 1.33333333333333; + result += (result / BASE64_LINELENGTH) * 2 + 20; return (ssize_t)(result); } case quoted_printable: - return cur_length*3; + return length * 3; case seven_bit: case eight_bit: case no_encoding: - return cur_length; + return length; case uuencode: default: return -1; } - + return -1; } -_EXPORT mail_encoding +mail_encoding encoding_for_cte(const char *cte) { if (cte == NULL) return no_encoding; - + if (strcasecmp(cte,"uuencode") == 0) return uuencode; if (strcasecmp(cte,"base64") == 0) @@ -111,28 +122,29 @@ encoding_for_cte(const char *cte) } -_EXPORT ssize_t +ssize_t encode_base64(char *out, const char *in, off_t length, int headerMode) { - unsigned long concat; + uint32 concat; int i = 0; int k = 0; - int curr_linelength = 4; //--4 is a safety extension, designed to cause retirement *before* it actually gets too long + int lineLength = 4; + // Stop before it actually gets too long while (i < length) { concat = ((in[i] & 0xff) << 16); - + if ((i+1) < length) concat |= ((in[i+1] & 0xff) << 8); if ((i+2) < length) concat |= (in[i+2] & 0xff); - + i += 3; - - out[k++] = base64_alphabet[(concat >> 18) & 63]; - out[k++] = base64_alphabet[(concat >> 12) & 63]; - out[k++] = base64_alphabet[(concat >> 6) & 63]; - out[k++] = base64_alphabet[concat & 63]; + + out[k++] = kBase64Alphabet[(concat >> 18) & 63]; + out[k++] = kBase64Alphabet[(concat >> 12) & 63]; + out[k++] = kBase64Alphabet[(concat >> 6) & 63]; + out[k++] = kBase64Alphabet[concat & 63]; if (i >= length) { int v; @@ -140,27 +152,27 @@ encode_base64(char *out, const char *in, off_t length, int headerMode) out[k-v] = '='; } - curr_linelength += 4; - + lineLength += 4; + // No line breaks in header mode, since the text is part of a Subject: // line or some other single header line. The header code will do word // wrapping separately from this encoding stuff. - if (!headerMode && curr_linelength > BASE64_LINELENGTH) { + if (!headerMode && lineLength > BASE64_LINELENGTH) { out[k++] = '\r'; out[k++] = '\n'; - - curr_linelength = 4; + + lineLength = 4; } } - + return k; } -_EXPORT ssize_t +ssize_t decode_base64(char *out, const char *in, off_t length) { - unsigned long concat, value; + uint32 concat, value; int lastOutLine = 0; int i, j; int outIndex = 0; @@ -217,84 +229,72 @@ decode_base64(char *out, const char *in, off_t length) } -_EXPORT ssize_t -decode_qp(char *out, const char *in, off_t length, int underscore_is_space) +ssize_t +decode_qp(char *out, const char *in, off_t length, int underscoreIsSpace) { // decode Quoted Printable char *dataout = out; - const char *datain = in, *dataend = in+length; - - while ( datain < dataend ) - { - if (*datain == '=' && dataend-datain>2) - { - int a,b; - - a = toupper(datain[1]); - a -= a>='0' && a<='9'? '0' : (a>='A' && a<='F'? 'A'-10 : a+1); - - b = toupper(datain[2]); - b -= b>='0' && b<='9'? '0' : (b>='A' && b<='F'? 'A'-10 : b+1); - - if (a>=0 && b>=0) - { - *dataout++ = (a<<4) + b; + const char *datain = in, *dataend = in + length; + + while (datain < dataend) { + if (*datain == '=' && dataend - datain > 2) { + int a = toupper(datain[1]); + a -= a >= '0' && a <= '9' ? '0' : (a >= 'A' && a <= 'F' + ? 'A' - 10 : a + 1); + + int b = toupper(datain[2]); + b -= b >= '0' && b <= '9' ? '0' : (b >= 'A' && b <= 'F' + ? 'A' - 10 : b + 1); + + if (a >= 0 && b >= 0) { + *dataout++ = (a << 4) + b; datain += 3; continue; - } else if (datain[1]=='\r' && datain[2]=='\n') { + } else if (datain[1] == '\r' && datain[2] == '\n') { // strip =<CR><NL> datain += 3; continue; } - } - else if ((*datain == '_') && (underscore_is_space)) - { + } else if (*datain == '_' && underscoreIsSpace) { *dataout++ = ' '; ++datain; continue; } - + *dataout++ = *datain++; } - + *dataout = '\0'; - return dataout-out; + return dataout - out; } -_EXPORT ssize_t +ssize_t encode_qp(char *out, const char *in, off_t length, int headerMode) { int g = 0, i = 0; - + for (; i < length; i++) { - if ((((unsigned char *)(in))[i] > 127) || - (in[i] == '?') || - (in[i] == '=') || - (in[i] == '_') || + if (((uint8 *)(in))[i] > 127 || in[i] == '?' || in[i] == '=' + || in[i] == '_' // Also encode the letter F in "From " at the start of the line, // which Unix systems use to mark the start of messages in their // mbox files. - (in[i] == 'F' && - (i + 5 <= length) && - (i == 0 || in[i-1] == '\n') && - in[i+1] == 'r' && - in[i+2] == 'o' && - in[i+3] == 'm' && - in[i+4] == ' ')) { + || (in[i] == 'F' && i + 5 <= length && (i == 0 || in[i - 1] == '\n') + && in[i + 1] == 'r' && in[i + 2] == 'o' && in[i + 3] == 'm' + && in[i + 4] == ' ')) { out[g++] = '='; - out[g++] = hex_alphabet[(in[i] >> 4) & 0x0f]; - out[g++] = hex_alphabet[in[i] & 0x0f]; - } - else if (headerMode && (in[i] == ' ' || in[i] == '\t')) + out[g++] = kHexAlphabet[(in[i] >> 4) & 0x0f]; + out[g++] = kHexAlphabet[in[i] & 0x0f]; + } else if (headerMode && (in[i] == ' ' || in[i] == '\t')) { out[g++] = '_'; - else if (headerMode && (in[i] >= 0 && in[i] < 32)) { + } else if (headerMode && in[i] >= 0 && in[i] < 32) { // Control codes in headers need to be sanitized, otherwise certain // Japanese ISPs mangle the headers badly. But they don't mangle // the body. out[g++] = '='; - out[g++] = hex_alphabet[(in[i] >> 4) & 0x0f]; - out[g++] = hex_alphabet[in[i] & 0x0f]; + out[g++] = kHexAlphabet[(in[i] >> 4) & 0x0f]; + out[g++] = kHexAlphabet[in[i] & 0x0f]; } else out[g++] = in[i]; } @@ -303,17 +303,18 @@ encode_qp(char *out, const char *in, off_t length, int headerMode) } -_EXPORT ssize_t +ssize_t uu_decode(char *out, const char *in, off_t length) { long n; - uchar *p,*inBuffer = (uchar *)in; - uchar *outBuffer = (uchar *)out; - - inBuffer = (uchar *)strstr((char *)inBuffer, "begin"); + uint8 *p, *inBuffer = (uint8 *)in; + uint8 *outBuffer = (uint8 *)out; + + inBuffer = (uint8 *)strstr((char *)inBuffer, "begin"); goto enterLoop; - while (((inBuffer - (uchar *)in) <= length) && strncmp((char *)inBuffer, "end", 3)) { + while ((inBuffer - (uint8 *)in) <= length + && strncmp((char *)inBuffer, "end", 3)) { p = inBuffer; n = DEC(inBuffer[0]); @@ -323,20 +324,25 @@ uu_decode(char *out, const char *in, off_t length) *outBuffer++ = DEC(inBuffer[1]) << 4 | DEC (inBuffer[2]) >> 2; *outBuffer++ = DEC(inBuffer[2]) << 6 | DEC (inBuffer[3]); } else { - if (n >= 1) *outBuffer++ = DEC(inBuffer[0]) << 2 - | DEC (inBuffer[1]) >> 4; - if (n >= 2) *outBuffer++ = DEC(inBuffer[1]) << 4 - | DEC (inBuffer[2]) >> 2; + if (n >= 1) { + *outBuffer++ = DEC(inBuffer[0]) << 2 + | DEC (inBuffer[1]) >> 4; + } + if (n >= 2) { + *outBuffer++ = DEC(inBuffer[1]) << 4 + | DEC (inBuffer[2]) >> 2; + } } } inBuffer = p; enterLoop: - while ((inBuffer[0] != '\n') && (inBuffer[0] != '\r') - && (inBuffer[0] != 0)) inBuffer++; - while ((inBuffer[0] == '\n') || (inBuffer[0] == '\r')) inBuffer++; + while (inBuffer[0] != '\n' && inBuffer[0] != '\r' && inBuffer[0] != 0) + inBuffer++; + while (inBuffer[0] == '\n' || inBuffer[0] == '\r') + inBuffer++; } - return (ssize_t)(outBuffer - ((uchar *)in)); + return (ssize_t)(outBuffer - (uint8 *)in); }