TinyMail研究—邮件的表示与解析
来源:互联网 发布:手机淘宝怎么认证 编辑:程序博客网 时间:2024/05/30 05:42
TinyMail研究—邮件的表示与解析
转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd
作者联系方式:李先静<xianjimli at hotmail dot com>
更新时间:2007-4-17
TinyMail是一套针对移动设备设计的邮件系统框架,为了达到最大的灵活性,它采用了很多设计模式和先进的编程技术,让框架的每一部分都可以定制和配置。TinyMail流行的趋势非常明显,Nokia770/800和GPE Phone Edition等项目中都使用了它。因为我们也要开发邮件系统,所以花了几天时间去研究它的实现,这里记录一些研究笔记,供有兴趣的朋友参考。本文介绍一下邮件的表示与解析。
在TinyMail中,表示邮件的类以及它们之间的关系如下图所示:
CamelObject是所有类的基类,它提供类型系统的实现、引用计数、signal机制等基本功能。
CamelDataWrapper 它提供了对数据对象的包装,可以调用set_mime_type/ get_mime_type去设置/获取数据对象的类型,可以调用write_to_stream/ decode_to_stream把数据对象写到流中去,也可以调用construct_from_stream从流中构造数据对象。这些函数都是虚函数,可以在子类中重载。
CamelMedium 它提供了邮件的基本雏形:邮件头和邮件体。可以调用add_header/ set_header/ remove_header/ get_header/ free_headers/ get_headers去操作邮件头,可以调用set_content_object /get_content_object去存取邮件体。
CamelMimePart 它代表Mime邮件的一个Part,每个Part都有自己的邮件头来描述Content-Type和Content-ID等信息,也都有自己的邮件体(通常是一个文件),所以它继承了CamelMedium接口。
CamelMimeMessage 它代表一个完整的Mime邮件,它没有自己的虚函数,只是实现了CamelMedium定义的接口函数,并包装了一些实用的函数。
CamelMultipart 它代表multipart/*类型的Mime-Message的邮件体,可以调用add_part/add_part_at/remove_part/remove_part_at去增删其中的CamelMimePart对象,可以调用get_part/get_number去访问中的CamelMimePart对象。
CamelMultipartSigned/CamelMultipartEncrypted 它们实现了CamelMultipart,用于表示mutlipart/signed和mutlipart/encrypted类型的MultiPart邮件。
下面是一个创建邮件的例子:
create_mail.c
#include <string.h>
#include <camel/camel.h>
int main(int argc, char* argv[])
{
CamelMimeMessage *msg;
CamelInternetAddress *addr;
const char *text;
CamelMultipart *mp;
CamelMimePart *part;
CamelStream* stream;
msg = camel_mime_message_new();
camel_mime_message_set_subject(msg, "Talking to myself again");
addr = camel_internet_address_new();
camel_internet_address_add(addr, "NotZed", "notzed@somewhere.com");
camel_mime_message_set_from(msg, addr);
camel_address_remove(CAMEL_ADDRESS(addr), -1);
camel_internet_address_add(addr, "NotZed", "notzed@somewhere.else.com");
camel_mime_message_set_recipients(msg, "To", addr);
camel_object_unref(addr);
mp = camel_multipart_new();
camel_data_wrapper_set_mime_type(CAMEL_DATA_WRAPPER(mp), "multipart/alternative");
camel_multipart_set_boundary(mp, NULL);
camel_multipart_set_preface(mp, "This is a message in MIME format. Get with the decade/n");
camel_multipart_set_postface(mp, "/nSome useless after-message text you should never see/n/n");
part = camel_mime_part_new();
text = "Hello NotZed,/nTalking to yourself again?/n/n NotZed/n";
camel_mime_part_set_content(part, text, strlen(text), "text/plain");
camel_multipart_add_part(mp, part);
camel_object_unref(part);
part = camel_mime_part_new();
text = "<html>/n<body>/nHello NotZed,<br>/nTalking to yourself again?<br>/n NotZed<br>/n</body>/n</html>/n";
camel_mime_part_set_content(part, text, strlen(text), "text/html");
camel_multipart_add_part(mp, part);
camel_object_unref(part);
camel_medium_set_content_object(CAMEL_MEDIUM(msg), CAMEL_DATA_WRAPPER(mp));
stream = camel_stream_fs_new_with_name("./test.eml", O_CREAT|O_RDWR, 0664);
camel_data_wrapper_write_to_stream(CAMEL_DATA_WRAPPER(msg), stream);
camel_object_unref(msg);
camel_stream_close(stream);
return 0;
}
Makefile:
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
FLAGS=-g `pkg-config --libs --cflags camel-lite-1.2 glib-2.0`
all:
gcc $(FLAGS) create_mail.c -o create_mail.exe
clean:
rm -f *.exe
邮件的解析是由CamelMimeParser完成,它采用了基于栈的下推自动机实现。其状态转换如下图所示:
参考资料:
http://www.go-evolution.org
~~end~~
- TinyMail研究—邮件的表示与解析
- TinyMail研究—类型系统
- TinyMail研究—Camel-lite的插件系统
- 使用TinyMail的API函数发送邮件
- TinyMail研究—Stream及相关设计模式
- 邮件的解析与显示
- 利用TinyMail发送Email的关键代码
- 信号的解析表示
- Java打印整数的二进制表示(代码与解析)
- 面向对象的邮件解析器的设计与实现
- 查到的别人稀疏表示的研究
- Expresso表示层的深入使用研究
- 研究递归函数的堆栈表示
- 【HEVC学习与研究】44、HEVC量化系数的解析——反量化过程
- Java包导入机制的研究与解析
- Java包导入机制的研究与解析
- 【HEVC学习与研究】18.HEVC的条带头解析
- 邮件那些事3—解析邮件Received数量问题与识别发件人IP
- 用flashget的同志们小心了
- DIV+CSS布局
- CImageList
- 请问通常java程序员做一年薪水是做少呢?
- (转)调用Java编译器API编译Java
- TinyMail研究—邮件的表示与解析
- 解决Oracle XDB与Tomcat等的8080端口的冲突
- test
- 我写的一个自定义分页标签
- java查询分页技术(1)
- Jdk和Tomcat的安装与配置
- 用WriteProcessMemory做进程注入
- java查询分页技术(2)
- 编译reactos