TinyMail研究—邮件的表示与解析

TinyMail研究—邮件的表示与解析

转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd

作者联系方式:李先静<xianjimli at hotmail dot com>

更新时间:2007-4-17

TinyMail是一套针对移动设备设计的邮件系统框架,为了达到最大的灵活性,它采用了很多设计模式和先进的编程技术,让框架的每一部分都可以定制和配置。TinyMail流行的趋势非常明显,Nokia770/800GPE Phone Edition等项目中都使用了它。因为我们也要开发邮件系统,所以花了几天时间去研究它的实现,这里记录一些研究笔记,供有兴趣的朋友参考。本文介绍一下邮件的表示与解析。

TinyMail中,表示邮件的类以及它们之间的关系如下图所示:

<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 276pt" type="#_x0000_t75" o:ole=""><imagedata src="file:///C:/DOCUME~1/q/LOCALS~1/Temp/msoclip1/01/clip_image001.png" o:title=""></imagedata></shape>

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-TypeContent-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/signedmutlipart/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&nbsp;&nbsp;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完成,它采用了基于栈的下推自动机实现。其状态转换如下图所示:

<shape id="_x0000_i1026" style="WIDTH: 415.5pt; HEIGHT: 392.25pt" type="#_x0000_t75" o:ole=""><imagedata src="file:///C:/DOCUME~1/q/LOCALS~1/Temp/msoclip1/01/clip_image003.png" o:title=""><font size="3"></font></imagedata></shape>

参考资料:

http://www.go-evolution.org

~~end~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值