root/MimeDecode.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. CMimeDecode
  2. CMimeDecode
  3. GetBody
  4. GetContentType
  5. GetEncodingType
  6. GetFileName
  7. GetRawCT
  8. GetRawCD
  9. GetRawCTE
  10. GetMultipartType
  11. HowManyPart
  12. IsMultipart
  13. GetHeaderEndPoint
  14. DoIt2
  15. DoIt
  16. AnalyzeMultiPart
  17. Initialize
  18. IsPgpMime
  19. GetCharSet

/*
 * Copyright (C) 2002-2003 chik, s.hiranaka
 * For license terms, see the file COPYING in this directory.
 */

// MimeDecode.cpp: CMimeDecode クラスのインプリメンテーション
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Pochy.h"
#include "MimeDecode.h"
#include <afxtempl.h>   // CArrayテンプレートクラスに必要
#include "lib.h"


//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////

CMimeDecode::CMimeDecode()
{

}

CMimeDecode::~CMimeDecode()
{

}

// partで指定されたmultipartのbodyをdst(CStringArray)へ書き込む
void CMimeDecode::GetBody(int part, CStringArray &dst)
{
        int start;
        int end;

        start = m_data.GetAt(part).end_header+2;
        end = m_data.GetAt(part).end;
        g_cstra_getpart(m_mail, dst, start, end);
}

CString CMimeDecode::GetContentType(int part)
{
        return m_data[part].content_type;
}

int CMimeDecode::GetEncodingType(int part)
{
        return m_data[part].encoding_type;
}

CString CMimeDecode::GetFileName(int part)
{
        return m_data[part].name;
}

CString CMimeDecode::GetRawCT(int part)
{
        return m_data[part].raw_content_type;
}

CString CMimeDecode::GetRawCD(int part)
{
        return m_data[part].raw_content_disposition;
}

CString CMimeDecode::GetRawCTE(int part)
{
        return m_data[part].raw_content_transfer_encoding;
}

CString CMimeDecode::GetMultipartType()
{
        CString buf;
        int start;
        int end;

        if(IsMultipart()){
                buf = m_hi.GetCT();
                start = buf.Find("/")+1;
                end = buf.Find(";", start);
                return buf.Mid(start, end-start);
        }

        buf.Empty();
        return buf;
}

int CMimeDecode::HowManyPart()
{
        return m_data.GetSize();
}

BOOL CMimeDecode::IsMultipart()
{
        return m_hi.IsMultipart();
}

BOOL CMimeDecode::GetHeaderEndPoint(CStringArray &mail, int &p)
{
        int n = 0;

        while(n < mail.GetSize()){
                mail.GetAt(n);
                if(mail.GetAt(n) == "\x0D\x0A"){
                        p = n-1;
                        break;
                }
                n++;
        }
        return TRUE;
}

