LifeMotif: GMail-based Private Diary System에 필요한 이메일 파서 라이브러리.
Mimetic에서 제공하는 상당량에 대한 필드 파싱 정보에 대한 예제 코드
#include <iostream> #include <sstream> #include <iterator> #include <fstream> #include <iterator> #include <string> #include <algorithm> #include <mimetic/mimetic.h> void read(const std::string& filename, std::string& content) { if (content.empty() == false) { std::string().swap(content); } std::ifstream ifs; ifs.open(filename); while ( ifs.good() ) { char c = ifs.get(); if (ifs.good()) content.push_back(c); } } void print_param_header(const std::string& param_name) { std::cout << "["; std::cout << param_name; std::cout << "]\n"; } void print_param_footer() { std::cout << '\n'; } void parse_mailbox(const mimetic::Mailbox& mb) { const std::string mailbox = mb.mailbox(); const std::string domain = mb.domain(); const std::string label = mb.label(); const std::string sourceroute = mb.sourceroute(); const std::string str = mb.str(); std::cout << "mailbox: " << mailbox << '\n'; std::cout << "domain: " << domain << '\n'; std::cout << "label: " << label << '\n'; std::cout << "sourceroute: " << sourceroute << '\n'; std::cout << "str: " << str << '\n'; } void parse_mailbox_list(const mimetic::MailboxList& mblist) { mimetic::MailboxList::const_iterator it; for(it = mblist.begin(); it != mblist.end(); ++it) { const mimetic::MailboxList::value_type& v = *it; parse_mailbox(v); } } void parse_group(const mimetic::Group& group) { print_param_header("group"); std::cout << "group: " << group.name() << std::endl; print_param_footer(); } void parse_address(const mimetic::Address & adr) { const mimetic::Mailbox& mailbox = adr.mailbox(); const mimetic::Group& group = adr.group(); bool isGroup = adr.isGroup(); parse_mailbox(mailbox); std::cout << "isGroup: " << isGroup << std::endl; parse_group(group); } void parse_address_list(const mimetic::AddressList& adrList) { mimetic::AddressList::const_iterator it; for(it = adrList.begin(); it != adrList.end(); ++it) { const mimetic::Address& adr = *it; parse_address(adr); } } void parse_mime_version(const mimetic::MimeVersion &mimeVersion) { std::cout << mimeVersion.str() << std::endl; } void parse_messageid(const mimetic::MessageId& messageid) { std::cout << messageid.str() << std::endl; } void parse_field_param(const mimetic::FieldParam& param) { std::cout << "name/value: " << param << std::endl; const std::string& name = param.name(); const std::string& value = param.value(); std::cout << " name: " << name << std::endl; std::cout << " value: " << value << std::endl; } void parse_content_type(const mimetic::ContentType& contentType) { const std::string &type = contentType.type(); const std::string &subtype = contentType.subtype(); bool isMultipart = contentType.isMultipart(); const mimetic::FieldParamList ¶mList = contentType.paramList(); std::cout << "type: " << type << '\n'; std::cout << "subtype: " << subtype <<'\n'; std::cout << "isMultipart: " << isMultipart << '\n'; mimetic::FieldParamList::const_iterator it; for(it = paramList.begin(); it != paramList.end(); ++it) { const mimetic::FieldParam& param = *it; parse_field_param(param); } } void parse_content_transfer_encoding(const mimetic::ContentTransferEncoding &content_transfer_encoding) { const std::string& mechanism = content_transfer_encoding.mechanism(); std::cout << "mechanism: " << mechanism << std::endl; } void parse_content_disposition(const mimetic::ContentDisposition &content_disposition) { const std::string &type = content_disposition.type(); const mimetic::FieldParamList ¶mList = content_disposition.paramList(); std::cout << "type: " << type << '\n'; mimetic::FieldParamList::const_iterator it; for(it = paramList.begin(); it != paramList.end(); ++it) { const mimetic::FieldParam& param = *it; parse_field_param(param); } } void parse_content_description(const mimetic::ContentDescription &content_description) { std::cout << content_description.str() << std::endl; } void parse_content_id(const mimetic::ContentId &content_id) { std::cout << content_id.str() << std::endl; } void parse_Rfc822_header(const mimetic::Rfc822Header& header) { // Rfc822Header class const mimetic::Mailbox &sender = header.sender(); const mimetic::MailboxList &from = header.from(); const mimetic::AddressList &to = header.to(); const std::string &subject = header.subject(); const mimetic::AddressList &replyto = header.replyto(); const mimetic::AddressList &cc = header.cc(); const mimetic::AddressList &bcc = header.bcc(); const mimetic::MessageId &msgid = header.messageid(); if (header.hasField("Content-Type")) { std::cout << header.field("Content-Type") << std::endl; } // Rfc822Header class print_param_header("sender"); parse_mailbox(sender); print_param_footer(); print_param_header("from"); parse_mailbox_list(from); print_param_footer(); print_param_header("to"); parse_address_list(to); print_param_footer(); print_param_header("subject"); std::cout << subject << std::endl; print_param_footer(); print_param_header("replyto"); parse_address_list(replyto); print_param_footer(); print_param_header("cc"); parse_address_list(cc); print_param_footer(); print_param_header("bcc"); parse_address_list(bcc); print_param_footer(); print_param_header("messageid"); parse_messageid(msgid); print_param_footer(); } void parse_header(const mimetic::Header& header) { parse_Rfc822_header(header); // Header class const mimetic::MimeVersion &mimeVersion = header.mimeVersion(); const mimetic::ContentType &contentType = header.contentType(); const mimetic::ContentTransferEncoding &cte = header.contentTransferEncoding(); const mimetic::ContentDisposition &cdispo = header.contentDisposition(); const mimetic::ContentDescription &cdescr = header.contentDescription(); const mimetic::ContentId &contentId = header.contentId(); print_param_header("Mime-Version"); parse_mime_version(mimeVersion); print_param_footer(); print_param_header("Content-Type"); parse_content_type(contentType); print_param_footer(); print_param_header("Content-Transfer-Encoding"); parse_content_transfer_encoding(cte); print_param_footer(); print_param_header("Content-Disposition"); parse_content_disposition(cdispo); print_param_footer(); print_param_header("Content-Description"); parse_content_description(cdescr); print_param_footer(); print_param_header("Content-Id"); parse_content_id(contentId); print_param_footer(); } void parse_body(const mimetic::Body& body); void parse_mime_entity(const mimetic::MimeEntity& entity); void parse_mime_entity(const mimetic::MimeEntity& entity) { const mimetic::Header& header = entity.header(); const mimetic::Body& body = entity.body(); parse_header(header); parse_body(body); } void parse_body(const mimetic::Body& body) { const std::string& preamble = body.preamble(); const std::string& epilogue = body.epilogue(); const mimetic::MimeEntityList& parts = body.parts(); print_param_header("preamble"); std::cout << preamble << std::endl; print_param_footer(); print_param_header("epilogue"); std::cout << epilogue << std::endl; print_param_footer(); const mimetic::MimeEntity* owner = body.owner(); const mimetic::Header& header = owner->header(); const mimetic::ContentType contentType = header.contentType(); print_param_header("body (encoded)"); std::cout << body << std::endl; print_param_footer(); if (contentType.type() == "text") { const mimetic::ContentTransferEncoding& encoding = header.contentTransferEncoding(); if (encoding.mechanism() == mimetic::ContentTransferEncoding::base64) { mimetic::Base64::Decoder decoder; std::string decoded; std::stringstream str; std::ostreambuf_iterator<char> oi(str); mimetic::decode(body.begin(), body.end(), decoder, oi); print_param_header("body (decoded)"); decoded = str.str(); std::cout << decoded << std::endl; print_param_footer(); } } mimetic::MimeEntityList::const_iterator it; for(it = parts.begin(); it != parts.end(); ++it) { const mimetic::MimeEntity& entity = **it; parse_mime_entity(entity); } } void simple_parse(const std::string& content) { mimetic::MimeEntity root_entity(content.begin(), content.end()); parse_mime_entity(root_entity); } int main(int argc, char** argv) { if (argc != 2) { std::cerr << "Please input a file." << std::endl; return EXIT_FAILURE; } std::string content; read(argv[1], content); //std::cout << content << std::endl; simple_parse(content); return EXIT_SUCCESS; }