Minor cleanup, no functional change.
This commit is contained in:
parent
6d870a6ce7
commit
4bd5da8275
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user