int OpenFile(char * pszFileName);
int DecodeLine(char * pszLine, int nLineLen);
int DecodeLine(char * pszLine, int nLineLen, uchar * uchBuffer, int nBufferLen);
};
int DecodeValue(const int c)
{
// Note that this works only on ASCII machines.
if ('A' <= c && c <= 'Z')
return c - 'A';
if ('a' <= c && c <= 'z')
return c - 'a' + 26;
if ('0' <= c && c <= '9')
return c - '0' + 52;
if (c == '+')
return 62;
if (c == '/')
return 63;
if (c == '=')
return -1;
return -2;
}
/////////////////////////////////////////////////////////////////////////////
// Function: CBase64Dec::OpenFile
// Description:
// Open a file that we can write the characters to.
/////////////////////////////////////////////////////////////////////////////
int CBase64Dec::OpenFile(char * pszFileName)
{
// Open the file. Handle any errors.
//m_hfile = _lopen(pszFileName, OF_WRITE);
m_hfile=CreateFile(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
/////////////////////////////////////////////////////////////////////////////
// Function: CBase64Dec::DecodeLine
// Description:
// Decode a line of data and write the bytes to the open file.
/////////////////////////////////////////////////////////////////////////////
int CBase64Dec::DecodeLine(char * pszLine, int nLineLen)
{
DWORD Written;
uchar * uchBuffer = new uchar[nLineLen];
int nDecodedLen = DecodeLine(pszLine, nLineLen, uchBuffer, nLineLen);
if (nDecodedLen >= 0)
{
//if (_lwrite(m_hfile, (LPCSTR)uchBuffer, nDecodedLen) == (UINT)HFILE_ERROR)
if (WriteFile(m_hfile, (LPCSTR)uchBuffer, nDecodedLen, &Written, NULL) == NULL)
nDecodedLen = RESULT_ERROR;
}
delete[] uchBuffer;
return nDecodedLen;
}
/////////////////////////////////////////////////////////////////////////////
// Function: CBase64Dec::DecodeLine
// Description:
// Simply decode a line of bytes. Note that a file doesn't
// have to be opened to use this member function. Returns
// the count of the decoded bytes or -1 on error.
/////////////////////////////////////////////////////////////////////////////
int CBase64Dec::DecodeLine(char * pszLine, int nLineLen,
uchar * uchBuffer, int nBufferLen)
{
int iLineIndex = 0;
int iBufferIndex = 0;
while (iLineIndex < nLineLen)
{
// Group together four characters for decode.
while (iLineIndex < nLineLen && m_iChars < 4)
{
int c = pszLine[iLineIndex++];
// Ignore characters that aren't BASE64 characters
// (e.g., spaces, CRLF, etc.).
if (DecodeValue(c) != -2)
m_uchStoredChars[m_iChars++] = (uchar) c;
}
if (m_iChars == 4)
{
// We've got four characters, so decode them.
m_iChars = 0;
// Decode first byte.
if (iBufferIndex == nBufferLen) return RESULT_ERROR;
uchBuffer[iBufferIndex++] = (uchar) (((uchar)DecodeValue(m_uchStoredChars[0]) << 2) | ((uchar)DecodeValue(m_uchStoredChars[1]) >> 4));
// Decode second byte.
if (iBufferIndex == nBufferLen)
return RESULT_ERROR;
if (m_uchStoredChars[2] == '=')
return iBufferIndex;
uchBuffer[iBufferIndex++] = (uchar) (((uchar)DecodeValue(m_uchStoredChars[1]) << 4) | ((uchar)DecodeValue(m_uchStoredChars[2]) >> 2));
// Decode third byte.
if (iBufferIndex == nBufferLen)
return RESULT_ERROR;
if (m_uchStoredChars[3] == '=')
return iBufferIndex;
uchBuffer[iBufferIndex++] = (uchar) (((uchar)DecodeValue(m_uchStoredChars[2]) << 6) | ((uchar)DecodeValue(m_uchStoredChars[3])));
}
}
// Return the count of decoded bytes.
return iBufferIndex;
}
///////////////////////////////////////////////////////////////
//
//把邮件文件strPath中的附件提取出来存放在strDir目录下
//
///////////////////////////////////////////////////////////////
int CReceiverDlg::SaveAttToDisk(CString strDir,CString strPath)
{
CString sAttFileName;
CStdioFile rawFile;
if (!rawFile.Open(strPath,CFile::modeRead))
return -1; //无法打开文件
CString sLine;
bool bAtt=false;
int nEmpLine=0;
CBase64Dec* pB64D=new CBase64Dec();
int nAttNum=1;
BOOL bGetLine=TRUE;
while(bGetLine)
{
bGetLine=rawFile.ReadString(sLine);
int nStart=sLine.Find("filename=");
if (nStart>=0)
{
CString strTmp=sLine.Left(nStart+9);
sAttFileName=sLine;
sAttFileName.Replace(strTmp,"");
sAttFileName.Replace("\"","");
//由邮件文件名strPath构造附件名,绝对路经.
//存放目录为strDir
ConstructFileName(nAttNum,strPath,strDir,sAttFileName);
bAtt=true;
int nRet=pB64D->OpenFile(sAttFileName.GetBuffer(sAttFileName.GetLength()));
if (nRet==-1)
{
delete pB64D;
rawFile.Close();
return -1;
}
}
if (bAtt)
{
if (strstr(sLine,"filename="))
continue;
if (sLine=="")
{
if (nEmpLine==0)
{
nEmpLine++;
continue;
}
}
// then begin encoded attachment!
CString strSet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
if (sLine=="" || strSet.Find(sLine.GetAt(0))<0) //end of attachment
{
delete pB64D;
pB64D=new CBase64Dec();
if (sLine.Find("--#BOUNDARY#--")>=0) //完
{
goto ok;
}
nAttNum++; //附件数加1
bAtt=false;
nEmpLine=0;
continue;
}
int nLen=strlen(sLine);
pB64D->DecodeLine(sLine.GetBuffer(nLen),nLen);
}
}
if (!bAtt) //no "filename=" in raw, means no attachment
{
rawFile.Close();
delete pB64D;
pB64D=NULL;
return 0;
}