Minor cleanup, no functional change.

This commit is contained in:
Axel Dörfler 2011-12-03 01:08:55 +01:00
parent 6d870a6ce7
commit 4bd5da8275

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 <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);
}