Re: IMAP extensions

Michael Leupold <[email protected]> Tue, 11 Apr 2006 15:39:54 +0200
Newsgroups gmane.mail.libetpan.user
Message-ID <[email protected]>
Hi,

Am Dienstag, 11. April 2006 13:27 schrieb DINH Viet Hoa:
> > So I thought it might be nice to have some api to add extensions without
> > changing the core of mailimap for every extension you code while being
> > able to keep extensions separate from the "clean" imaprev1 code.
> Then, what kind of API do you propose ?
> You may provide a patch for this.

I've been thinking about it. But I fear it's a bit hard to explain. Basically, 
each extension would have an interface consisting of a parser, a new and a 
free. Then you'd have one parser implemented in mailimap_parser called 
mailimap_extension_parse which cycles through all of the extensions known and 
calls the extensions' parsers. One extra information the extension's parser 
needs is where it was called from (eg. mailimap_response_data_parse). It then 
calls the actual parser-function(s) based on that information. new and free 
would be implemented in a similar fashion. The data returned by an extension 
is wrapped by a struct mailimap_extension_data:
struct mailimap_extension_data {
	int extension;
	int type;
	void * data;
};
where extension is the extension that parsed this data.

Maybe an example helps to clarify what I mean:
I assume we have 2 extensions: ANNOTATEMORE and ACL2. The server returns the 
following:
* ANNOTATION "INBOX.1" "/comment" ("value.priv" "My comment for 1")
5 OK GETANNOTATION complete

libetpan will first try to parse this for mailbox-data and similar. Then, 
inside mailimap_response_data_parse, it will finally call 
mailimap_extension_parse(RESPONSE_DATA_PARSE, fd, buffer, ...) where 
RESPONSE_DATA_PARSE tells the extension parser that it was called from 
response_data_parse.
The extension parser will go through the list of extensions and call the 
annotetatemore extension's parser function:
mailimap_extension_annotatemore_parse(RESPONSE_DATA_PARSE, fd, buffer, ...). 
annotatemore_parse will examine the calling parser and - according to the 
extension's syntax - call the extension's correct parser, which in this case 
would be annotate_data_parse, so you got a stack like:
---
mailimap_extension_annotatemore_annotate_data_parse
mailimap_extension_annotatemore_parse
mailimap_extension_parse
mailimap_response_data_parse
---

The result (in case of NO_ERROR) would be
struct mailimap_extension_data result = {
  .extension = MAILIMAP_EXTENSION_ANNOTATEMORE,
  .type = MAILIMAP_EXTENSION_ANNOTATEMORE_ANNOTATE_DATA,
  /* ... and data would be a link to the actual (struct annotate_data *) */
};

Ok, I sincerely hope it's somehow understandable. Please don't take this as a 
proposal or anything, it's merely the result of a brainstorm and a request 
for comments.

> I think that this will introduce some global variable unless you have a
> better solution for this.

Yes, you'll need at least a static list of extensions and pointers to their 
parse, new and free functions.

Regards,
Michael


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642