• TinyMail研究—Camellite的插件系统


    TinyMail研究—Camel-lite的插件系统

                 

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

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

    更新时间:2007-4-19

     

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

     

    邮件的收/发协议有好几种,比如SMTPPOPIMAP等等,Tinymail并不依赖于特定的收/发协议,这些协议都是以插件的方式加入进来的,扩展和裁减都很方便。Tinymail把协议的实现称为提供者(provider)

     

    提供者(provider)可以分为两类:STORETRANSPORT。前者实现CamelStore接口,用于邮件的接收,比如POP3IMAP。后者实现CamelTransport接口,用于邮件的发送,比如SMTPSendmail

     

    CamelProvider定义了provider的公共数据结构,其中包括像协议、名称、描述、配置和许可证等等信息,其中最重要的是object_types成员,它描述了STORETRANSPORT的类型,用它来创建协议实现的实例。

     

    每个provider都以独立的共享库方形提供,并且exportcamel_provider_module_init函数,在该函数内,provider调用camel_provider_register向系统注册自己,只有注册之后才能被使用者使用。而系统在初始化时,调用camel_provider_init去加载所有的provider

     

    CamelServiceSTORETRANSPORT共同的基类,它定义了一些两者都要实现的虚函数,比如connect/ disconnect用于建立和断开连接,cancel_connect用于取消连接,query_auth_ types用于查询认证类型。

     

    CamelTransport是发送协议必须实现的接口,它只有一个函数send_to,它的参数包括邮件、发件人和收件人等信息。

     

    CamelStore是接收协议必须实现的接口,它和IMAP能很好的对应起来。它的要求看起来非常复杂,它并没有提供接收邮件的函数,相反它提供了一些管理folder的函数。要接收邮件,先用get_folder得到CamelFolder,然后调用CamelFolder的函数get_message才行。

     

    下面的例子展示了发送邮件的方法:

    static char *types[] = { "to", "cc", "bcc" };

     

    void sendMail(CamelMimeMessage *msg, CamelException *ex)

    {

             CamelInternetAddress *from, *addr, *to;

             CamelTransport *trans;

     

             if (camel_mime_message_get_from(msg) == NULL) {

                       camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot send message: No from address set");

                       return;

             }

     

             trans = (CamelTransport *)camel_session_get_service(session, "smtp://localhost/", ex);

             if (camel_exception_is_set(ex))

                       return;

             camel_service_connect(trans, ex);

             if (camel_exception_is_set(ex))

                       goto noconnect;

     

             to = camel_internet_address_new();

             for (i=0;i<sizeof(types)/sizeof(types[0]);i++) {

                       CamelInternetAddress *addr = camel_mime_message_get_recipients(msg, types[i]);

     

                       if (addr)

                                camel_address_cat(to, addr);

             }

     

             camel_transport_send_to(trans, msg, camel_mime_message_get_from(msg), to, ex);

             camel_object_unref(to);

             camel_transport_disconnect(trans, FALSE, NULL);

    noconnect:

             camel_object_unref(trans);

    }

     

    下面的例子展示了接收邮件的方法:

    #include <camel/camel.h>

    #include <camel/camel-store.h>

    #include <camel/camel-session.h>

    #include <camel/camel-folder.h>

     

    int main(int argc, char* argv[])

    {

        g_type_init();

        g_thread_init(NULL);

        camel_init(NULL, 0);

     

        camel_provider_init();

     

        CamelException* ex = camel_exception_new();

     

        CamelSession* session = CAMEL_SESSION(camel_object_new(CAMEL_SESSION_TYPE));

        camel_session_construct(session, "/tmp");

     

        CamelStore* store = CAMEL_STORE(camel_session_get_service_connected(session,

            "pop://topmailtester:top321@pop.sohu.com",

            CAMEL_PROVIDER_STORE, ex));

     

        CamelFolder* inbox = camel_store_get_inbox(store, ex);

        GPtrArray* uids = camel_folder_get_uids(inbox);

     

        int i = 0;

        for(i = 0; i < uids->len; i++)

        {

            CamelMimeMessage* message = camel_folder_get_message(inbox, uids->pdata[i], CAMEL_FOLDER_RECEIVE_FULL, 0, ex);

            camel_mime_message_dump(message, 1);

            CamelStream* fs = camel_stream_fs_new_with_name(uids->pdata[i], O_CREAT|O_RDWR, 0664);

            camel_data_wrapper_write_to_stream(CAMEL_DATA_WRAPPER(message), fs);

     

            camel_object_unref(CAMEL_OBJECT(fs));

            camel_object_unref(CAMEL_OBJECT(message));

            printf("%p/n", uids->pdata[i]);

        }

       

        camel_folder_free_uids(inbox, uids);

       

        camel_object_unref(CAMEL_OBJECT(store));

        camel_object_unref(CAMEL_OBJECT(session));

        camel_exception_free(ex);

       

        return 0;

    }

     

    参考资料:

    http://www.go-evolution.org

     

    ~~end~~

     
  • 相关阅读:
    线性表的顺序存储结构详解
    Java就业急训营-感悟与分享
    在Ubuntu系统下用C语言编写程序
    NTIRE介绍和近年来超分SR结果展示
    《王道操作系统》学习笔记:计算机系统概述
    JavaScript 语言通识 — 重学 JavaScript
    python利用numpy存取文件
    Batch Normalization(批标准化,BN)
    全零填充(padding)
    感受野(Receptive Field)理解为什么采用多层小卷积核来替换一层大卷积核
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167733.html
Copyright © 2020-2023  润新知