diff options
-rw-r--r-- | camel/camel-folder.c | 2 | ||||
-rw-r--r-- | camel/camel-log.h | 2 | ||||
-rw-r--r-- | camel/camel-mime-message.c | 46 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 51 | ||||
-rw-r--r-- | camel/camel-mime-part.h | 3 | ||||
-rw-r--r-- | camel/gmime-utils.c | 37 | ||||
-rw-r--r-- | camel/gmime-utils.h | 2 | ||||
-rw-r--r-- | camel/gstring-util.c | 47 | ||||
-rw-r--r-- | camel/gstring-util.h | 7 | ||||
-rw-r--r-- | tests/test2.c | 36 |
10 files changed, 193 insertions, 40 deletions
diff --git a/camel/camel-folder.c b/camel/camel-folder.c index 09ba5a7fa9..26b051c4d7 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -367,7 +367,7 @@ _create(CamelFolder *folder) if (folder->parent_folder) camel_folder_create(folder->parent_folder); else { if (folder->full_name) { - dich_result = g_string_right_dichotomy(folder->full_name, sep, &prefix, NULL, STRIP_TRAILING); + dich_result = g_string_dichotomy(folder->full_name, sep, &prefix, NULL, STRIP_TRAILING | 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.h b/camel/camel-log.h index 2e68fdc770..b2c9cbe305 100644 --- a/camel/camel-log.h +++ b/camel/camel-log.h @@ -33,6 +33,8 @@ extern FILE *camel_log_file_descriptor; typedef enum { NO_LOG = 0, + STRANGE = 5, + WARNING = 7, FULL_DEBUG = 10 } CamelLogLevel; diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index 13d8f30f8c..01f9b48e27 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -26,6 +26,13 @@ #include <stdio.h> #include "gmime-content-field.h" #include "gstring-util.h" +#include "camel-log.h" + +typedef enum { + HEADER_UNKNOWN, + HEADER_FROM +} CamelHeaderType; +static GHashTable *header_name_table; @@ -58,12 +65,20 @@ static void _set_message_number (CamelMimeMessage *mime_message, guint number); static guint _get_message_number (CamelMimeMessage *mime_message); static void _write_to_file(CamelDataWrapper *data_wrapper, FILE *file); +static gboolean _parse_header_pair (CamelMimePart *mime_part, GString *header_name, GString *header_value); /* Returns the class for a CamelMimeMessage */ #define CMM_CLASS(so) CAMEL_MIME_MESSAGE_CLASS (GTK_OBJECT(so)->klass) #define CDW_CLASS(so) CAMEL_DATA_WRAPPER_CLASS (GTK_OBJECT(so)->klass) +static void +_init_header_name_table() +{ + header_name_table = g_hash_table_new (g_string_hash, g_string_equal_for_hash); + g_hash_table_insert (header_name_table, g_string_new ("From"), (gpointer)HEADER_FROM); + +} static void camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) @@ -72,6 +87,7 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) CamelMimePartClass *camel_mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_class); parent_class = gtk_type_class (camel_mime_part_get_type ()); + _init_header_name_table(); received_date_str = g_string_new(""); sent_date_str = g_string_new(""); @@ -99,6 +115,8 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class) /* virtual method overload */ camel_data_wrapper_class->write_to_file = _write_to_file; + camel_mime_part_class->parse_header_pair = _parse_header_pair; + } @@ -521,3 +539,31 @@ _write_to_file (CamelDataWrapper *data_wrapper, FILE *file) } +/*******************************/ +/* mime message header parsing */ + +static gboolean +_parse_header_pair (CamelMimePart *mime_part, GString *header_name, GString *header_value) +{ + CamelHeaderType header_type; + CamelMimeMessage *message = CAMEL_MIME_MESSAGE (mime_part); + + + header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, header_name); + switch (header_type) { + + case HEADER_FROM: + camel_log(FULL_DEBUG, + "CamelMimeMessage::parse_header_pair found HEADER_FROM : %s\n", + header_value->str ); + + camel_mime_message_set_from (message, header_value); + g_string_free (header_name, TRUE); + return TRUE; + break; + + } + + return parent_class->parse_header_pair (mime_part, header_name, header_value); + +} diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 7be15d20fe..1a18aeeb4b 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -28,6 +28,16 @@ #include "gstring-util.h" +typedef enum { + HEADER_UNKNOWN, + HEADER_DESCRIPTION, + HEADER_DISPOSITION, + HEADER_CONTENT_ID, + HEADER_ENCODING, + HEADER_CONTENT_LANGUAGES +} CamelHeaderType; +static GHashTable *header_name_table; + static CamelDataWrapperClass *parent_class=NULL; @@ -57,14 +67,24 @@ static GList *_get_header_lines (CamelMimePart *mime_part); static CamelDataWrapper *_get_content_object(CamelMimePart *mime_part); static void _write_to_file(CamelDataWrapper *data_wrapper, FILE *file); +static gboolean _parse_header_pair (CamelMimePart *mime_part, GString *header_name, GString *header_value); +static void +_init_header_name_table() +{ + header_name_table = g_hash_table_new (g_string_hash, g_string_equal_for_hash); + g_hash_table_insert (header_name_table, g_string_new ("Content-Description"), (gpointer)HEADER_DESCRIPTION); + g_hash_table_insert (header_name_table, g_string_new ("Content-Disposition"), (gpointer)HEADER_DISPOSITION); + +} static void camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) { CamelDataWrapperClass *camel_data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_mime_part_class); parent_class = gtk_type_class (camel_data_wrapper_get_type ()); + _init_header_name_table(); /* virtual method definition */ camel_mime_part_class->add_header=_add_header; @@ -86,8 +106,10 @@ camel_mime_part_class_init (CamelMimePartClass *camel_mime_part_class) camel_mime_part_class->get_content_languages=_get_content_languages; camel_mime_part_class->set_header_lines=_set_header_lines; camel_mime_part_class->get_header_lines=_get_header_lines; - + camel_mime_part_class->parse_header_pair = _parse_header_pair; camel_mime_part_class->get_content_object = _get_content_object; + + /* virtual method overload */ camel_data_wrapper_class->write_to_file = _write_to_file; @@ -98,7 +120,7 @@ camel_mime_part_init (gpointer object, gpointer klass) { CamelMimePart *camel_mime_part = CAMEL_MIME_PART (object); - camel_mime_part->headers = g_hash_table_new(g_string_hash, g_string_equal_for_hash); + camel_mime_part->headers = g_hash_table_new (g_string_hash, g_string_equal_for_hash); } @@ -138,7 +160,9 @@ _add_header (CamelMimePart *mime_part, GString *header_name, GString *header_val gboolean header_exists; GString *old_header_name; GString *old_header_value; - + + if (CMP_CLASS(mime_part)->parse_header_pair (mime_part, header_name, header_value)) + return; header_exists = g_hash_table_lookup_extended (mime_part->headers, header_name, (gpointer *) &old_header_name, (gpointer *) &old_header_value); @@ -503,3 +527,24 @@ _write_to_file(CamelDataWrapper *data_wrapper, FILE *file) } + + +/*******************************/ +/* mime part parsing */ + +static gboolean +_parse_header_pair (CamelMimePart *mime_part, GString *header_name, GString *header_value) +{ + CamelHeaderType header_type; + header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, header_name); + switch (header_type) { + + case HEADER_DESCRIPTION: + printf("found HEADER_DESCRIPTION\n"); + return TRUE; + break; + + } + return FALSE; + +} diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index 3fdb75dee7..7cd724e44f 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -87,7 +87,8 @@ typedef struct { GList * (*get_content_languages) (CamelMimePart *mime_part); void (*set_header_lines) (CamelMimePart *mime_part, GList *header_lines); GList * (*get_header_lines) (CamelMimePart *mime_part); - + gboolean (*parse_header_pair) (CamelMimePart *mime_part, GString *header_name, GString *header_value); + CamelDataWrapper * (*get_content_object) (CamelMimePart *mime_part); } CamelMimePartClass; diff --git a/camel/gmime-utils.c b/camel/gmime-utils.c index f4009e91cf..9f489a257a 100644 --- a/camel/gmime-utils.c +++ b/camel/gmime-utils.c @@ -24,6 +24,9 @@ #include "gmime-utils.h" +#include "gstring-util.h" +#include "camel-log.h" + void gmime_write_header_pair_to_file (FILE* file, gchar* name, GString *value) { @@ -88,9 +91,29 @@ write_header_with_glist_to_file (FILE *file, gchar *header_name, GList *header_v /* * * * * * * * * * * */ /* scanning functions */ +static void +_store_header_pair_from_gstring (GHashTable *header_table, GString *header_line) +{ + gchar dich_result; + GString *header_name, *header_value; + + g_assert (header_table); + if ( (header_line) && (header_line->str) ) { + dich_result = g_string_dichotomy(header_line, ':', &header_name, &header_value, 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_hash_table_insert (header_table, header_name, header_value); + } + +} + -GList * -get_header_lines_from_file (FILE *file) +GHashTable * +get_header_table_from_file (FILE *file) { int next_char; @@ -99,8 +122,9 @@ get_header_lines_from_file (FILE *file) gboolean end_of_headers = FALSE; gboolean end_of_file = FALSE; GString *header_line=NULL; - GList *header_lines=NULL; + GHashTable *header_table; + header_table = g_hash_table_new (g_string_hash, g_string_equal_for_hash); next_char = fgetc (file); do { header_line = g_string_new(""); @@ -137,13 +161,12 @@ get_header_lines_from_file (FILE *file) } while ( !end_of_header_line ); if ( strlen(header_line->str) ) - header_lines = g_list_append (header_lines, header_line); - else - g_string_free (header_line, FALSE); + _store_header_pair_from_gstring (header_table, header_line); + g_string_free (header_line, FALSE); } while ( (!end_of_headers) && (!end_of_file) ); - return header_lines; + return header_table; } diff --git a/camel/gmime-utils.h b/camel/gmime-utils.h index d7ce1d0843..dafc5ca18a 100644 --- a/camel/gmime-utils.h +++ b/camel/gmime-utils.h @@ -38,7 +38,7 @@ void gmime_write_header_pair_to_file (FILE* file, gchar* name, GString *value); void write_header_table_to_file (FILE *file, GHashTable *header_table); void write_header_with_glist_to_file (FILE *file, gchar *header_name, GList *header_values); -GList *get_header_lines_from_file (FILE *file); +GHashTable *get_header_table_from_file (FILE *file); diff --git a/camel/gstring-util.c b/camel/gstring-util.c index 4d0411de33..5d11fa91a8 100644 --- a/camel/gstring-util.c +++ b/camel/gstring-util.c @@ -64,7 +64,7 @@ g_string_clone(GString *string) /** - * right_dichotomy : return the strings before and/or after + * g_string_dichotomy : return the strings before and/or after * the last occurence of the specified separator * * This routine returns the string before and/or after @@ -85,20 +85,20 @@ g_string_clone(GString *string) * **/ gchar -g_string_right_dichotomy( GString *string, gchar sep, GString **prefix, GString **suffix, DichotomyOption options) +g_string_dichotomy (GString *string, gchar sep, GString **prefix, GString **suffix, DichotomyOption options) { gchar *str, *tmp; gint pos, len, first; CAMEL_LOG(FULL_DEBUG,\ - "Entering rightDichotomy: \n\tseparator=%c \n\tprefix=%p \n\tsuffix=%p \n\toptions=%ld\n",\ + "Entering string_dichotomy: \n\tseparator=%c \n\tprefix=%p \n\tsuffix=%p \n\toptions=%ld\n",\ sep, prefix, suffix, options); g_assert( tmp=string->str ); len = strlen(tmp); if (!len) { if (prefix) *prefix=NULL; if (suffix) *suffix=NULL; - CAMEL_LOG(FULL_DEBUG,"rightDichotomy: string is empty\n"); + CAMEL_LOG(FULL_DEBUG,"string_dichotomy: string is empty\n"); return 'n'; } first = 0; @@ -113,32 +113,48 @@ g_string_right_dichotomy( GString *string, gchar sep, GString **prefix, GString if (first==len) { if (prefix) *prefix=NULL; if (suffix) *suffix=NULL; - CAMEL_LOG(FULL_DEBUG,"rightDichotomy: after stripping, string is empty\n"); + CAMEL_LOG(FULL_DEBUG,"string_dichotomy: after stripping, string is empty\n"); return 'n'; } - pos = len; - - do { - pos--; - } while ((pos>=first) && (tmp[pos]!=sep)); - + if (options & RIGHT_DIR) { + pos = len; + + do { + pos--; + } while ((pos>=first) && (tmp[pos]!=sep)); + } else { + pos = first; + do { + pos++; + } while ((pos<len) && (tmp[pos]!=sep)); + + } - if (pos<first) + if ( (pos<first) || (pos>=len) ) { if (suffix) *suffix=NULL; if (prefix) *prefix=NULL; - CAMEL_LOG(FULL_DEBUG,"rightDichotomy: separator not found\n"); + CAMEL_LOG(FULL_DEBUG,"string_dichotomy: separator not found\n"); return 'n'; } - /* if we have stripped trailongs separators, we should */ + /* if we have stripped trailing separators, we should */ /* never enter here */ if (pos==len-1) { if (suffix) *suffix=NULL; if (prefix) *prefix=NULL; - CAMEL_LOG(FULL_DEBUG,"rightDichotomy: separator is last character\n"); + CAMEL_LOG(FULL_DEBUG,"string_dichotomy: separator is last character\n"); + return 'l'; + } + /* if we have stripped leading separators, we should */ + /* never enter here */ + if (pos==first) + { + if (suffix) *suffix=NULL; + if (prefix) *prefix=NULL; + CAMEL_LOG(FULL_DEBUG,"string_dichotomy: separator is first character\n"); return 'l'; } @@ -159,7 +175,6 @@ g_string_right_dichotomy( GString *string, gchar sep, GString **prefix, GString } - /** * g_string_append_g_string : append a GString to another GString * diff --git a/camel/gstring-util.h b/camel/gstring-util.h index f8b7ee3fd1..8d88bf18af 100644 --- a/camel/gstring-util.h +++ b/camel/gstring-util.h @@ -36,15 +36,16 @@ extern "C" { typedef enum { NONE = 0, - STRIP_TRAILING = 1, - STRIP_LEADING = 2 + RIGHT_DIR = 1, + STRIP_TRAILING = 2, + STRIP_LEADING = 4, } DichotomyOption; gboolean g_string_equals(GString *string1, GString *string2); GString *g_string_clone(GString *string); -gchar g_string_right_dichotomy( GString *string, gchar sep, GString **prefix, GString **suffix, DichotomyOption options); +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_equal_for_hash (gconstpointer v, gconstpointer v2); diff --git a/tests/test2.c b/tests/test2.c index be72e8f8a6..4fa3bc59f1 100644 --- a/tests/test2.c +++ b/tests/test2.c @@ -2,34 +2,54 @@ /* tests mime message file parsing */ #include "gmime-utils.h" #include "stdio.h" +#include "camel-log.h" +#include "camel-mime-message.h" +#include "camel-mime-part.h" -void print_header_line (gpointer data, gpointer user_data) +void print_header_pair (gpointer key, gpointer value, gpointer user_data) { - GString *header_line = (GString *)data; + GString *header_name = (GString *)key; + GString *header_value = (GString *)value; + CamelMimeMessage *message = (CamelMimeMessage *) user_data; + + printf("\n--------- New Header ----------\n"); - if ((header_line) && (header_line->str)) - printf("%s\n", header_line->str); + if ((header_name) && (header_name->str)) + printf("header name :%s\n", header_name->str); + if ((header_value) && (header_value->str)) + printf("header value :%s\n", header_value->str); + + camel_mime_part_add_header ( CAMEL_MIME_PART (message), header_name, header_value); + printf("--------- End -----------------\n"); + } void main (int argc, char**argv) { FILE *input_file; - GList *header_lines; + GHashTable *header_table; + CamelMimeMessage *message; + + gtk_init (&argc, &argv); - + camel_debug_level = WARNING; + message = camel_mime_message_new_with_session( (CamelSession *)NULL); + input_file = fopen ("mail.test", "r"); if (!input_file) { perror("could not open input file"); exit(2); } - header_lines = get_header_lines_from_file (input_file); - if (header_lines) g_list_foreach (header_lines, print_header_line, NULL); + header_table = get_header_table_from_file (input_file); + + if (header_table) g_hash_table_foreach (header_table, print_header_pair, (gpointer)message); else printf("header is empty, no header line present\n"); + fclose (input_file); |