BOOL CMimeDecode::DoIt2(CString mail)
{
        Initialize();

        int p = 0; // headerの終わり
        g_cstr2cstra(mail, m_mail, "\r\n");
        GetHeaderEndPoint(m_mail, p);
        if(p == 0){
                AfxMessageBox("メールが壊れてます(ヘッダが見当たりません)");
                return FALSE;
        }

        CStringArray header;
        g_cstra_getpart(m_mail, header, 0, p);
        m_hi.DoIt(header);

        MULTIPART_STRUCT data;
        int n;

        if(IsMultipart()){
                if(!AnalyzeMultiPart(0, m_hi.GetBoundary())){
                        AfxMessageBox("MIMEの構造が変です");
                        return FALSE;
                }
                n = 0;
                while(n < m_data.GetSize()){
                        if(!m_data.GetAt(n).boundary.IsEmpty())
                                if(!AnalyzeMultiPart(m_data.GetAt(n).start, m_data.GetAt(n).boundary)){
                                        AfxMessageBox("MIMEの構造が変です");
                                        return FALSE;
                                }
                        n++;
                }

                // multipart入れ子構造の親を削除
                n = 0;
                while(n < m_data.GetSize()){
                        if(!m_data.GetAt(n).boundary.IsEmpty()){
                                m_data.RemoveAt(n);
                        }
                        n++;
                }
        }else{
                data.start = 0;
                GetHeaderEndPoint(m_mail, p);
                data.end_header = p;
                data.end = m_mail.GetSize()-1;
                data.name = m_hi.GetFilename();
                if(data.name.IsEmpty())
                        data.name = m_hi.GetName();
                data.content_type = m_hi.GetCType();
                data.encoding_type = m_hi.GetEnc();
                m_data.Add(data);
        }
        return TRUE;
}
BOOL CMimeDecode::DoIt(CString path)
{
        Initialize();

        CString message;
        if(!g_is_there(path)){
                message.Format("%s が存在しないため開けません", path);
                AfxMessageBox(message);
                message.Empty();
                return FALSE;
        }

        int p = 0; // headerの終わり
        CStringArray header;
        g_file2cstra(path, m_mail);
        GetHeaderEndPoint(m_mail, p);
        if(p == 0){
                AfxMessageBox("メールが壊れてます(ヘッダが見当たりません)");
                return FALSE;
        }
        g_cstra_getpart(m_mail, header, 0, p);
        m_hi.DoIt(header);

        MULTIPART_STRUCT data;
        int n;

        if(IsMultipart()){
                if(!AnalyzeMultiPart(0, m_hi.GetBoundary())){
                        AfxMessageBox("MIMEの構造が変です");
                        return FALSE;
                }
                n = 0;
                while(n < m_data.GetSize()){
                        if(!m_data.GetAt(n).boundary.IsEmpty())
                                if(!AnalyzeMultiPart(m_data.GetAt(n).start, m_data.GetAt(n).boundary)){
                                        AfxMessageBox("MIMEの構造が変です");
                                        return FALSE;
                                }
                        n++;
                }

                // multipart入れ子構造の親を削除
                n = 0;
                while(n < m_data.GetSize()){
                        if(!m_data.GetAt(n).boundary.IsEmpty()){
                                m_data.RemoveAt(n);
                        }
                        n++;
                }
        }else{
                data.start = 0;
                GetHeaderEndPoint(m_mail, p);
                data.end_header = p;
                data.end = m_mail.GetSize()-1;
                data.name = m_hi.GetFilename();
                if(data.name.IsEmpty())
                        data.name = m_hi.GetName();
                data.content_type = m_hi.GetCType();
                data.encoding_type = m_hi.GetEnc();
                data.raw_content_type = m_hi.GetCT();
                data.raw_content_transfer_encoding = m_hi.GetCTE();
                data.raw_content_disposition = m_hi.GetCD();
                m_data.Add(data);
        }
        return TRUE;
}

BOOL CMimeDecode::AnalyzeMultiPart(int start, CString boundary)
{
        int n1;
        int n2;
        int p;
        CUIntArray ia;
        CHeaderInfo hi;
        CStringArray part;
        CString sep = "--"+boundary+"\r\n";
        CString last = "--"+boundary+"--"+"\r\n";
        CStringArray pheader;
        MULTIPART_STRUCT data;

        n1 = start;
        while(n1 < m_mail.GetSize()){
                if(m_mail.GetAt(n1) == sep){
                        ia.Add(n1);
                        n1++;
                        continue;
                }
                if(m_mail.GetAt(n1) == last){
                        ia.Add(n1);
                        break;
                }
                n1++;
        }

        if(ia.GetSize() < 2)
                return FALSE;

        n2 = 0;
        while(n2+1 < ia.GetSize()){
                g_cstra_getpart(m_mail, part, ia.GetAt(n2)+1, ia.GetAt(n2+1)-1);
                GetHeaderEndPoint(part, p);
                g_cstra_getpart(m_mail, pheader, ia.GetAt(n2)+1, ia.GetAt(n2)+1+p);
                hi.DoIt(pheader);

                data.start = ia.GetAt(n2)+1;
                data.end_header = data.start+p;
                data.end = ia.GetAt(n2+1)-1;
                data.boundary = hi.GetBoundary();
                data.content_type = hi.GetCType();
                data.encoding_type = hi.GetEnc();
                data.name = hi.GetFilename();
                if(data.name.IsEmpty())
                        data.name = hi.GetName();
                data.raw_content_type = hi.GetCT();
                data.raw_content_transfer_encoding = hi.GetCTE();
                data.raw_content_disposition = hi.GetCD();
                m_data.Add(data);
                n2++;
        }
        return TRUE;
}

void CMimeDecode::Initialize()
{
        // 変数の初期化
        m_data.RemoveAll();
        m_mail.RemoveAll();
}

BOOL CMimeDecode::IsPgpMime()
{
        return g_cstr_compare(m_hi.GetProtocol(), "application/pgp-encrypted");
}

CString CMimeDecode::GetCharSet()
{
        return m_hi.GetCharset();
}

/* [<][>][^][v][top][bottom][index][help] */