Minor cleanup, no functional change.

This commit is contained in:
Axel Dörfler
2011-12-03 01:10:00 +01:00
parent 6d870a6ce7
commit 4bd5da8275
+108 -102
View File
@@ -1,25 +1,37 @@
/*
* Copyright 2011, Haiku, Inc. All rights reserved.
* Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
*/
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <SupportDefs.h>
#include <mail_encoding.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', 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',
'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', '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 ssize_t
encode(mail_encoding encoding, char *out, const char *in, off_t length, int headerMode) encode(mail_encoding encoding, char *out, const char *in, off_t length,
int headerMode)
{ {
switch (encoding) { switch (encoding) {
case base64: case base64:
@@ -35,13 +47,14 @@ encode(mail_encoding encoding, char *out, const char *in, off_t length, int head
default: default:
return -1; return -1;
} }
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) { switch (encoding) {
case base64: case base64:
@@ -54,7 +67,7 @@ decode(mail_encoding encoding, char *out, const char *in, off_t length, int unde
memcpy(out, in, length); memcpy(out, in, length);
return length; return length;
case quoted_printable: case quoted_printable:
return decode_qp(out, in, length, underscore_is_space); return decode_qp(out, in, length, underscoreIsSpace);
default: default:
break; break;
} }
@@ -63,39 +76,37 @@ decode(mail_encoding encoding, char *out, const char *in, off_t length, int unde
} }
_EXPORT ssize_t ssize_t
max_encoded_length(mail_encoding encoding, off_t cur_length) max_encoded_length(mail_encoding encoding, off_t length)
{ {
switch (encoding) { switch (encoding) {
case base64: case base64:
{ {
double result; double result = length * 1.33333333333333;
result = cur_length; result += (result / BASE64_LINELENGTH) * 2 + 20;
result *= 1.33333333333333;
result += (result / BASE64_LINELENGTH)*2 + 20;
return (ssize_t)(result); return (ssize_t)(result);
} }
case quoted_printable: case quoted_printable:
return cur_length*3; return length * 3;
case seven_bit: case seven_bit:
case eight_bit: case eight_bit:
case no_encoding: case no_encoding:
return cur_length; return length;
case uuencode: case uuencode:
default: default:
return -1; return -1;
} }
return -1; return -1;
} }
_EXPORT mail_encoding mail_encoding
encoding_for_cte(const char *cte) encoding_for_cte(const char *cte)
{ {
if (cte == NULL) if (cte == NULL)
return no_encoding; return no_encoding;
if (strcasecmp(cte,"uuencode") == 0) if (strcasecmp(cte,"uuencode") == 0)
return uuencode; return uuencode;
if (strcasecmp(cte,"base64") == 0) 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) encode_base64(char *out, const char *in, off_t length, int headerMode)
{ {
unsigned long concat; uint32 concat;
int i = 0; int i = 0;
int k = 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) { while (i < length) {
concat = ((in[i] & 0xff) << 16); concat = ((in[i] & 0xff) << 16);
if ((i+1) < length) if ((i+1) < length)
concat |= ((in[i+1] & 0xff) << 8); concat |= ((in[i+1] & 0xff) << 8);
if ((i+2) < length) if ((i+2) < length)
concat |= (in[i+2] & 0xff); concat |= (in[i+2] & 0xff);
i += 3; i += 3;
out[k++] = base64_alphabet[(concat >> 18) & 63]; out[k++] = kBase64Alphabet[(concat >> 18) & 63];
out[k++] = base64_alphabet[(concat >> 12) & 63]; out[k++] = kBase64Alphabet[(concat >> 12) & 63];
out[k++] = base64_alphabet[(concat >> 6) & 63]; out[k++] = kBase64Alphabet[(concat >> 6) & 63];
out[k++] = base64_alphabet[concat & 63]; out[k++] = kBase64Alphabet[concat & 63];
if (i >= length) { if (i >= length) {
int v; int v;
@@ -140,27 +152,27 @@ encode_base64(char *out, const char *in, off_t length, int headerMode)
out[k-v] = '='; out[k-v] = '=';
} }
curr_linelength += 4; lineLength += 4;
// No line breaks in header mode, since the text is part of a Subject: // 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 // line or some other single header line. The header code will do word
// wrapping separately from this encoding stuff. // wrapping separately from this encoding stuff.
if (!headerMode && curr_linelength > BASE64_LINELENGTH) { if (!headerMode && lineLength > BASE64_LINELENGTH) {
out[k++] = '\r'; out[k++] = '\r';
out[k++] = '\n'; out[k++] = '\n';
curr_linelength = 4; lineLength = 4;
} }
} }
return k; return k;
} }
_EXPORT ssize_t ssize_t
decode_base64(char *out, const char *in, off_t length) decode_base64(char *out, const char *in, off_t length)
{ {
unsigned long concat, value; uint32 concat, value;
int lastOutLine = 0; int lastOutLine = 0;
int i, j; int i, j;
int outIndex = 0; int outIndex = 0;
@@ -217,84 +229,72 @@ decode_base64(char *out, const char *in, off_t length)
} }
_EXPORT ssize_t ssize_t
decode_qp(char *out, const char *in, off_t length, int underscore_is_space) decode_qp(char *out, const char *in, off_t length, int underscoreIsSpace)
{ {
// decode Quoted Printable // decode Quoted Printable
char *dataout = out; char *dataout = out;
const char *datain = in, *dataend = in+length; const char *datain = in, *dataend = in + length;
while ( datain < dataend ) while (datain < dataend) {
{ if (*datain == '=' && dataend - datain > 2) {
if (*datain == '=' && dataend-datain>2) int a = toupper(datain[1]);
{ a -= a >= '0' && a <= '9' ? '0' : (a >= 'A' && a <= 'F'
int a,b; ? 'A' - 10 : a + 1);
a = toupper(datain[1]); int b = toupper(datain[2]);
a -= a>='0' && a<='9'? '0' : (a>='A' && a<='F'? 'A'-10 : a+1); b -= b >= '0' && b <= '9' ? '0' : (b >= 'A' && b <= 'F'
? 'A' - 10 : b + 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;
if (a>=0 && b>=0)
{
*dataout++ = (a<<4) + b;
datain += 3; datain += 3;
continue; continue;
} else if (datain[1]=='\r' && datain[2]=='\n') { } else if (datain[1] == '\r' && datain[2] == '\n') {
// strip =<CR><NL> // strip =<CR><NL>
datain += 3; datain += 3;
continue; continue;
} }
} } else if (*datain == '_' && underscoreIsSpace) {
else if ((*datain == '_') && (underscore_is_space))
{
*dataout++ = ' '; *dataout++ = ' ';
++datain; ++datain;
continue; continue;
} }
*dataout++ = *datain++; *dataout++ = *datain++;
} }
*dataout = '\0'; *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) encode_qp(char *out, const char *in, off_t length, int headerMode)
{ {
int g = 0, i = 0; int g = 0, i = 0;
for (; i < length; i++) { for (; i < length; i++) {
if ((((unsigned char *)(in))[i] > 127) || if (((uint8 *)(in))[i] > 127 || in[i] == '?' || in[i] == '='
(in[i] == '?') || || in[i] == '_'
(in[i] == '=') ||
(in[i] == '_') ||
// Also encode the letter F in "From " at the start of the line, // 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 // which Unix systems use to mark the start of messages in their
// mbox files. // mbox files.
(in[i] == 'F' && || (in[i] == 'F' && i + 5 <= length && (i == 0 || in[i - 1] == '\n')
(i + 5 <= length) && && in[i + 1] == 'r' && in[i + 2] == 'o' && in[i + 3] == 'm'
(i == 0 || in[i-1] == '\n') && && in[i + 4] == ' ')) {
in[i+1] == 'r' &&
in[i+2] == 'o' &&
in[i+3] == 'm' &&
in[i+4] == ' ')) {
out[g++] = '='; out[g++] = '=';
out[g++] = hex_alphabet[(in[i] >> 4) & 0x0f]; out[g++] = kHexAlphabet[(in[i] >> 4) & 0x0f];
out[g++] = hex_alphabet[in[i] & 0x0f]; out[g++] = kHexAlphabet[in[i] & 0x0f];
} } else if (headerMode && (in[i] == ' ' || in[i] == '\t')) {
else if (headerMode && (in[i] == ' ' || in[i] == '\t'))
out[g++] = '_'; 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 // Control codes in headers need to be sanitized, otherwise certain
// Japanese ISPs mangle the headers badly. But they don't mangle // Japanese ISPs mangle the headers badly. But they don't mangle
// the body. // the body.
out[g++] = '='; out[g++] = '=';
out[g++] = hex_alphabet[(in[i] >> 4) & 0x0f]; out[g++] = kHexAlphabet[(in[i] >> 4) & 0x0f];
out[g++] = hex_alphabet[in[i] & 0x0f]; out[g++] = kHexAlphabet[in[i] & 0x0f];
} else } else
out[g++] = in[i]; 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) uu_decode(char *out, const char *in, off_t length)
{ {
long n; long n;
uchar *p,*inBuffer = (uchar *)in; uint8 *p, *inBuffer = (uint8 *)in;
uchar *outBuffer = (uchar *)out; uint8 *outBuffer = (uint8 *)out;
inBuffer = (uchar *)strstr((char *)inBuffer, "begin"); inBuffer = (uint8 *)strstr((char *)inBuffer, "begin");
goto enterLoop; goto enterLoop;
while (((inBuffer - (uchar *)in) <= length) && strncmp((char *)inBuffer, "end", 3)) { while ((inBuffer - (uint8 *)in) <= length
&& strncmp((char *)inBuffer, "end", 3)) {
p = inBuffer; p = inBuffer;
n = DEC(inBuffer[0]); 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[1]) << 4 | DEC (inBuffer[2]) >> 2;
*outBuffer++ = DEC(inBuffer[2]) << 6 | DEC (inBuffer[3]); *outBuffer++ = DEC(inBuffer[2]) << 6 | DEC (inBuffer[3]);
} else { } else {
if (n >= 1) *outBuffer++ = DEC(inBuffer[0]) << 2 if (n >= 1) {
| DEC (inBuffer[1]) >> 4; *outBuffer++ = DEC(inBuffer[0]) << 2
if (n >= 2) *outBuffer++ = DEC(inBuffer[1]) << 4 | DEC (inBuffer[1]) >> 4;
| DEC (inBuffer[2]) >> 2; }
if (n >= 2) {
*outBuffer++ = DEC(inBuffer[1]) << 4
| DEC (inBuffer[2]) >> 2;
}
} }
} }
inBuffer = p; inBuffer = p;
enterLoop: enterLoop:
while ((inBuffer[0] != '\n') && (inBuffer[0] != '\r') while (inBuffer[0] != '\n' && inBuffer[0] != '\r' && inBuffer[0] != 0)
&& (inBuffer[0] != 0)) inBuffer++; inBuffer++;
while ((inBuffer[0] == '\n') || (inBuffer[0] == '\r')) inBuffer++; while (inBuffer[0] == '\n' || inBuffer[0] == '\r')
inBuffer++;
} }
return (ssize_t)(outBuffer - ((uchar *)in)); return (ssize_t)(outBuffer - (uint8 *)in);
} }