邮件解析(源码)

    技术2022-05-11  116

    存储邮件信息的结构:

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


    最新回复(0)