email.cpp
来自「解析email的源代码。 mine协议 解码译码」· C++ 代码 · 共 517 行
CPP
517 行
#include "email.h"
#include <algorithm>
#include <fstream>
#include <iostream>
using namespace std;
string& trimLeft(string& str);
string trimRight(string& str);
string& removeEnter(string& str);
string dealWithHead(string& head);
//---------------------
//mail_node的构造函数
mail_node::mail_node()
{
code=plain;
content_type=text;
tag=nohtml;
bodyBeg=NULL;
bodyEnd=NULL;
bound="";
uncodeContent="";
}
Xcontent_type mail_node::getContent_type()
{return content_type;}
Xtag mail_node::getTag()
{return tag;}
Xcode mail_node::getCode()
{return code;}
Xmail_nodes& mail_node::getMail_nodes()
{
return mail_nodes;
}
string& mail_node::getContent()
{
content=removeEnter(trimRight(trimLeft(content)));
return content;
}
//--------------------------
//mail的构造函数
mail::mail()
{
from="";
subject="";
to="";
}
string mail::getSubject()
{
subject=dealWithHead(subject);
return subject;
}
string mail::getFrom()
{
from=dealWithHead(from);
return from;
}
string mail::getTo()
{
to=dealWithHead(to);
return to;
}
//-----------------------------
//node load
mail* mail_node::getMail()
{
return Mail;
}
char* mail_node::nodeload(const char* str)
{
//提取文本/html类型,编码,文档结构
//标记body开始部分,结束部分
char* p=(char*)str;
char* pEnd=p;
string lowtemp="",temp=""; //临时存储用
string::size_type pos;
if(pEnd==NULL)
return NULL;
while(*(pEnd)!=NULL)
{//
if(*pEnd=='\n')
{
temp.assign(p,pEnd);
temp=trimLeft(temp);
lowtemp=temp;
if(!temp.empty())
{
for(int i=0; i<temp.size(); i++)
{lowtemp[i]=char(tolower(lowtemp[i]));} //转成小写
pos=0;
if((pos=lowtemp.find("content-type:"))!=string::npos)
{
if((pos=lowtemp.find("text"))!=string::npos)
{
content_type=text;pos=0;
}
if((pos=lowtemp.find("multipart"))!=string::npos)
{
content_type=multipart;pos=0;
if((pos=lowtemp.find("boundary"))!=string::npos)
{
string::size_type pre,back;
pre=temp.find_first_of("\"",pos);
back=temp.find_last_of("\"",temp.size());
bound.assign(temp,pre+1,back-pre-1);
pos=0;
}
}
if((pos=lowtemp.find("html"))!=string::npos)
{
tag=html;pos=0;
}
if((pos=lowtemp.find("plain"))!=string::npos)
{
tag=nohtml;pos=0;
}
}
if((pos=lowtemp.find("boundary"))!=string::npos)
{
string::size_type pre,back;
pre=temp.find_first_of("\"",pos);
back=temp.find_last_of("\"",temp.size());
bound.assign(temp,pre+1,back-pre-1);
pos=0;
}
if((pos=lowtemp.find("content-transfer-encoding:"))!=string::npos)
{
if((pos=lowtemp.find("base64"))!=string::npos)
{
code=Base64;pos=0;
}
if((pos=lowtemp.find("quoted-printable"))!=string::npos)
{
code=qp;pos=0;
}
}
temp="";lowtemp="";
}
else
{
break;
}
p=pEnd+1;
}
pEnd++;
}
//查找边界
p=++pEnd; //定位到第一个空行后面第一个字符
if(content_type==text)
{
bodyBeg=p;
while(*(pEnd+1)!=NULL)
{
pEnd++;
}
bodyEnd=pEnd;
content.assign(bodyBeg,bodyEnd);
}
//multipart的情况的处理
if(content_type==multipart)
{
bodyBeg=p;
char *f=NULL, *e=NULL; //f指向子结点的头,e指向字节点的尾
while(*(pEnd+1)!=NULL)
{
if(*pEnd=='\n')
{
temp.assign(p,pEnd);
if((pos=temp.find(bound))!=string::npos)
{
if(f==NULL)
{
e=pEnd+1;
f=e;
}
else
{
e=p-1;
string node_fulltext="";
node_fulltext.assign(f,e);
node_fulltext=trimLeft(node_fulltext);
mail_node* node = new mail_node;
node->Mail=Mail;
char* end;
if((end = node->nodeload(node_fulltext.c_str()))==NULL)
{
delete node;
return NULL;
}
mail_nodes.push_back(node);
}
}
p=pEnd+1;
}
pEnd++;
}
bodyEnd=pEnd;
content.assign(bodyBeg,bodyEnd);
return pEnd;
}
//------------------------------------------------------------
return pEnd;
}
string& mail_node::getUncodeContent()
{
if(content_type==text)
{
if(code==Base64)
{
unBase64(getContent(),uncodeContent);
if(tag==html)
{
uncodeContent=convertHtml(uncodeContent);
}
return uncodeContent;
}
else if(code==qp)
{
DecodeQuoted(getContent(),uncodeContent,getContent().size());
if(tag==html)
{
uncodeContent=convertHtml(uncodeContent);
}
return uncodeContent;
}
else
{
uncodeContent=content;
if(tag==html)
{
uncodeContent=convertHtml(uncodeContent);
}
return uncodeContent;
}
}
else
return uncodeContent;
}
void mail_node::setMail(mail* Mail)
{
this->Mail=Mail;
}
//--------------------------------
//mail load
void mail::load(const char* str)
{
mail_node* node = new mail_node;
setMail(this);
//------------------------------------------------
//提取发件人,收件人,主题
char* p=(char*)str;
char* pEnd=p;
string lowtemp="",temp=""; //临时存储用
while(*(pEnd)!=NULL)
{//
if(*pEnd=='\n')
{
temp.assign(p,pEnd);
temp=trimLeft(temp);
lowtemp=temp;
if(!temp.empty())
{
for(int i=0; i<temp.size(); i++)
{lowtemp[i]=char(tolower(lowtemp[i]));} //转成小写
string::size_type pos=0;
if(lowtemp.compare(0,5,"from:")==0)
{from.assign(temp,pos+5,temp.size());pos=0;}
if(lowtemp.compare(0,3,"to:")==0)
{to.assign(temp,pos+3,temp.size());pos=0;}
if(lowtemp.compare(0,8,"subject:")==0)
{subject.assign(temp,pos+8,temp.size());pos=0;}
temp="";
lowtemp=temp;
}
else
break;
p=pEnd+1;
}
pEnd++;
}
//-------------------------------------------------------------
bodyBeg=++p;
char* end;
if((end = node->nodeload(str))==NULL)
{
delete node;
}
else
{
bodyEnd=end;
content.assign(bodyBeg,bodyEnd);
mail_nodes.push_back(node);
}
}
string& mail::getfile(const char* str)
{
ifstream ifile(str);
if(!ifile)
{
cerr<<"file can not be open!";
return fulltext;
}
string temp="";
while(!ifile.eof())
{
getline(ifile,temp);
fulltext+=temp;
fulltext+="\n";
}
return fulltext;
}
//程序处理中的辅助函数
string& trimLeft(string& str)
{//去掉空格和tab
char* p=(char*)str.c_str();
int i=0;
while(p)
{
if(*p==' '||*p==' ')
{
p++;
i++;
}
else
break;
}
str.assign(str,i,str.size()-i);
return str;
}
string trimRight(string& str)
{
char* p=(char*)(str.end()-1);
int i=0;
while(p)
{
if(*p==' '||*p==' '||*p=='\n')
{
p--;
i++;
}
else
break;
}
str.assign(str,0,str.size()-i);
return str;
}
string& removeEnter(string& str)
{
char* p=(char*)str.c_str();
string::size_type pre=0, post=0;
while((post=str.find_first_of("\n",pre))!=string::npos)
{
str.erase(p+post);
pre=post;
}
return str;
}
void unBase64(string & content, string &uncoded)
{
uncoded="";
char t = NULL;
char chuue[4] = {' ',' ',' ',' '};
char chasc[3] = {' ',' ',' '};
for(int k = 0; k < content.size()/4; k++)
{
for(int j = 0; j < 4; j++)
{
chuue[j] = *(content.c_str()+4*k+j);
}
int i,k=2;
unsigned char t=NULL;
for(i=0;i<4;i++)
{
if((*(chuue+i)>=65)&&(*(chuue+i)<=90)) *(chuue+i)-=65;
else if((*(chuue+i)>=97)&&(*(chuue+i)<=122)) *(chuue+i)-=71;
else if((*(chuue+i)>=48)&&(*(chuue+i)<=57)) *(chuue+i)+=4;
else if(*(chuue+i)==43) *(chuue+i)=62;
else if(*(chuue+i)==47) *(chuue+i)=63;
else if(*(chuue+i)==61) *(chuue+i)=0;
}
for(i=0;i<3;i++)
{
*(chasc+i)=*(chuue+i)<<k;
k+=2;
t=*(chuue+i+1)>>(8-k);
*(chasc+i)|=t;
}
uncoded.append(chasc, 3);
}
}
void DecodeQuoted(string & content, string & uncoded, int size)
{
char ch1;
char ch2;
char ch3;
string temp2 = "";
const char * p = content.c_str();
int i = 0; //count
while(i < size)
{
if(*p == ' ')
{
p++;
i++;
continue;
}
if(*p == '=')
{
if(i < size)
{
ch1 = content[++i];
ch2 = content[++i];
ch3 = (ch1>'9'?(ch1-'A'+10):(ch1-'0'))*16+ (ch2>'9'?(ch2-'A'+10):(ch2-'0'));
temp2 = ch3;
uncoded = uncoded + temp2;
i++;
p+=3;
}
else
{
continue;
}
}
else
{
temp2 = *p;
uncoded = uncoded + temp2;
p++;
i++;
}
}
}
string& convertHtml(string& html)
{
char* p=(char*)html.c_str();
char* pre, *post;
while(*p!=NULL)
{
if(*p=='<')
{
pre=p;
p++;
}
else
if(*p=='>')
{
post=p;
html.erase(pre,post+1);
post=pre;
p=pre;
}
else
p++;
}
return html;
}
string dealWithHead(string& head)
{
string text=head;
string::size_type pos=0;
if((pos=head.find_last_of("?",head.size()))!=string::npos)
{
head.erase(pos,head.size()-pos);
pos=head.find_last_of("?",head.size());
head.erase(0,pos+1);
unBase64(head,text);
}
return text;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?