邮件解析(源码)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

存储邮件信息的结构:

struct ContentHeader{

int nType;//=(1)0 text/plain, =(1)1 text/html, =(1)2 maybe attach

AnsiString strTransferEncoding;

AnsiString strContent;

AnsiString strFileName;//for attachment

};

处理每一行的函数,处理完成存入结构体ContehtHeader,并存入链表CHList( TList* )

void __fastcall TRecvMailThread::DealLine(char* line, int len)

{

int pos;

AnsiString strLine( line );

AnsiString strTemp( line );

strLine = strLine.LowerCase();

switch( nItemKind )

{

case 0 :

if( strLine == "" && nItems >= 1 )//第一部分结束

{

nItemKind = 1;//进入下一部分

break;

}

if( ( pos = strLine.AnsiPos( "from:" ) ) == 1 )

{

if( strFrom == "" )

{

strFrom = strTemp.SubString( pos + 5, len - pos - 4 );

if( strFrom[ 1 ] == 0x20 )

strFrom = strFrom.SubString( 2, strFrom.Length() - 1 );

nItems ++;

}

}

else if( ( pos = strLine.AnsiPos( "to:" ) ) == 1 )

{

if( strTo == "" )

{

strTo = strTemp.SubString( pos + 3, len - pos - 2 );

if( strTo[ 1 ] == 0x20 )

strTo = strTo.SubString( 2, strTo.Length() - 1 );

nItems ++;

}

}

else if( ( pos = strLine.AnsiPos( "subject:" ) ) == 1 )

{

if( strSubject == "" )

{

strSubject = strTemp.SubString( pos + 8, len - pos - 7 );

if( strSubject[ 1 ] == 0x20 )

strSubject = strSubject.SubString( 2, strSubject.Length() - 1 );

nItems ++;

}

}

else if( ( pos = strLine.AnsiPos( "content-type: multipart" ) ) != 0 )

{

if( ( pos = strLine.AnsiPos( "boundary=" ) ) != 0 )

{

strNormalBoundary = strTemp.SubString( pos + 9, len - pos - 8 );

if( strNormalBoundary[ 1 ] == '\"' )

strNormalBoundary = strNormalBoundary.SubString( 2, strNormalBoundary.Length() - 2 );

bBoundary = true;

}

}

else if( ( pos = strLine.AnsiPos( "boundary=" ) ) != 0 )

{

strNormalBoundary = strTemp.SubString( pos + 9, len - pos - 8 );

if( strNormalBoundary[ 1 ] == '\"' )

strNormalBoundary = strNormalBoundary.SubString( 2, strNormalBoundary.Length() - 2 );

bBoundary = true;

}

else if( ( pos = strLine.AnsiPos( "content-type: text/plain" ) ) != 0 )

{

nTextKind = 0;

pCH->nType = 0;

}

else if( ( pos = strLine.AnsiPos( "content-type: text/html" ) ) != 0 )

{

nTextKind = 1;

pCH->nType = 1;

}

else if( ( pos = strLine.AnsiPos( "content-transfer-encoding: " ) ) != 0 )

{

strTempEncode = strLine.SubString( pos + 27, len - pos - 26 );

pCH->strTransferEncoding = strTempEncode;

}

break;

case 1 :

if( bBoundary )

{

if( strTemp.AnsiPos( strNormalBoundary ) != 0 )

{

file://找到边界,

nItemKind = 2;

nItems = 0;

bBoundary = false;

}

}

else

{

file://没有边界,以下为邮件正文部分,至 "." 结束

pCH->strContent = strTemp;

nItemKind = 111;

}

break;

case 111 :

if( strLine != "." )

{

pCH->strContent += strTemp;

pCH->strContent += "\r\n";

}

else

{

CHList->Add( pCH );

nItemKind = ALL_READY;

}

break;

case 2 :

file://在此查找Content-Type, Content-Transfer-Encoding, boundary, Content-Disposition等

//.........

if( strLine == "" && nItems >= 1 )

{

file://进入下一部分

nItemKind = 3;

nItems = 0;

break;

}

if( ( pos = strLine.AnsiPos( "content-type:" ) ) != 0 )

{

nItems ++;

if( strLine.AnsiPos( "multipart/" ) != 0 )

{

if( ( pos = strLine.AnsiPos( "boundary=" ) ) != 0 )

{

strExpandBoundary = strTemp.SubString( pos + 9, len - pos - 8 );

if( strExpandBoundary[ 1 ] == '\"' )

strExpandBoundary = strExpandBoundary.SubString( 2, strExpandBoundary.Length() - 2 );

bBoundary = true;

}

nItemKind = 222;

break;

}

if( strLine.AnsiPos( "text/plain" ) != 0 )

nTextKind = 0;

else if( strLine.AnsiPos( "text/html" ) != 0 )

nTextKind = 1;

else

nTextKind = 2;

pCH->nType = nTextKind;

}

else if( ( pos = strLine.AnsiPos( "content-transfer-encoding:" ) ) != 0 )

{

nItems ++;

pCH->strTransferEncoding = strLine.SubString( pos + 27, len - pos - 26 );

}

else if( strLine.AnsiPos( "content-disposition:" ) != 0 )

{

if( ( pos = strLine.AnsiPos( "filename=\"" ) ) != 0 )

{

nItems ++;

pCH->strFileName = strTemp.SubString( pos + 10, len - pos - 10 );

bAttach = true;

}

}

else if( ( pos = strLine.AnsiPos( "filename=\"" ) ) != 0 )

{

nItems ++;

pCH->strFileName = strTemp.SubString( pos + 10, len - pos - 10 );

bAttach = true;

}

break;

case 3 :

file://接收内容to pCH->strContent

if( strTemp == "." )

{

CHList->Add( pCH );

nItemKind = ALL_READY;

break;

}

if( strTemp.AnsiPos( strNormalBoundary ) != 0 )

{

CHList->Add( pCH );

if( strTemp.AnsiPos ( strNormalBoundary + "--" ) == 0 )//未到最后

{

nItemKind = 2;

pCH = new ContentHeader;

}

else

{

nItemKind = ALL_READY;

break;

}

}

else

{

pCH->strContent += strTemp;

pCH->strContent += "\r\n";

}

break;

case 222 :

file://Microsoft Outlook Express

if( bBoundary )

{

nItemKind = 333;

}

else if( ( pos = strLine.AnsiPos( "boundary=" ) ) != 0 )

{

strExpandBoundary = strTemp.SubString( pos + 9, len - pos - 8 );

if( strExpandBoundary[ 1 ] == '\"' )

strExpandBoundary = strExpandBoundary.SubString( 2, strExpandBoundary.Length() - 2 );

nItemKind = 333;

}

break;

case 333 :

if( ( pos = strTemp.AnsiPos( strExpandBoundary ) ) != 0 )

{

nItemKind = 444;

nItems = 0;

}

break;

case 444 :

file://在此查找Content-Type, Content-Transfer-Encoding, boundary, Content-Disposition等

//.........

if( strLine == "" && nItems >= 1 )

{

file://进入下一部分

nItemKind = 555;

nItems = 0;

break;

}

if( ( pos = strLine.AnsiPos( "content-type:" ) ) != 0 )

{

nItems ++;

strLine = strLine.SubString( pos + 13, len - pos - 12 );

if( strLine.AnsiPos( "text/plain" ) != 0 )

nTextKind = 10;

else if( strLine.AnsiPos( "text/html" ) != 0 )

nTextKind = 11;

else

nTextKind = 12;

pCH->nType = nTextKind;

}

else if( ( pos = strLine.AnsiPos( "content-transfer-encoding:" ) ) != 0 )

{

nItems ++;

pCH->strTransferEncoding = strLine.SubString( pos + 27, len - pos - 26 );

}

else if( strLine.AnsiPos( "content-disposition:" ) != 0 )

{

if( ( pos = strLine.AnsiPos( "filename=\"" ) ) != 0 )

{

nItems ++;

pCH->strFileName = strTemp.SubString( pos + 10, len - pos - 10 );

}

}

else if( ( pos = strLine.AnsiPos( "filename=\"" ) ) != 0 )

{

nItems ++;

pCH->strFileName = strTemp.SubString( pos + 10, len - pos - 10 );

}

break;

case 555 :

file://接收内容to pCH->strContent

if( strTemp == "." )

{

CHList->Add( pCH );

nItemKind = ALL_READY;

break;

}

if( strTemp.AnsiPos( strExpandBoundary ) != 0 )

{

CHList->Add( pCH );

pCH = new ContentHeader;

if( strTemp.AnsiPos ( strExpandBoundary + "--" ) == 0 )//未到最后

{

nItemKind = 444;

nItems = 0;

}

else

{

nItemKind = 1;

bBoundary = true;

break;

}

}

else

{

pCH->strContent += strTemp;

pCH->strContent += "\r\n";

}

break;

}

}

将收取的邮件原文分行处理

mail为TMemoryStream*, 存放的是邮件原文。

int __fastcall TRecvMailThread::DealMailInfo()

{

int len = mail->Size;

int rval, i = 0;

mail->Position = 0;

char line[ 1024 ];

nItems = 0;

nItemKind = 0;

nTextKind = 0;//default

bAttach = false;

bBoundary = false;

strFrom = "";

strTo = "";

strSubject = "";

strTempEncode = "";

pCH = new ContentHeader;//初始生成一ContentHeader结构

while( mail->Position < len )

{

if( i >= 1022 )//一行长度超出1024

{

line[ i ] = 0;

DealLine( line, i );

if( nItems == ALL_READY )

{

return 1;//完成

}

i = 0;

}

mail->ReadBuffer( line + i, 1 );

if( line[ i ] == '\r')

{

i ++;

mail->ReadBuffer( line + i, 1 );

if( line[ i ] == '\n')

{

line[ i - 1 ] = 0;

DealLine( line, i - 1 );

if( nItemKind == ALL_READY )

{

return 1;//完成

}

i = -1;

}

else

{

mail->Position -= 1;

i -= 1;

}

}

i ++;

}

return 1;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航