aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnu.org>1999-07-15 08:11:56 +0800
committerArturo Espinosa <unammx@src.gnome.org>1999-07-15 08:11:56 +0800
commitfce26238c489db149f63164f13adf4bdb83d6062 (patch)
treef05ffd69d069044bcdb28e6d0d768239bc489e03
parent68f3afb7a29764be0389cb5a7b9960357e957412 (diff)
downloadgsoc2013-evolution-fce26238c489db149f63164f13adf4bdb83d6062.tar
gsoc2013-evolution-fce26238c489db149f63164f13adf4bdb83d6062.tar.gz
gsoc2013-evolution-fce26238c489db149f63164f13adf4bdb83d6062.tar.bz2
gsoc2013-evolution-fce26238c489db149f63164f13adf4bdb83d6062.tar.lz
gsoc2013-evolution-fce26238c489db149f63164f13adf4bdb83d6062.tar.xz
gsoc2013-evolution-fce26238c489db149f63164f13adf4bdb83d6062.tar.zst
gsoc2013-evolution-fce26238c489db149f63164f13adf4bdb83d6062.zip
Implemented base64 encoder based on CamelStreams. Should the
1999-07-13 Miguel de Icaza <miguel@gnu.org> * camel/gmime-base64.c (gmime_encode_base64): Implemented base64 encoder based on CamelStreams. Should the encoder/decoder be a Stream itself? * camel/gmime-utils.c: include config.h here. * camel/url-util.c: ditto. * camel/gstring-util.c: ditto. * camel/gmime-content-field.c: ditto. * camel/camel-stream.c: ditto. * camel/camel-stream-fs.c: ditto. * camel/camel-store.c: ditto. * camel/camel-simple-data-wrapper.c: ditto. * camel/camel-session.c: ditto. * camel/camel-service.c: ditto. * camel/camel-mime-part.c: ditto. * camel/camel-mime-message.c: ditto. * camel/camel-log.c: ditto. * camel/camel-data-wrapper.c: ditto * camel/camel-folder.c: ditto. * camel/camel-stream.c (camel_stream_write): Moved api documentation to the places that they document. (camel_stream_class_init): Virtual classes do not need to have a default implementation. So null them all. (camel_stream_write): Return value from write. (camel_stream_available): implement. (camel_stream_write_strings): documented. * devel-docs/query/virtual-folder-in-depth.sgml: Small reformatting 1999-06-28 bertrand <Bertrand.Guiheneuf@inria.fr> * tests/test2.c (main): now use CamelDataWrapper::contruct_form_stream to test svn path=/trunk/; revision=1024
-rw-r--r--ChangeLog33
-rw-r--r--camel/camel-data-wrapper.c2
-rw-r--r--camel/camel-folder.c13
-rw-r--r--camel/camel-log.c2
-rw-r--r--camel/camel-mime-message.c6
-rw-r--r--camel/camel-mime-message.h91
-rw-r--r--camel/camel-mime-part.c2
-rw-r--r--camel/camel-mime-part.h44
-rw-r--r--camel/camel-service.c2
-rw-r--r--camel/camel-session.c2
-rw-r--r--camel/camel-simple-data-wrapper.c2
-rw-r--r--camel/camel-store.c2
-rw-r--r--camel/camel-stream-fs.c22
-rw-r--r--camel/camel-stream-fs.h1
-rw-r--r--camel/camel-stream.c142
-rw-r--r--camel/camel-stream.h22
-rw-r--r--camel/gmime-content-field.c4
-rw-r--r--camel/gmime-utils.c11
-rw-r--r--camel/gstring-util.c59
-rw-r--r--camel/gstring-util.h42
-rw-r--r--camel/url-util.c2
-rw-r--r--devel-docs/query/virtual-folder-in-depth.sgml772
22 files changed, 680 insertions, 598 deletions
diff --git a/ChangeLog b/ChangeLog
index 3b584fd623..a4c3ee5643 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+1999-07-13 Miguel de Icaza <miguel@gnu.org>
+
+ * camel/gmime-base64.c (gmime_encode_base64): Implemented base64
+ encoder based on CamelStreams. Should the encoder/decoder be a
+ Stream itself?
+
+ * camel/gmime-utils.c: include config.h here.
+ * camel/url-util.c: ditto.
+ * camel/gstring-util.c: ditto.
+ * camel/gmime-content-field.c: ditto.
+ * camel/camel-stream.c: ditto.
+ * camel/camel-stream-fs.c: ditto.
+ * camel/camel-store.c: ditto.
+ * camel/camel-simple-data-wrapper.c: ditto.
+ * camel/camel-session.c: ditto.
+ * camel/camel-service.c: ditto.
+ * camel/camel-mime-part.c: ditto.
+ * camel/camel-mime-message.c: ditto.
+ * camel/camel-log.c: ditto.
+ * camel/camel-data-wrapper.c: ditto
+ * camel/camel-folder.c: ditto.
+
+ * camel/camel-stream.c (camel_stream_write): Moved api
+ documentation to the places that they document.
+ (camel_stream_class_init): Virtual classes do not need to have a
+ default implementation. So null them all.
+ (camel_stream_write): Return value from write.
+ (camel_stream_available): implement.
+ (camel_stream_write_strings): documented.
+
+ * devel-docs/query/virtual-folder-in-depth.sgml: Small
+ reformatting
+
1999-06-28 bertrand <Bertrand.Guiheneuf@inria.fr>
* tests/test2.c (main): now use
diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c
index 05d97d415d..b4ef2f9c36 100644
--- a/camel/camel-data-wrapper.c
+++ b/camel/camel-data-wrapper.c
@@ -23,7 +23,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-data-wrapper.h"
static GtkObjectClass *parent_class=NULL;
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index d7b54075be..63881d1422 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-folder.h"
#include "gstring-util.h"
@@ -362,12 +362,17 @@ _create(CamelFolder *folder)
g_assert(folder->parent_store);
g_assert(folder->name);
- if ( CF_CLASS(folder)->exists(folder) ) return TRUE;
+ if (CF_CLASS(folder)->exists(folder))
+ return TRUE;
+
sep = camel_store_get_separator(folder->parent_store);
- if (folder->parent_folder) camel_folder_create(folder->parent_folder);
+ if (folder->parent_folder)
+ camel_folder_create(folder->parent_folder);
else {
if (folder->full_name) {
- dich_result = g_string_dichotomy(folder->full_name, sep, &prefix, NULL, DICHOTOMY_STRIP_TRAILING | DICHOTOMY_RIGHT_DIR);
+ dich_result = g_string_dichotomy(
+ folder->full_name, sep, &prefix, NULL,
+ GSTRING_DICHOTOMY_STRIP_TRAILING | GSTRING_DICHOTOMY_RIGHT_DIR);
if (dich_result!='o') {
g_warning("I have to handle the case where the path is not OK\n");
return FALSE;
diff --git a/camel/camel-log.c b/camel/camel-log.c
index 59ce5573b2..a0dd8007b7 100644
--- a/camel/camel-log.c
+++ b/camel/camel-log.c
@@ -20,7 +20,7 @@
* USA
*/
-
+#include <config.h>
#include "camel-log.h"
int camel_debug_level = 10;
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index df65c127f6..61a4ca4c8d 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -21,7 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-mime-message.h"
#include <stdio.h>
#include "gmime-content-field.h"
@@ -564,7 +564,9 @@ _set_recipient_list_from_string (CamelMimeMessage *message, GString *recipient_t
{
GList *recipients_list;
CAMEL_LOG (FULL_DEBUG,"CamelMimeMessage::_set_recipient_list_from_string parsing ##%s##\n", recipients_string->str);
- recipients_list = g_string_split (recipients_string, ',', "\t ", TRIM_STRIP_TRAILING | TRIM_STRIP_LEADING);
+ recipients_list = g_string_split (
+ recipients_string, ',', "\t ",
+ GSTRING_TRIM_STRIP_TRAILING | GSTRING_TRIM_STRIP_LEADING);
g_hash_table_insert (message->recipients, recipient_type, recipients_list);
}
diff --git a/camel/camel-mime-message.h b/camel/camel-mime-message.h
index 73d1cb9388..321f3fdade 100644
--- a/camel/camel-mime-message.h
+++ b/camel/camel-mime-message.h
@@ -81,24 +81,35 @@ typedef struct {
CamelMimePartClass parent_class;
/* Virtual methods */
- void (*set_received_date) (CamelMimeMessage *mime_message, GString *received_date);
+ void (*set_received_date) (CamelMimeMessage *mime_message,
+ GString *received_date);
GString * (*get_received_date) (CamelMimeMessage *mime_message);
- GString * (*get_sent_date) (CamelMimeMessage *mime_message);
- void (*set_reply_to) (CamelMimeMessage *mime_message, GString *reply_to);
- GString * (*get_reply_to) (CamelMimeMessage *mime_message);
- void (*set_subject) (CamelMimeMessage *mime_message, GString *subject);
- GString * (*get_subject) (CamelMimeMessage *mime_message);
- void (*set_from) (CamelMimeMessage *mime_message, GString *from);
- GString * (*get_from) (CamelMimeMessage *mime_message);
- void (*add_recipient) (CamelMimeMessage *mime_message, GString *recipient_type, GString *recipient);
- void (*remove_recipient) (CamelMimeMessage *mime_message, GString *recipient_type, GString *recipient);
- GList * (*get_recipients) (CamelMimeMessage *mime_message, GString *recipient_type);
- void (*set_flag) (CamelMimeMessage *mime_message, GString *flag, gboolean value);
- gboolean (*get_flag) (CamelMimeMessage *mime_message, GString *flag);
-
- void (*set_message_number) (CamelMimeMessage *mime_message, guint number);
- guint (*get_message_number) (CamelMimeMessage *mime_message);
-
+ GString * (*get_sent_date) (CamelMimeMessage *mime_message);
+ void (*set_reply_to) (CamelMimeMessage *mime_message,
+ GString *reply_to);
+ GString * (*get_reply_to) (CamelMimeMessage *mime_message);
+ void (*set_subject) (CamelMimeMessage *mime_message,
+ GString *subject);
+ GString * (*get_subject) (CamelMimeMessage *mime_message);
+ void (*set_from) (CamelMimeMessage *mime_message,
+ GString *from);
+ GString * (*get_from) (CamelMimeMessage *mime_message);
+ void (*add_recipient) (CamelMimeMessage *mime_message,
+ GString *recipient_type,
+ GString *recipient);
+ void (*remove_recipient) (CamelMimeMessage *mime_message,
+ GString *recipient_type,
+ GString *recipient);
+ GList * (*get_recipients) (CamelMimeMessage *mime_message,
+ GString *recipient_type);
+ void (*set_flag) (CamelMimeMessage *mime_message,
+ GString *flag, gboolean value);
+ gboolean (*get_flag) (CamelMimeMessage *mime_message,
+ GString *flag);
+
+ void (*set_message_number)(CamelMimeMessage *mime_message,
+ guint number);
+ guint (*get_message_number)(CamelMimeMessage *mime_message);
} CamelMimeMessageClass;
@@ -111,24 +122,34 @@ GtkType camel_mime_message_get_type (void);
CamelMimeMessage *camel_mime_message_new_with_session (CamelSession *session);
-void camel_mime_message_set_received_date (CamelMimeMessage *mime_message, GString *received_date);
-GString *camel_mime_message_get_received_date (CamelMimeMessage *mime_message);
-GString *camel_mime_message_get_sent_date (CamelMimeMessage *mime_message);
-void camel_mime_message_set_reply_to (CamelMimeMessage *mime_message, GString *reply_to);
-GString *camel_mime_message_get_reply_to (CamelMimeMessage *mime_message);
-void camel_mime_message_set_subject (CamelMimeMessage *mime_message, GString *subject);
-GString *camel_mime_message_get_subject (CamelMimeMessage *mime_message);
-void camel_mime_message_set_from (CamelMimeMessage *mime_message, GString *from);
-GString *camel_mime_message_get_from (CamelMimeMessage *mime_message);
-
-void camel_mime_message_add_recipient (CamelMimeMessage *mime_message, GString *recipient_type, GString *recipient);
-void camel_mime_message_remove_recipient (CamelMimeMessage *mime_message, GString *recipient_type, GString *recipient);
-GList *camel_mime_message_get_recipients (CamelMimeMessage *mime_message, GString *recipient_type);
-
-void camel_mime_message_set_flag (CamelMimeMessage *mime_message, GString *flag, gboolean value);
-gboolean camel_mime_message_get_flag (CamelMimeMessage *mime_message, GString *flag);
-
-guint camel_mime_message_get_message_number (CamelMimeMessage *mime_message);
+void camel_mime_message_set_received_date (CamelMimeMessage *mime_message,
+ GString *received_date);
+GString *camel_mime_message_get_received_date (CamelMimeMessage *mime_message);
+GString *camel_mime_message_get_sent_date (CamelMimeMessage *mime_message);
+void camel_mime_message_set_reply_to (CamelMimeMessage *mime_message,
+ GString *reply_to);
+GString *camel_mime_message_get_reply_to (CamelMimeMessage *mime_message);
+void camel_mime_message_set_subject (CamelMimeMessage *mime_message,
+ GString *subject);
+GString *camel_mime_message_get_subject (CamelMimeMessage *mime_message);
+void camel_mime_message_set_from (CamelMimeMessage *mime_message, GString *from);
+GString *camel_mime_message_get_from (CamelMimeMessage *mime_message);
+
+void camel_mime_message_add_recipient (CamelMimeMessage *mime_message,
+ GString *recipient_type,
+ GString *recipient);
+void camel_mime_message_remove_recipient (CamelMimeMessage *mime_message,
+ GString *recipient_type,
+ GString *recipient);
+GList *camel_mime_message_get_recipients (CamelMimeMessage *mime_message,
+ GString *recipient_type);
+
+void camel_mime_message_set_flag (CamelMimeMessage *mime_message,
+ GString *flag, gboolean value);
+gboolean camel_mime_message_get_flag (CamelMimeMessage *mime_message,
+ GString *flag);
+
+guint camel_mime_message_get_message_number (CamelMimeMessage *mime_message);
#ifdef __cplusplus
}
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index 0fdf749d38..aa40144acf 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -21,7 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-mime-part.h"
#include <stdio.h>
#include "gmime-content-field.h"
diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h
index ad3ce17d2f..9f364c427c 100644
--- a/camel/camel-mime-part.h
+++ b/camel/camel-mime-part.h
@@ -104,23 +104,33 @@ GtkType camel_mime_part_get_type (void);
/* public methods */
-void camel_mime_part_add_header (CamelMimePart *mime_part, GString *header_name, GString *header_value);
-void camel_mime_part_remove_header (CamelMimePart *mime_part, GString *header_name);
-GString *camel_mime_part_get_header (CamelMimePart *mime_part, GString *header_name);
-void camel_mime_part_set_description (CamelMimePart *mime_part, GString *description);
-GString *camel_mime_part_get_description (CamelMimePart *mime_part);
-void camel_mime_part_set_disposition (CamelMimePart *mime_part, GString *disposition);
-GString *camel_mime_part_get_disposition (CamelMimePart *mime_part);
-void camel_mime_part_set_filename (CamelMimePart *mime_part, GString *filename);
-GString *camel_mime_part_get_filename (CamelMimePart *mime_part);
-GString *camel_mime_part_get_content_id (CamelMimePart *mime_part);
-GString *camel_mime_part_get_content_MD5 (CamelMimePart *mime_part);
-void camel_mime_part_set_encoding (CamelMimePart *mime_part, GString *encoding);
-GString *camel_mime_part_get_encoding (CamelMimePart *mime_part);
-void camel_mime_part_set_content_languages (CamelMimePart *mime_part, GList *content_languages);
-GList *camel_mime_part_get_content_languages (CamelMimePart *mime_part);
-void camel_mime_part_set_header_lines (CamelMimePart *mime_part, GList *header_lines);
-GList *camel_mime_part_get_header_lines (CamelMimePart *mime_part);
+void camel_mime_part_add_header (CamelMimePart *mime_part,
+ GString *header_name,
+ GString *header_value);
+void camel_mime_part_remove_header (CamelMimePart *mime_part,
+ GString *header_name);
+GString *camel_mime_part_get_header (CamelMimePart *mime_part,
+ GString *header_name);
+void camel_mime_part_set_description (CamelMimePart *mime_part,
+ GString *description);
+GString *camel_mime_part_get_description (CamelMimePart *mime_part);
+void camel_mime_part_set_disposition (CamelMimePart *mime_part,
+ GString *disposition);
+GString *camel_mime_part_get_disposition (CamelMimePart *mime_part);
+void camel_mime_part_set_filename (CamelMimePart *mime_part,
+ GString *filename);
+GString *camel_mime_part_get_filename (CamelMimePart *mime_part);
+GString *camel_mime_part_get_content_id (CamelMimePart *mime_part);
+GString *camel_mime_part_get_content_MD5 (CamelMimePart *mime_part);
+void camel_mime_part_set_encoding (CamelMimePart *mime_part,
+ GString *encoding);
+GString *camel_mime_part_get_encoding (CamelMimePart *mime_part);
+void camel_mime_part_set_content_languages (CamelMimePart *mime_part,
+ GList *content_languages);
+GList *camel_mime_part_get_content_languages (CamelMimePart *mime_part);
+void camel_mime_part_set_header_lines (CamelMimePart *mime_part,
+ GList *header_lines);
+GList *camel_mime_part_get_header_lines (CamelMimePart *mime_part);
#ifdef __cplusplus
}
diff --git a/camel/camel-service.c b/camel/camel-service.c
index 2ca3d6f352..645eaf3f09 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-service.h"
static GtkObjectClass *parent_class=NULL;
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 42f681f626..5238b8d5eb 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-session.h"
#include "gstring-util.h"
diff --git a/camel/camel-simple-data-wrapper.c b/camel/camel-simple-data-wrapper.c
index 2d81fa62a9..775cf5ca58 100644
--- a/camel/camel-simple-data-wrapper.c
+++ b/camel/camel-simple-data-wrapper.c
@@ -21,7 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-simple-data-wrapper.h"
static CamelDataWrapperClass *parent_class=NULL;
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 61c5216780..cedd452c44 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-store.h"
static GtkObjectClass *parent_class=NULL;
diff --git a/camel/camel-stream-fs.c b/camel/camel-stream-fs.c
index 09b193b229..0b70802943 100644
--- a/camel/camel-stream-fs.c
+++ b/camel/camel-stream-fs.c
@@ -21,7 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-stream-fs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -32,7 +32,7 @@
static CamelStreamClass *parent_class=NULL;
-/* Returns the class for a CamelMimeMessage */
+/* Returns the class for a CamelStreamFS */
#define CS_CLASS(so) CAMEL_STREAM_FS_CLASS (GTK_OBJECT(so)->klass)
static gint _read (CamelStream *stream, gchar *buffer, gint n);
@@ -101,13 +101,17 @@ camel_stream_fs_new_with_name (GString *name, CamelStreamFsMode mode)
CAMEL_LOG (FULL_DEBUG, "Entering CamelStream::new_with_name, name=\"%s\", mode=%d\n", name->str, mode);
v = stat (name->str, &s);
- if (mode & CAMEL_STREAM_FS_READ)
- if (mode & CAMEL_STREAM_FS_WRITE) flags = O_RDWR | O_CREAT;
- else flags = O_RDONLY;
- else
- if (mode & CAMEL_STREAM_FS_WRITE) flags = O_WRONLY | O_CREAT;
- else return NULL;
-
+ if (mode & CAMEL_STREAM_FS_READ){
+ if (mode & CAMEL_STREAM_FS_WRITE)
+ flags = O_RDWR | O_CREAT;
+ else
+ flags = O_RDONLY;
+ } else {
+ if (mode & CAMEL_STREAM_FS_WRITE)
+ flags = O_WRONLY | O_CREAT;
+ else
+ return NULL;
+ }
if ( (mode & CAMEL_STREAM_FS_READ) && !(mode & CAMEL_STREAM_FS_WRITE) )
if (v == -1) return NULL;
diff --git a/camel/camel-stream-fs.h b/camel/camel-stream-fs.h
index 046e90d26c..3570e8a9f9 100644
--- a/camel/camel-stream-fs.h
+++ b/camel/camel-stream-fs.h
@@ -52,7 +52,6 @@ typedef struct
CamelStream parent_object;
GString *name;
int fd;
-
} CamelStreamFs;
diff --git a/camel/camel-stream.c b/camel/camel-stream.c
index 9f9e912bd8..5554b8fe38 100644
--- a/camel/camel-stream.c
+++ b/camel/camel-stream.c
@@ -21,22 +21,26 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-
+#include <config.h>
#include "camel-stream.h"
-static CamelStreamClass *parent_class=NULL;
+static CamelStreamClass *parent_class = NULL;
/* Returns the class for a CamelMimeMessage */
#define CS_CLASS(so) CAMEL_STREAM_CLASS (GTK_OBJECT(so)->klass)
-static gint _read (CamelStream *stream, gchar *buffer, gint n);
-static gint _write (CamelStream *stream, gchar *buffer, gint n);
-static void _flush (CamelStream *stream);
-static gint _available (CamelStream *stream);
-static gboolean _eos (CamelStream *stream);
-static void _close (CamelStream *stream);
+static void
+default_camel_flush (CamelStream *stream)
+{
+ /* nothing */
+}
+static void
+default_camel_close (CamelStream *stream)
+{
+ /* nothing */
+}
static void
camel_stream_class_init (CamelStreamClass *camel_stream_class)
@@ -45,19 +49,16 @@ camel_stream_class_init (CamelStreamClass *camel_stream_class)
parent_class = gtk_type_class (gtk_object_get_type ());
/* virtual method definition */
- camel_stream_class->read = _read;
- camel_stream_class->write = _write;
- camel_stream_class->flush = _flush;
- camel_stream_class->available = _available;
- camel_stream_class->eos = _eos;
- camel_stream_class->close = _close;
+ camel_stream_class->read = NULL;
+ camel_stream_class->write = NULL;
+ camel_stream_class->flush = default_camel_flush;
+ camel_stream_class->available = NULL;
+ camel_stream_class->eos = NULL;
+ camel_stream_class->close = default_camel_close;
/* virtual method overload */
-
}
-
-
GtkType
camel_stream_get_type (void)
{
@@ -82,24 +83,17 @@ camel_stream_get_type (void)
return camel_stream_type;
}
-
-
/**
- * _read: read bytes from a stream
- * @stream: stream
- * @buffer: buffer where bytes are stored
- * @n: max number of bytes to read
- *
+ * camel_stream_read:
+ * @stream: a CamelStream.
+ * @buffer: buffer where bytes pulled from the stream are stored.
+ * @n: max number of bytes to read.
*
+ * Read at most @n bytes from the @stream object and stores them
+ * in the buffer pointed at by @buffer.
*
* Return value: number of bytes actually read.
**/
-static gint
-_read (CamelStream *stream, gchar *buffer, gint n)
-{
-
-}
-
gint
camel_stream_read (CamelStream *stream, gchar *buffer, gint n)
{
@@ -107,98 +101,84 @@ camel_stream_read (CamelStream *stream, gchar *buffer, gint n)
}
/**
- * _write: read bytes to a stream
- * @stream: the stream
- * @buffer: byte buffer
+ * camel_stream_write:
+ * @stream: a CamelStream object.
+ * @buffer: buffer to write.
* @n: number of bytes to write
- *
- *
- *
+ *
+ * Write @n bytes from the buffer pointed at by @buffer into @stream.
+ *
* Return value: the number of bytes actually written
* in the stream.
**/
-static gint
-_write (CamelStream *stream, gchar *buffer, gint n)
-{
-
-}
-
gint
camel_stream_write (CamelStream *stream, gchar *buffer, gint n)
{
- CS_CLASS (stream)->write (stream, buffer, n);
+ return CS_CLASS (stream)->write (stream, buffer, n);
}
-
-
/**
- * _flush: flush pending changes
- * @stream: the stream
- *
+ * camel_stream_flush:
+ * @stream: a CamelStream object
*
+ * Flushes the contents of the stream to its backing store.
**/
-static void
-_flush (CamelStream *stream)
+void
+camel_stream_flush (CamelStream *stream)
{
-
+ return CS_CLASS (stream)->flush (stream);
}
-
-
/**
- * _available: return the number of bytes available for reading
- * @stream: the stream
- *
- * Return the number of bytes available without blocking.
+ * camel_stream_available:
+ * @stream: a CamelStream object
*
- * Return value: the number of bytes available
+ * Return value: the number of bytes available.
**/
static gint
-_available (CamelStream *stream)
+camel_stream_available (CamelStream *stream)
{
-
+ return CS_CLASS (stream)->available (stream);
}
-
/**
- * _eos: test if there are bytes left to read
- * @stream: the stream
- *
+ * camle_stream_eos:
+ * @stream: a CamelStream object
*
+ * Test if there are bytes left to read on the @stream object.
*
- * Return value: true if all stream has been read
+ * Return value: %TRUE if all the contents on the stream has been read, or
+ * %FALSE if information is still available.
**/
static gboolean
-_eos (CamelStream *stream)
+camel_stream_eos (CamelStream *stream)
{
-
+ return CS_CLASS (stream)->eos (stream);
}
/**
- * _close: close a stream
- * @stream: the stream
- *
+ * camel_stram_close:
+ * @stream: a CamelStream object.
*
+ * Close the @stream object.
**/
-static void
-_close (CamelStream *stream)
-{
-
-}
-
void
camel_stream_close (CamelStream *stream)
{
CS_CLASS (stream)->close (stream);
}
-
-
-
-
/***************** Utility functions ********************/
+/**
+ * came_stream_write_strings:
+ * @stream: a CamelStream object.
+ * @...: A %NULL terminated list of strings.
+ *
+ * This is a utility function that writes the list of
+ * strings into the @stream object.
+ */
void
camel_stream_write_strings (CamelStream *stream, ... )
{
@@ -209,7 +189,7 @@ camel_stream_write_strings (CamelStream *stream, ... )
string = va_arg (args, char *);
while (string) {
- camel_stream_write_string(stream, string);
+ camel_stream_write_string (stream, string);
string = va_arg (args, char *);
}
va_end (args);
diff --git a/camel/camel-stream.h b/camel/camel-stream.h
index 5fff22a24a..8434002757 100644
--- a/camel/camel-stream.h
+++ b/camel/camel-stream.h
@@ -52,13 +52,12 @@ typedef struct {
GtkObjectClass parent_class;
/* Virtual methods */
-gint (*read) (CamelStream *stream, gchar *buffer, gint n);
-gint (*write) (CamelStream *stream, gchar *buffer, gint n);
-void (*flush) (CamelStream *stream);
-gint (*available) (CamelStream *stream);
-gboolean (*eos) (CamelStream *stream);
-void (*close) (CamelStream *stream);
-
+ gint (*read) (CamelStream *stream, gchar *buffer, gint n);
+ gint (*write) (CamelStream *stream, gchar *buffer, gint n);
+ void (*flush) (CamelStream *stream);
+ gint (*available) (CamelStream *stream);
+ gboolean (*eos) (CamelStream *stream);
+ void (*close) (CamelStream *stream);
} CamelStreamClass;
@@ -68,9 +67,12 @@ GtkType camel_stream_get_type (void);
/* public methods */
-gint camel_stream_read (CamelStream *stream, gchar *buffer, gint n);
-gint camel_stream_write (CamelStream *stream, gchar *buffer, gint n);
-void camel_stream_close (CamelStream *stream);
+gint camel_stream_read (CamelStream *stream, gchar *buffer, gint n);
+gint camel_stream_write (CamelStream *stream, gchar *buffer, gint n);
+void camel_stream_flush (CamelStream *stream);
+gint camel_stream_available (CamelStream *stream);
+gboolean camel_stream_eos (CamelStream *stream);
+void camel_stream_close (CamelStream *stream);
/* utility macros and funcs */
#define camel_stream_write_string(stream, string) camel_stream_write ((stream), (string), strlen (string))
diff --git a/camel/gmime-content-field.c b/camel/gmime-content-field.c
index 06e4384437..a86c7047ad 100644
--- a/camel/gmime-content-field.c
+++ b/camel/gmime-content-field.c
@@ -21,9 +21,7 @@
* USA
*/
-
-
-
+#include <config.h>
#include "gmime-content-field.h"
#include "gstring-util.h"
#include "camel-log.h"
diff --git a/camel/gmime-utils.c b/camel/gmime-utils.c
index 1555d27e7b..8c3db96cd4 100644
--- a/camel/gmime-utils.c
+++ b/camel/gmime-utils.c
@@ -21,8 +21,7 @@
* USA
*/
-
-
+#include <config.h>
#include "gmime-utils.h"
#include "gstring-util.h"
#include "camel-log.h"
@@ -112,14 +111,18 @@ _store_header_pair_from_gstring (GHashTable *header_table, GString *header_line)
g_assert (header_table);
if ( (header_line) && (header_line->str) ) {
- dich_result = g_string_dichotomy(header_line, ':', &header_name, &header_value, DICHOTOMY_NONE);
+ dich_result = g_string_dichotomy (
+ header_line, ':', &header_name, &header_value,
+ GSTRING_DICHOTOMY_NONE);
if (dich_result != 'o')
camel_log(WARNING,
"store_header_pair_from_gstring : dichotomy result is %c"
"header line is :\n--\n%s\n--\n");
else {
- g_string_trim (header_value, " \t", TRIM_STRIP_LEADING | TRIM_STRIP_TRAILING);
+ g_string_trim (
+ header_value, " \t",
+ GSTRING_TRIM_STRIP_LEADING | GSTRING_TRIM_STRIP_TRAILING);
g_hash_table_insert (header_table, header_name, header_value);
}
}
diff --git a/camel/gstring-util.c b/camel/gstring-util.c
index c48a98d410..89cd263e85 100644
--- a/camel/gstring-util.c
+++ b/camel/gstring-util.c
@@ -23,7 +23,7 @@
-
+#include <config.h>
#include "gstring-util.h"
#include "camel-log.h"
@@ -64,7 +64,14 @@ g_string_clone(GString *string)
/**
- * g_string_dichotomy : return the strings before and/or after
+ * g_string_dichotomy:
+ * @sep : separator
+ * @prefix: pointer to be field by the prefix object
+ * the prefix is not returned when the given pointer is NULL
+ * @suffix: pointer to be field by the suffix object
+ * the suffix is not returned when the given pointer is NULL
+ *
+ * Return the strings before and/or after
* the last occurence of the specified separator
*
* This routine returns the string before and/or after
@@ -75,17 +82,12 @@ g_string_clone(GString *string)
* suffix is set to NULL and result is set to 'n'
* When the operation succedeed, the return value is 'o'
*
- * @sep : separator
- * @prefix: pointer to be field by the prefix object
- * the prefix is not returned when the given pointer is NULL
- * @suffix: pointer to be field by the suffix object
- * the suffix is not returned when the given pointer is NULL
- *
* @Return Value : result of the operation ('o', 'l' or 'n')
*
**/
gchar
-g_string_dichotomy (GString *string, gchar sep, GString **prefix, GString **suffix, DichotomyOption options)
+g_string_dichotomy (GString *string, gchar sep, GString **prefix, GString **suffix,
+ GStringDichotomyOption options)
{
gchar *str, *tmp;
gint pos, len, first;
@@ -96,17 +98,19 @@ g_string_dichotomy (GString *string, gchar sep, GString **prefix, GString **suff
g_assert( tmp=string->str );
len = strlen(tmp);
if (!len) {
- if (prefix) *prefix=NULL;
- if (suffix) *suffix=NULL;
+ if (prefix)
+ *prefix=NULL;
+ if (suffix)
+ *suffix=NULL;
CAMEL_LOG(FULL_DEBUG,"string_dichotomy: string is empty\n");
return 'n';
}
first = 0;
- if ( (options & DICHOTOMY_STRIP_LEADING ) && (tmp[first] == sep) )
+ if ( (options & GSTRING_DICHOTOMY_STRIP_LEADING ) && (tmp[first] == sep) )
do {first++;} while ( (first<len) && (tmp[first] == sep) );
- if (options & DICHOTOMY_STRIP_TRAILING )
+ if (options & GSTRING_DICHOTOMY_STRIP_TRAILING )
while (tmp[len-1] == sep)
len--;
@@ -117,7 +121,7 @@ g_string_dichotomy (GString *string, gchar sep, GString **prefix, GString **suff
return 'n';
}
- if (options & DICHOTOMY_RIGHT_DIR) {
+ if (options & GSTRING_DICHOTOMY_RIGHT_DIR) {
pos = len;
do {
@@ -253,7 +257,7 @@ g_string_list_free (GList *string_list)
GList *
-g_string_split (GString *string, char sep, gchar *trim_chars, TrimOption trim_options)
+g_string_split (GString *string, char sep, gchar *trim_chars, GStringTrimOption trim_options)
{
GList *result = NULL;
gint first, last, pos;
@@ -296,10 +300,8 @@ g_string_split (GString *string, char sep, gchar *trim_chars, TrimOption trim_op
}
-
-
void
-g_string_trim (GString *string, gchar *chars, TrimOption options)
+g_string_trim (GString *string, gchar *chars, GStringTrimOption options)
{
gint first_ok;
gint last_ok;
@@ -308,24 +310,31 @@ g_string_trim (GString *string, gchar *chars, TrimOption options)
CAMEL_LOG(FULL_DEBUG,"**\nentering g_string_trim::\n");
- if ((!string) || (!string->str)) return;
+ if ((!string) || (!string->str))
+ return;
str = string->str;
length = strlen (str);
- if (!length) return;
+ if (!length)
+ return;
first_ok = 0;
last_ok = length - 1;
CAMEL_LOG (FULL_DEBUG,"g_string_trim:: trim_options:%d\n", options);
- if (options & TRIM_STRIP_LEADING)
+ if (options & GSTRING_TRIM_STRIP_LEADING)
while ( (first_ok <= last_ok) && (strchr (chars, str[first_ok])) )
first_ok++;
- if (options & TRIM_STRIP_TRAILING)
+ if (options & GSTRING_TRIM_STRIP_TRAILING)
while ( (first_ok <= last_ok) && (strchr (chars, str[last_ok])) )
last_ok++;
- CAMEL_LOG (FULL_DEBUG,"g_string_trim::\n\t\"%s\":first ok:%d last_ok:%d\n", string->str, first_ok, last_ok);
- if (first_ok>0) g_string_erase (string, 0, first_ok);
- if (last_ok<length-1) g_string_truncate (string, last_ok - first_ok +1);
+ CAMEL_LOG (FULL_DEBUG,"g_string_trim::\n\t\"%s\":first ok:%d last_ok:%d\n",
+ string->str, first_ok, last_ok);
+
+ if (first_ok > 0)
+ g_string_erase (string, 0, first_ok);
+
+ if (last_ok < length-1)
+ g_string_truncate (string, last_ok - first_ok +1);
}
diff --git a/camel/gstring-util.h b/camel/gstring-util.h
index 419895831c..7a82f9ab01 100644
--- a/camel/gstring-util.h
+++ b/camel/gstring-util.h
@@ -35,33 +35,37 @@ extern "C" {
#include <glib.h>
typedef enum {
- DICHOTOMY_NONE = 0,
- DICHOTOMY_RIGHT_DIR = 1,
- DICHOTOMY_STRIP_TRAILING = 2,
- DICHOTOMY_STRIP_LEADING = 4,
+ GSTRING_DICHOTOMY_NONE = 0,
+ GSTRING_DICHOTOMY_RIGHT_DIR = 1,
+ GSTRING_DICHOTOMY_STRIP_TRAILING = 2,
+ GSTRING_DICHOTOMY_STRIP_LEADING = 4,
-} DichotomyOption;
+} GStringDichotomyOption;
typedef enum {
- TRIM_NONE = 0,
- TRIM_STRIP_TRAILING = 1,
- TRIM_STRIP_LEADING = 2,
-
-} TrimOption;
+ GSTRING_TRIM_NONE = 0,
+ GSTRING_TRIM_STRIP_TRAILING = 1,
+ GSTRING_TRIM_STRIP_LEADING = 2,
+} GStringTrimOption;
-gboolean g_string_equals(GString *string1, GString *string2);
-GString *g_string_clone(GString *string);
-gchar g_string_dichotomy( GString *string, gchar sep, GString **prefix, GString **suffix, DichotomyOption options);
-void g_string_append_g_string(GString *dest_string, GString *other_string);
+gboolean g_string_equals (GString *string1, GString *string2);
+GString *g_string_clone (GString *string);
+gchar g_string_dichotomy (GString *string, gchar sep,
+ GString **prefix, GString **suffix,
+ GStringDichotomyOption options);
+void g_string_append_g_string (GString *dest_string,
+ GString *other_string);
-gboolean g_string_equal_for_hash (gconstpointer v, gconstpointer v2);
+gboolean g_string_equal_for_hash (gconstpointer v, gconstpointer v2);
gboolean g_string_equal_for_glist (gconstpointer v, gconstpointer v2);
-guint g_string_hash (gconstpointer v);
-void g_string_list_free (GList *string_list);
+guint g_string_hash (gconstpointer v);
+void g_string_list_free (GList *string_list);
-GList *g_string_split (GString *string, char sep, gchar *trim_chars, TrimOption trim_options);
-void g_string_trim (GString *string, gchar *chars, TrimOption options);
+GList *g_string_split (GString *string, char sep,
+ gchar *trim_chars, GStringTrimOption trim_options);
+void g_string_trim (GString *string, gchar *chars,
+ GStringTrimOption options);
#ifdef __cplusplus
}
diff --git a/camel/url-util.c b/camel/url-util.c
index 1b784385f5..b9ee4c653b 100644
--- a/camel/url-util.c
+++ b/camel/url-util.c
@@ -34,7 +34,7 @@
/*
XXX TODO: recover the words between #'s or ?'s after the path */
-
+#include <config.h>
#include "url-util.h"
/* general item finder */
diff --git a/devel-docs/query/virtual-folder-in-depth.sgml b/devel-docs/query/virtual-folder-in-depth.sgml
index fc85132673..e6ba7ecf18 100644
--- a/devel-docs/query/virtual-folder-in-depth.sgml
+++ b/devel-docs/query/virtual-folder-in-depth.sgml
@@ -3,393 +3,405 @@
<!-- SGMLized by Bertrand <Bertrand.Guiheneuf@inria.fr> -->
<article id="index">
- <artheader>
- <authorgroup>
- <author>
- <firstname>Giao</firstname>
- <surname>Nguyen</surname>
- </author>
- </authorgroup>
- <title>An in-depth look at the virtual folder mechanism</title>
- <abstract>
- <para>
- This document describes a different way of approaching mail
- organization and how all things are possible in this brave new
- world. This document does not describe physical storage issues nor
- interface issues.
- </para>
- <para>
- Historically mail has been organized into folders. These folders
- usually mapped to a single storage medium. The relationship between
- mail organization and storage medium was one to one. There was one
- mail organization for every storage medium. This scheme had its
- limitations.
- </para>
- <para>
- Efforts at categorizations are only meaningful at the instance that
- one categorized. To find any piece of data, regardless of how well
- it was categorized, required some amount of searching. Therefore, any
- attempts to nullify searching is doomed to fail. It's time to embrace
- searching as a way of life.
- </para>
- <para>
- These are the terms and their definitions. The example rules used are
- based on the syntax for VM (http://www.wonderworks.com/vm/) by Kyle
- Jones whose ideas form the basis for this. I'm only adding the
- existence of summary files to aid in scaling. I currently use VM and
- it's virtual-folder rules for my daily mail purposes. To date, my only
- complaints are speed (it has no caches) and for the unitiated, it's
- not very user-friendly.
- </para>
- <para>
- Comments, questions, rants, etc. should be directed at Giao Nguyen
- (grail@cafebabe.org) who will try to address issues in a timely
- manner.
- </para>
- </abstract>
-</artheader>
- <sect1 id="definitions">
- <title>Definitions</title>
- <sect2>
- <title>Store</title>
- <para>
- A location where mail can be found. This may be a file (Berkeley
- mbox), directory (MH), IMAP server, POP3 server, Exchange server,
- Lotus Notes server, a stack of Post-Its by your monitor fed through
- some OCR system.
- </para>
- </sect2>
- <sect2>
- <title>Message</title>
- <para>
- An individual mail message.
- </para>
- </sect2>
- <sect2>
- <title>Vfolder</title>
- <para>
- A group of messages sharing some commonality. This is the result of a
- query. The vfolder maybe contained in a store, but it is not necessary
- that a store holds only one vfolder. There is always an implicit
- vfolder rule which matches all messages. A store contains the vfolder
- which is the result of the query (any). It's short for virtual folder
- or maybe view folder. I dunno.
- </para>
- </sect2>
- <sect2>
- <title>Default-vfolder</title>
- <para>
- The vfolder defined by (any) applied to the store. This is not the
- inbox. The inbox could easily be defined by a query. A default rule
- for the inbox could be (new) but it doesn't have to be. Mine happens
- to be (or (unread) (new)).
- </para>
- </sect2>
- <sect2>
- <title>Folder</title>
- <para>
- The classical mail folder approach: one message organization per
- store.
- </para>
- </sect2>
- <sect2>
- <title>Query</title>
- <para>
- A search for messages. The result of this is a vfolder. There are two
- kinds of queries: named queries and lambda queries. More on this
- later.
- </para>
- </sect2>
- <sect2>
- <title>Summary file </title>
- <para>
- An external file that contains pointers to messages which are matches
- for a named query. In addition to pointers, the summary file should
- also contain signatures of the store for sanity checks. When the term
- "index" is used as a verb, it means to build a summary file for a
- given name-value pair.
- </para>
- </sect2>
- </sect1>
+ <artheader>
+ <authorgroup>
+ <author>
+ <firstname>Giao</firstname>
+ <surname>Nguyen</surname>
+ </author>
+ </authorgroup>
- <sect1>
- <title>Queries</title>
- <para>
- Named queries are analogous to classical mail folders. Because named
- queries maybe reused, summary files are kept as caches to reduce
- the overall cost of viewing a vfolder. Summary files are superior to
- folders in that they allow for the same messages to appear in multiple
- vfolders without message duplications. Duplications of messages
- defeats attempts at tagging a message with additional user information
- like annotations. Named queries will define folders.
- </para>
- <para>
- Lambda queries are similar to named queries except that they have no
- name. These are created on the fly by the user to filter out or
- include certain messages.
- </para>
- <para>
- All queries can be layered on top of each other. A lambda query can be
- layered on a named query and a named query can be layered on a lambda
- query. The possibilities are endless.
- </para>
- <para>
- The layerings can be done as boolean operations (and, or, not). Short
- circuiting should be used.
- </para>
- <para>
- Examples:
- <programlisting>
- (and (author "Giao")
- (unread))
- </programlisting>
- The (unread) query should only be evaluated on the results of (author
- "Giao").
- <programlisting>
- (or (author "Giao")
- (unread))
- </programlisting>
- Both of these queries should be evaluated. Any matches are added to the
- resulting vfolder.
- </para>
- </sect1>
-
- <sect1>
- <title>Summary files</title>
- <para>
- Summary files are only meaningful when applied to the context of the
- default-vfolder of a store.
- </para>
- <para>
- Summary files should be generated for queries of the form:
- <programlisting>
- (function "constant value")
- </programlisting>
- Summary files should never be generated for queries of the form:
- <programlisting>
- (function (function1))
-
- (and (function "value")
- (another-function "another value"))
- </programlisting>
- Given a query of the form:
- <programlisting>
- (and (function "value")
- (another-function "another value"))
- </programlisting>
- The system should use one summary file for (function "value") and
- another summary file for (another-function "another value"). I will
- call the prior form the "plain form".
- </para>
- <para>
- It should be noted that the signature of the store should be based on
- the assumption that new data may have been added to the store since
- the application generated the summary file. Signatures generated on
- the entirety of the store will most likely be meaningless for things
- like POP/IMAP servers.
- </para>
- </sect1>
+ <title>An in-depth look at the virtual folder mechanism</title>
+ <abstract>
+ <para>
+ This document describes a different way of approaching mail
+ organization and how all things are possible in this brave new
+ world. This document does not describe physical storage issues
+ nor interface issues.
+ </para>
+ <para>
+ Historically mail has been organized into folders. These
+ folders usually mapped to a single storage medium. The
+ relationship between mail organization and storage medium was
+ one to one. There was one mail organization for every storage
+ medium. This scheme had its limitations.
+ </para>
+ <para>
+ Efforts at categorizations are only meaningful at the instance that
+ one categorized. To find any piece of data, regardless of how well
+ it was categorized, required some amount of searching. Therefore, any
+ attempts to nullify searching is doomed to fail. It's time to embrace
+ searching as a way of life.
+ </para>
+ <para>
+ These are the terms and their definitions. The example rules used are
+ based on the syntax for VM (http://www.wonderworks.com/vm/) by Kyle
+ Jones whose ideas form the basis for this. I'm only adding the
+ existence of summary files to aid in scaling. I currently use VM and
+ it's virtual-folder rules for my daily mail purposes. To date, my only
+ complaints are speed (it has no caches) and for the unitiated, it's
+ not very user-friendly.
+ </para>
+ <para>
+ Comments, questions, rants, etc. should be directed at Giao Nguyen
+ (grail@cafebabe.org) who will try to address issues in a timely
+ manner.
+ </para>
+ </abstract>
+ </artheader>
- <sect1>
- <title>Incremental indexing</title>
- <para>
- When new messages are detected, all known queries should be evaluated
- on the new messages. vfolders should be notified of new messages that
- are positive matches for their queries. The indexes generated by this
- process should be merged into the current indexes for the vfolder.
- </para>
- </sect1>
+ <!-- Definitions -->
+ <sect1 id="definitions">
+ <title>Definitions</title>
+ <sect2>
+ <title>Store</title>
+ <para>
+ A location where mail can be found. This may be a file (Berkeley
+ mbox), directory (MH), IMAP server, POP3 server, Exchange server,
+ Lotus Notes server, a stack of Post-Its by your monitor fed through
+ some OCR system.
+ </para>
+ </sect2>
- <sect1>
- <title>Can I have multiple stores?</title>
- <para>
- I don't see why not. Again, the inbox is a vfolder so you can get a
- unified inbox consisting of all new mail sent to all your stores or
- your can get inboxes for each store or any combination your heart
- desire. You get your cake, eat it, and someone else cleans the dishes!
- </para>
- </sect1>
+ <sect2>
+ <title>Message</title>
+ <para>
+ An individual mail message.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Vfolder</title>
+ <para>
+ A group of messages sharing some commonality. This is the result of a
+ query. The vfolder maybe contained in a store, but it is not necessary
+ that a store holds only one vfolder. There is always an implicit
+ vfolder rule which matches all messages. A store contains the vfolder
+ which is the result of the query (any). It's short for virtual folder
+ or maybe view folder. I dunno.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Default-vfolder</title>
+ <para>
+ The vfolder defined by (any) applied to the store. This is not the
+ inbox. The inbox could easily be defined by a query. A default rule
+ for the inbox could be (new) but it doesn't have to be. Mine happens
+ to be (or (unread) (new)).
+ </para>
+ </sect2>
+ <sect2>
+ <title>Folder</title>
+ <para>
+ The classical mail folder approach: one message organization per
+ store.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Query</title>
+ <para>
+ A search for messages. The result of this is a vfolder. There are two
+ kinds of queries: named queries and lambda queries. More on this
+ later.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Summary file </title>
+ <para>
+ An external file that contains pointers to messages which are matches
+ for a named query. In addition to pointers, the summary file should
+ also contain signatures of the store for sanity checks. When the term
+ "index" is used as a verb, it means to build a summary file for a
+ given name-value pair.
+ </para>
+ </sect2>
+ </sect1>
- <sect1>
- <title>Why all this?</title>
- <para>
- Consider the dynamic nature of the following query:
- <programlisting>
- (and (author "Giao")
- (sent-after (today-midnight)))
- </programlisting>
- today-midnight would be a function that is evaluated at run-time to
- calculate the appropriate object.
- </para>
- </sect1>
+ <!-- Queries -->
+ <sect1>
+ <title>Queries</title>
+ <para>
+ Named queries are analogous to classical mail folders. Because named
+ queries maybe reused, summary files are kept as caches to reduce
+ the overall cost of viewing a vfolder. Summary files are superior to
+ folders in that they allow for the same messages to appear in multiple
+ vfolders without message duplications. Duplications of messages
+ defeats attempts at tagging a message with additional user information
+ like annotations. Named queries will define folders.
+ </para>
+ <para>
+ Lambda queries are similar to named queries except that they have no
+ name. These are created on the fly by the user to filter out or
+ include certain messages.
+ </para>
+ <para>
+ All queries can be layered on top of each other. A lambda query can be
+ layered on a named query and a named query can be layered on a lambda
+ query. The possibilities are endless.
+ </para>
+ <para>
+ The layerings can be done as boolean operations (and, or, not). Short
+ circuiting should be used.
+ </para>
+ <para>
+ Examples:
+ <programlisting>
+(and (author "Giao")
+ (unread))
+ </programlisting>
+ The (unread) query should only be evaluated on the results of (author
+ "Giao").
+ <programlisting>
+(or (author "Giao")
+ (unread))
+ </programlisting>
+ Both of these queries should be evaluated. Any matches are added to the
+ resulting vfolder.
+ </para>
+ </sect1>
- <sect1>
- <title>Scenarios of usage and their solutions</title>
- <sect2>
- <title>Mesage alterations</title>
- <para>
- This is a fuzzy area that should be left to the UI to handle. Messages
- are altered. Read status are altered when a new message is read for
- example. How do we handle this if our query is for unread messages?
- Upon viewing the state would change.
- </para>
- <para>
- One idea is to not evaluate the queries unless we're changing between
- vfolder views. This assumes that one can only view a particular
- vfolder at a time. For multi-vfolder viewing, a message change should
- propagate through the vfolder system. Certain effects (as in our
- example) would not be intuitive.
- </para>
- <para>
- It would not be a clean solution to make special cases but they may be
- necessary where certain defined fields are ignored when they are
- changed. Some combination of the above rules can be used. I don't
- think it's an easy solution.
- </para>
- </sect2>
- <sect2>
- <title>Message inclusion and exclusion</title>
- <para>
- Messages are included and excluded also with queries. The final query
- will have the form of:
- <programlisting>
- (and (author "Giao")
- (criteria value)
- (not (criteria other-value)))
- </programlisting>
- Userland criterias may be a label of some sort. These may be userland
- labels or Message-IDs. What are the performance issues involved in
- this? With short circuiting, it's not a major problem.
- </para>
- <para>
- The criterias and values are determined by the UI. The vfolder
- mechanism isn't concerned with such issues.
- </para>
- <para>
- Messages can be included and excluded at will. The idea is often
- called "arbitrary inclusion/exclusion". This can be done by
- Message-IDs or other fields. It's been noted that Message-IDs are not
- unique.
- </para>
- <para>
- I propose that any given vfolder is allocated an inclusion label and an
- exclusion label. These should be randomly generated. This should be
- part of the vfolder description. It should be noted that the vfolder
- description has not been drafted yet.
- </para>
- <para>
- The result is such that the rules for a given named query is:
- <programlisting>
- (and (user-query)
- (label inclusion-label)
- (not exclusion-label))
- </programlisting>
- </para>
- </sect2>
- <sect2>
- <title>Query scheduling</title>
- <para>
- Consider the following extremely dynamic queries:
- <programlisting>
- A:
- (and (author "Giao")
- (sent-after (today-midnight)))
-
- B:
- (and (sent-after (today-midnight))
- (author "Giao"))
-
- C:
- (or (author "Giao")
- (sent-after (today-midnight)))
- </programlisting>
- Query A would be significantly faster because (author "Giao") is not
- dynamic. A summary file could be generated for this query. Query B is
- slow and can be optimized if there was a query compiler of some
- sort. Query C demonstrates a query in which there is no good
- optimization which can be applied. These come with a certain amount of
- baggage.
- </para>
- <para>
- It seems then that for boolean 'and' operations, plain forms should be
- moved forward and other queries should be moved such that they are
- evaluated later. I would expect that the majority of queries would be
- of the plain form.
- </para>
- <para>
- First is that the summary file is tied to the query and the store
- where the query originates from. Second, a hashing function for
- strings needs to be calculated for the query so that the query and the
- summary file can be associated. This hashing function could be similar
- to the hashing function described in Rob Pike's "The Practice of
- Programming". (FIXME: Stick page number here)
- </para>
- </sect2>
- <sect2>
- <title>Archives</title>
- <para>
- Many people are concerned that archives won't be preserved, archives
- aren't supported, and many other archive related issues. This is the
- short version.
- </para>
- <para>
- Archives are just that, archives. Archives are stores. Take your
- vfolder, export it to a store. You are done. If you load up the store
- again, then the default-vfolder of that store is the view of the
- vfolder, except the query is different.
- </para>
- <para>
- The point to vfolder is not to do away with classical folder
- representation but to move the queries to the front where it would
- make data management easier for people who don't think in terms of
- files but in terms of queries because ordinary people don't think in
- terms of files.
- </para>
- </sect2>
- </sect1>
+ <!-- Summary files -->
+ <sect1>
+ <title>Summary files</title>
+ <para>
+ Summary files are only meaningful when applied to the context of the
+ default-vfolder of a store.
+ </para>
+ <para>
+ Summary files should be generated for queries of the form:
+ <programlisting>
+(function "constant value")
+ </programlisting>
+ Summary files should never be generated for queries of the form:
+ <programlisting>
+ (function (function1))
+
+ (and (function "value")
+ (another-function "another value"))
+ </programlisting>
+ Given a query of the form:
+ <programlisting>
+ (and (function "value")
+ (another-function "another value"))
+ </programlisting>
+ The system should use one summary file for (function "value") and
+ another summary file for (another-function "another value"). I will
+ call the prior form the "plain form".
+ </para>
+ <para>
+ It should be noted that the signature of the store should be based on
+ the assumption that new data may have been added to the store since
+ the application generated the summary file. Signatures generated on
+ the entirety of the store will most likely be meaningless for things
+ like POP/IMAP servers.
+ </para>
+ </sect1>
- <sect1>
- <title>Miscellany</title>
- <sect2>
- <title>Annotations</title>
- <para>
- There should be a scheme to add annotations to messages. Common mail
- user agents have used a tag in the message header to mark messages as
- read/unread for example. Extending on this we have the ability to add
- our own data to a message to add meaning to it. If we have a good
- scheme for doing this, new possibilities are opened.
- </para>
- <sect3>
- <title>Keywords</title>
+ <!-- Incremental Indexing -->
+ <sect1>
+ <title>Incremental indexing</title>
<para>
- When sending a message, a message could have certain keywords attached
- to it. While this can be done with the subject line, the subject line
- has a tendency to be munged by other mail applications. One popular
- example is the "[rR]e:" prefix. Using the subject line also breaks the
- "contract" with other mail user agents. Using keywords in another
- field in the message header allows the sender to assist the recipient
- in organizing data automatically. Note that the sender can only
- provide hints as the sender is unlikely to know the organization
- schemes of the recipient.
+ When new messages are detected, all known queries should be evaluated
+ on the new messages. vfolders should be notified of new messages that
+ are positive matches for their queries. The indexes generated by this
+ process should be merged into the current indexes for the vfolder.
</para>
- </sect3>
- </sect2>
- <sect2>
- <title>Scope</title>
- <para>
- Let us assume that we have multiple stores. Does a query work on a
- given store? Or does it work on all stores? Or is it configurable such
- that a query can work on a user-selected list of stores?
- </para>
- </sect2>
- </sect1>
+ </sect1>
- <sect1>
- <title>Alternatives to the above</title>
- <para>
- Jim Meyer (purp@selequa.com) is putting some notes on where
- annotations needs to be located. They'll be located here as well as
- any contributions I may have to them.
- </para>
- </sect1>
+ <!-- Can I have multiple stores -->
+ <sect1>
+ <title>Can I have multiple stores?</title>
+ <para>
+ I don't see why not. Again, the inbox is a vfolder so you can get a
+ unified inbox consisting of all new mail sent to all your stores or
+ your can get inboxes for each store or any combination your heart
+ desire. You get your cake, eat it, and someone else cleans the dishes!
+ </para>
+ </sect1>
+
+ <!-- Why all this? -->
+ <sect1>
+ <title>Why all this?</title>
+ <para>
+ Consider the dynamic nature of the following query:
+ <programlisting>
+(and (author "Giao")
+ (sent-after (today-midnight)))
+ </programlisting>
+ today-midnight would be a function that is evaluated at run-time to
+ calculate the appropriate object.
+ </para>
+ </sect1>
+
+ <!-- Scenarios of usage and their solutions -->
+ <sect1>
+ <title>Scenarios of usage and their solutions</title>
+ <sect2>
+ <title>Mesage alterations</title>
+ <para>
+ This is a fuzzy area that should be left to the UI to handle. Messages
+ are altered. Read status are altered when a new message is read for
+ example. How do we handle this if our query is for unread messages?
+ Upon viewing the state would change.
+ </para>
+ <para>
+ One idea is to not evaluate the queries unless we're changing between
+ vfolder views. This assumes that one can only view a particular
+ vfolder at a time. For multi-vfolder viewing, a message change should
+ propagate through the vfolder system. Certain effects (as in our
+ example) would not be intuitive.
+ </para>
+ <para>
+ It would not be a clean solution to make special cases but they may be
+ necessary where certain defined fields are ignored when they are
+ changed. Some combination of the above rules can be used. I don't
+ think it's an easy solution.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Message inclusion and exclusion</title>
+ <para>
+ Messages are included and excluded also with queries. The final query
+ will have the form of:
+ <programlisting>
+ (and (author "Giao")
+ (criteria value)
+ (not (criteria other-value)))
+ </programlisting>
+ Userland criterias may be a label of some sort. These may be userland
+ labels or Message-IDs. What are the performance issues involved in
+ this? With short circuiting, it's not a major problem.
+ </para>
+ <para>
+ The criterias and values are determined by the UI. The vfolder
+ mechanism isn't concerned with such issues.
+ </para>
+ <para>
+ Messages can be included and excluded at will. The idea is often
+ called "arbitrary inclusion/exclusion". This can be done by
+ Message-IDs or other fields. It's been noted that Message-IDs are not
+ unique.
+ </para>
+ <para>
+ I propose that any given vfolder is allocated an inclusion label and an
+ exclusion label. These should be randomly generated. This should be
+ part of the vfolder description. It should be noted that the vfolder
+ description has not been drafted yet.
+ </para>
+ <para>
+ The result is such that the rules for a given named query is:
+ <programlisting>
+ (and (user-query)
+ (label inclusion-label)
+ (not exclusion-label))
+ </programlisting>
+ </para>
+ </sect2>
+ <sect2>
+ <title>Query scheduling</title>
+ <para>
+ Consider the following extremely dynamic queries:
+ <programlisting>
+ A:
+ (and (author "Giao")
+ (sent-after (today-midnight)))
+
+ B:
+ (and (sent-after (today-midnight))
+ (author "Giao"))
+
+ C:
+ (or (author "Giao")
+ (sent-after (today-midnight)))
+ </programlisting>
+ Query A would be significantly faster because (author "Giao") is not
+ dynamic. A summary file could be generated for this query. Query B is
+ slow and can be optimized if there was a query compiler of some
+ sort. Query C demonstrates a query in which there is no good
+ optimization which can be applied. These come with a certain amount of
+ baggage.
+ </para>
+ <para>
+ It seems then that for boolean 'and' operations, plain forms should be
+ moved forward and other queries should be moved such that they are
+ evaluated later. I would expect that the majority of queries would be
+ of the plain form.
+ </para>
+ <para>
+ First is that the summary file is tied to the query and the store
+ where the query originates from. Second, a hashing function for
+ strings needs to be calculated for the query so that the query and the
+ summary file can be associated. This hashing function could be similar
+ to the hashing function described in Rob Pike's "The Practice of
+ Programming". (FIXME: Stick page number here)
+ </para>
+ </sect2>
+ <sect2>
+ <title>Archives</title>
+ <para>
+ Many people are concerned that archives won't be preserved, archives
+ aren't supported, and many other archive related issues. This is the
+ short version.
+ </para>
+ <para>
+ Archives are just that, archives. Archives are stores. Take your
+ vfolder, export it to a store. You are done. If you load up the store
+ again, then the default-vfolder of that store is the view of the
+ vfolder, except the query is different.
+ </para>
+ <para>
+ The point to vfolder is not to do away with classical folder
+ representation but to move the queries to the front where it would
+ make data management easier for people who don't think in terms of
+ files but in terms of queries because ordinary people don't think in
+ terms of files.
+ </para>
+ </sect2>
+ </sect1>
+
+ <!-- Miscellany -->
+ <sect1>
+ <title>Miscellany</title>
+ <sect2>
+ <title>Annotations</title>
+ <para>
+ There should be a scheme to add annotations to messages. Common mail
+ user agents have used a tag in the message header to mark messages as
+ read/unread for example. Extending on this we have the ability to add
+ our own data to a message to add meaning to it. If we have a good
+ scheme for doing this, new possibilities are opened.
+ </para>
+ <sect3>
+ <title>Keywords</title>
+ <para>
+ When sending a message, a message could have certain keywords attached
+ to it. While this can be done with the subject line, the subject line
+ has a tendency to be munged by other mail applications. One popular
+ example is the "[rR]e:" prefix. Using the subject line also breaks the
+ "contract" with other mail user agents. Using keywords in another
+ field in the message header allows the sender to assist the recipient
+ in organizing data automatically. Note that the sender can only
+ provide hints as the sender is unlikely to know the organization
+ schemes of the recipient.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Scope</title>
+ <para>
+ Let us assume that we have multiple stores. Does a query work on a
+ given store? Or does it work on all stores? Or is it configurable such
+ that a query can work on a user-selected list of stores?
+ </para>
+ </sect2>
+ </sect1>
+
+ <!-- Alternatives to the above -->
+ <sect1>
+ <title>Alternatives to the above</title>
+ <para>
+ Jim Meyer (purp@selequa.com) is putting some notes on where
+ annotations needs to be located. They'll be located here as well as
+ any contributions I may have to them.
+ </para>
+ </sect1>
</article>