evolution-data-server r8761 - in trunk: . camel camel/providers/imapp docs/reference/camel docs/reference/camel/tmpl docs/reference/libebackend docs/reference/libedataserver libedataserver
- From: mbarnes svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r8761 - in trunk: . camel camel/providers/imapp docs/reference/camel docs/reference/camel/tmpl docs/reference/libebackend docs/reference/libedataserver libedataserver
- Date: Wed, 7 May 2008 03:15:40 +0100 (BST)
Author: mbarnes
Date: Wed May 7 02:15:39 2008
New Revision: 8761
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8761&view=rev
Log:
2008-05-06 Matthew Barnes <mbarnes redhat com>
** Fixes part of bug #424744
* libedataserver/e-iconv.[ch]:
Deprecate the e-iconv API. Use camel-iconv instead.
* libedataserver/e-trie.[ch]:
Deprecate the ETrie API. Use CamelTrie instead.
* libedataserver/e-msgport.[ch]:
Deprecate the EMsgPort API. Use CamelMsgPort instead.
* camel/Makefile.am:
* camel-iconv.[ch]:
* camel-msgport.[ch]:
* camel-trie.[ch]:
Add camel-iconv.[ch], camel-msgport.[ch], camel-trie.[ch].
Essentially they're just renamed versions of equivalent but now
deprecated API in libedataserver.
* camel/camel.h:
#include <camel/camel-msgport.h>
#include <camel/camel-trie.h>
* camel/camel-charset-map.c:
* camel/camel-filter-search.c:
* camel/camel-mime-utils.c:
* camel/camel-mime-part.c:
* camel/camel-sasl-digest-md5.c:
* camel/camel-mime-message.c:
* camel/camel-gpg-context.c:
* camel/camel-mime-filter-charset.c:
* camel/camel-folder-summary.c:
Use camel-iconv.h instead of e-iconv.h.
* camel/camel-net-utils.c:
* camel/camel-operation.c:
* camel/camel-session.h:
Use camel-msgport.h instead of e-msgport.h.
* camel/camel-url-scanner.c:
Use camel-trie.h instead of e-trie.h.
* camel/providers/imapp/camel-imapp-driver.c:
* camel/providers/imapp/camel-imapp-engine.c:
Use CamelMsgPort instead of EMsgPort.
Added:
trunk/camel/camel-iconv.c
trunk/camel/camel-msgport.c
trunk/camel/camel-msgport.h
trunk/camel/camel-trie.c
trunk/camel/camel-trie.h
Modified:
trunk/ChangeLog
trunk/camel/ChangeLog
trunk/camel/Makefile.am
trunk/camel/camel-charset-map.c
trunk/camel/camel-filter-search.c
trunk/camel/camel-folder-summary.c
trunk/camel/camel-gpg-context.c
trunk/camel/camel-iconv.h
trunk/camel/camel-mime-filter-charset.c
trunk/camel/camel-mime-message.c
trunk/camel/camel-mime-part-utils.c
trunk/camel/camel-mime-part.c
trunk/camel/camel-mime-utils.c
trunk/camel/camel-net-utils.c
trunk/camel/camel-operation.c
trunk/camel/camel-sasl-digest-md5.c
trunk/camel/camel-session.h
trunk/camel/camel-url-scanner.c
trunk/camel/camel.h
trunk/camel/providers/imapp/ChangeLog
trunk/camel/providers/imapp/camel-imapp-driver.c
trunk/camel/providers/imapp/camel-imapp-engine.c
trunk/docs/reference/camel/camel-docs.sgml
trunk/docs/reference/camel/camel-sections.txt
trunk/docs/reference/camel/tmpl/camel-unused.sgml
trunk/docs/reference/libebackend/libebackend-sections.txt
trunk/docs/reference/libedataserver/libedataserver-sections.txt
trunk/libedataserver/e-iconv.h
trunk/libedataserver/e-msgport.h
trunk/libedataserver/e-trie.h
Modified: trunk/camel/Makefile.am
==============================================================================
--- trunk/camel/Makefile.am (original)
+++ trunk/camel/Makefile.am Wed May 7 02:15:39 2008
@@ -161,6 +161,7 @@
camel-exception.c \
camel-file-utils.c \
camel-html-parser.c \
+ camel-iconv.c \
camel-index.c \
camel-internet-address.c \
camel-junk-plugin.c \
@@ -190,6 +191,7 @@
camel-mime-part.c \
camel-mime-utils.c \
camel-mime-tables.c \
+ camel-msgport.c \
camel-multipart-encrypted.c \
camel-multipart-signed.c \
camel-multipart.c \
@@ -209,6 +211,7 @@
camel-stream.c \
camel-string-utils.c \
camel-text-index.c \
+ camel-trie.c \
camel-url-scanner.c \
camel-url.c \
camel-utf8.c \
@@ -229,6 +232,7 @@
camel-exception.h \
camel-file-utils.h \
camel-i18n.h \
+ camel-iconv.h \
camel-index.h \
camel-internet-address.h \
camel-junk-plugin.h \
@@ -258,6 +262,7 @@
camel-mime-part-utils.h \
camel-mime-part.h \
camel-mime-utils.h \
+ camel-msgport.h \
camel-multipart-encrypted.h \
camel-multipart-signed.h \
camel-multipart.h \
@@ -279,6 +284,7 @@
camel-stream.h \
camel-string-utils.h \
camel-text-index.h \
+ camel-trie.h \
camel-types.h \
camel-url-scanner.h \
camel-url.h \
Modified: trunk/camel/camel-charset-map.c
==============================================================================
--- trunk/camel/camel-charset-map.c (original)
+++ trunk/camel/camel-charset-map.c Wed May 7 02:15:39 2008
@@ -39,6 +39,8 @@
#include <iconv.h>
#include <errno.h>
+#include "camel-iconv.h"
+
/*
if you want to build the charset map, compile this with something like:
gcc -DBUILD_MAP camel-charset-map.c `pkg-config --cflags --libs glib-2.0`
@@ -305,8 +307,6 @@
#include "camel-charset-map-private.h"
#include "camel-utf8.h"
-#include <libedataserver/e-iconv.h>
-
void
camel_charset_init (CamelCharset *c)
{
@@ -353,10 +353,10 @@
const char *locale_lang, *lang;
int i;
- locale_lang = e_iconv_locale_language ();
+ locale_lang = camel_iconv_locale_language ();
for (i = 0; i < G_N_ELEMENTS (camel_charinfo); i++) {
if (camel_charinfo[i].bit & mask) {
- lang = e_iconv_charset_language (camel_charinfo[i].name);
+ lang = camel_iconv_charset_language (camel_charinfo[i].name);
if (!locale_lang || (lang && !strncmp (locale_lang, lang, 2)))
return camel_charinfo[i].name;
Modified: trunk/camel/camel-filter-search.c
==============================================================================
--- trunk/camel/camel-filter-search.c (original)
+++ trunk/camel/camel-filter-search.c Wed May 7 02:15:39 2008
@@ -45,12 +45,12 @@
#include <sys/wait.h>
#endif
-#include <libedataserver/e-iconv.h>
#include <libedataserver/e-sexp.h>
#include "camel-debug.h"
#include "camel-exception.h"
#include "camel-filter-search.h"
+#include "camel-iconv.h"
#include "camel-mime-message.h"
#include "camel-multipart.h"
#include "camel-provider.h"
@@ -180,7 +180,7 @@
ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (message));
if (ct) {
charset = camel_content_type_param (ct, "charset");
- charset = e_iconv_charset_name (charset);
+ charset = camel_iconv_charset_name (charset);
}
}
Modified: trunk/camel/camel-folder-summary.c
==============================================================================
--- trunk/camel/camel-folder-summary.c (original)
+++ trunk/camel/camel-folder-summary.c Wed May 7 02:15:39 2008
@@ -36,12 +36,12 @@
#include <glib.h>
#include <glib/gstdio.h>
-#include <libedataserver/e-iconv.h>
#include <libedataserver/e-memory.h>
#include "camel-file-utils.h"
#include "camel-folder-summary.h"
#include "camel-folder.h"
+#include "camel-iconv.h"
#include "camel-mime-filter-basic.h"
#include "camel-mime-filter-charset.h"
#include "camel-mime-filter-html.h"
@@ -1758,7 +1758,7 @@
&& (g_ascii_strcasecmp(charset, "us-ascii") == 0))
charset = NULL;
- charset = charset ? e_iconv_charset_name (charset) : NULL;
+ charset = charset ? camel_iconv_charset_name (charset) : NULL;
subject = summary_format_string(h, "subject", charset);
from = summary_format_address(h, "from", charset);
@@ -2023,7 +2023,7 @@
ci = camel_folder_summary_content_info_new (s);
- charset = e_iconv_locale_charset ();
+ charset = camel_iconv_locale_charset ();
ci->id = camel_header_msgid_decode (camel_header_raw_find (&h, "content-id", NULL));
ci->description = camel_header_decode_string (camel_header_raw_find (&h, "content-description", NULL), charset);
ci->encoding = camel_content_transfer_encoding_decode (camel_header_raw_find (&h, "content-transfer-encoding", NULL));
Modified: trunk/camel/camel-gpg-context.c
==============================================================================
--- trunk/camel/camel-gpg-context.c (original)
+++ trunk/camel/camel-gpg-context.c Wed May 7 02:15:39 2008
@@ -53,10 +53,9 @@
#include <termios.h>
#endif
-#include <libedataserver/e-iconv.h>
-
#include "camel-debug.h"
#include "camel-gpg-context.h"
+#include "camel-iconv.h"
#include "camel-mime-filter-canon.h"
#include "camel-mime-filter-charset.h"
#include "camel-mime-part.h"
@@ -298,7 +297,7 @@
gpg->diagbuf = CAMEL_STREAM_MEM (stream)->buffer;
gpg->diagflushed = FALSE;
- if ((charset = e_iconv_locale_charset ()) && g_ascii_strcasecmp (charset, "UTF-8") != 0) {
+ if ((charset = camel_iconv_locale_charset ()) && g_ascii_strcasecmp (charset, "UTF-8") != 0) {
CamelMimeFilterCharset *filter;
CamelStreamFilter *fstream;
Added: trunk/camel/camel-iconv.c
==============================================================================
--- (empty file)
+++ trunk/camel/camel-iconv.c Wed May 7 02:15:39 2008
@@ -0,0 +1,630 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * camel-iconv.c
+ * Copyright 2000, 2001, Ximian, Inc.
+ *
+ * Authors:
+ * Michael Zucchi <notzed ximian com>
+ * Jeffery Stedfast <fejj ximian com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib.h>
+
+#include <locale.h>
+
+#ifdef HAVE_CODESET
+#include <langinfo.h>
+#endif
+
+#include "camel-iconv.h"
+#include "iconv-detect.h"
+
+#define cd(x)
+
+#ifdef G_THREADS_ENABLED
+static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+#define LOCK() g_static_mutex_lock(&lock)
+#define UNLOCK() g_static_mutex_unlock(&lock)
+#else
+#define LOCK()
+#define UNLOCK()
+#endif
+
+typedef struct _EDListNode {
+ struct _EDListNode *next;
+ struct _EDListNode *prev;
+} EDListNode;
+
+typedef struct _EDList {
+ struct _EDListNode *head;
+ struct _EDListNode *tail;
+ struct _EDListNode *tailpred;
+} EDList;
+
+#define E_DLIST_INITIALISER(l) { (EDListNode *)&l.tail, 0, (EDListNode *)&l.head }
+
+struct _iconv_cache_node {
+ struct _iconv_cache_node *next;
+ struct _iconv_cache_node *prev;
+
+ struct _iconv_cache *parent;
+
+ int busy;
+ iconv_t ip;
+};
+
+struct _iconv_cache {
+ struct _iconv_cache *next;
+ struct _iconv_cache *prev;
+
+ char *conv;
+
+ EDList open; /* stores iconv_cache_nodes, busy ones up front */
+};
+
+#define E_ICONV_CACHE_SIZE (16)
+
+static EDList iconv_cache_list;
+static GHashTable *iconv_cache;
+static GHashTable *iconv_cache_open;
+static unsigned int iconv_cache_size = 0;
+
+static GHashTable *iconv_charsets = NULL;
+static char *locale_charset = NULL;
+static char *locale_lang = NULL;
+
+struct {
+ char *charset;
+ char *iconv_name;
+} known_iconv_charsets[] = {
+#if 0
+ /* charset name, iconv-friendly charset name */
+ { "iso-8859-1", "iso-8859-1" },
+ { "iso8859-1", "iso-8859-1" },
+ /* the above mostly serves as an example for iso-style charsets,
+ but we have code that will populate the iso-*'s if/when they
+ show up in camel_iconv_charset_name() so I'm
+ not going to bother putting them all in here... */
+ { "windows-cp1251", "cp1251" },
+ { "windows-1251", "cp1251" },
+ { "cp1251", "cp1251" },
+ /* the above mostly serves as an example for windows-style
+ charsets, but we have code that will parse and convert them
+ to their cp#### equivalents if/when they show up in
+ camel_iconv_charset_name() so I'm not going to bother
+ putting them all in here either... */
+#endif
+ /* charset name (lowercase!), iconv-friendly name (sometimes case sensitive) */
+ { "utf-8", "UTF-8" },
+
+ /* 10646 is a special case, its usually UCS-2 big endian */
+ /* This might need some checking but should be ok for solaris/linux */
+ { "iso-10646-1", "UCS-2BE" },
+ { "iso_10646-1", "UCS-2BE" },
+ { "iso10646-1", "UCS-2BE" },
+ { "iso-10646", "UCS-2BE" },
+ { "iso_10646", "UCS-2BE" },
+ { "iso10646", "UCS-2BE" },
+
+ { "ks_c_5601-1987", "EUC-KR" },
+
+ /* FIXME: Japanese/Korean/Chinese stuff needs checking */
+ { "euckr-0", "EUC-KR" },
+ { "5601", "EUC-KR" },
+ { "zh_TW-euc", "EUC-TW" },
+ { "zh_CN.euc", "gb2312" },
+ { "zh_TW-big5", "BIG5" },
+ { "euc-cn", "gb2312" },
+ { "big5-0", "BIG5" },
+ { "big5.eten-0", "BIG5" },
+ { "big5hkscs-0", "BIG5HKSCS" },
+ { "gb2312-0", "gb2312" },
+ { "gb2312.1980-0", "gb2312" },
+ { "gb-2312", "gb2312" },
+ { "gb18030-0", "gb18030" },
+ { "gbk-0", "GBK" },
+
+ { "eucjp-0", "eucJP" },
+ { "ujis-0", "ujis" },
+ { "jisx0208.1983-0","SJIS" },
+ { "jisx0212.1990-0","SJIS" },
+ { "pck", "SJIS" },
+ { NULL, NULL }
+};
+
+
+
+/* Another copy of this trivial list implementation
+ Why? This stuff gets called a lot (potentially), should run fast,
+ and g_list's are f@@#$ed up to make this a hassle */
+static void e_dlist_init(EDList *v)
+{
+ v->head = (EDListNode *)&v->tail;
+ v->tail = NULL;
+ v->tailpred = (EDListNode *)&v->head;
+}
+
+static EDListNode *e_dlist_addhead(EDList *l, EDListNode *n)
+{
+ n->next = l->head;
+ n->prev = (EDListNode *)&l->head;
+ l->head->prev = n;
+ l->head = n;
+ return n;
+}
+
+static EDListNode *e_dlist_addtail(EDList *l, EDListNode *n)
+{
+ n->next = (EDListNode *)&l->tail;
+ n->prev = l->tailpred;
+ l->tailpred->next = n;
+ l->tailpred = n;
+ return n;
+}
+
+static EDListNode *e_dlist_remove(EDListNode *n)
+{
+ n->next->prev = n->prev;
+ n->prev->next = n->next;
+ return n;
+}
+
+
+/* fucking glib... */
+static const char *
+e_strdown (char *str)
+{
+ register char *s = str;
+
+ while (*s) {
+ if (*s >= 'A' && *s <= 'Z')
+ *s += 0x20;
+ s++;
+ }
+
+ return str;
+}
+
+static const char *
+e_strup (char *str)
+{
+ register char *s = str;
+
+ while (*s) {
+ if (*s >= 'a' && *s <= 'z')
+ *s -= 0x20;
+ s++;
+ }
+
+ return str;
+}
+
+
+static void
+locale_parse_lang (const char *locale)
+{
+ char *codeset, *lang;
+
+ if ((codeset = strchr (locale, '.')))
+ lang = g_strndup (locale, codeset - locale);
+ else
+ lang = g_strdup (locale);
+
+ /* validate the language */
+ if (strlen (lang) >= 2) {
+ if (lang[2] == '-' || lang[2] == '_') {
+ /* canonicalise the lang */
+ e_strdown (lang);
+
+ /* validate the country code */
+ if (strlen (lang + 3) > 2) {
+ /* invalid country code */
+ lang[2] = '\0';
+ } else {
+ lang[2] = '-';
+ e_strup (lang + 3);
+ }
+ } else if (lang[2] != '\0') {
+ /* invalid language */
+ g_free (lang);
+ lang = NULL;
+ }
+
+ locale_lang = lang;
+ } else {
+ /* invalid language */
+ locale_lang = NULL;
+ g_free (lang);
+ }
+}
+
+/* NOTE: Owns the lock on return if keep is TRUE ! */
+static void
+camel_iconv_init(int keep)
+{
+ char *from, *to, *locale;
+ int i;
+
+ LOCK();
+
+ if (iconv_charsets != NULL) {
+ if (!keep)
+ UNLOCK();
+ return;
+ }
+
+ iconv_charsets = g_hash_table_new(g_str_hash, g_str_equal);
+
+ for (i = 0; known_iconv_charsets[i].charset != NULL; i++) {
+ from = g_strdup(known_iconv_charsets[i].charset);
+ to = g_strdup(known_iconv_charsets[i].iconv_name);
+ e_strdown (from);
+ g_hash_table_insert(iconv_charsets, from, to);
+ }
+
+ e_dlist_init(&iconv_cache_list);
+ iconv_cache = g_hash_table_new(g_str_hash, g_str_equal);
+ iconv_cache_open = g_hash_table_new(NULL, NULL);
+
+#ifndef G_OS_WIN32
+ locale = setlocale (LC_ALL, NULL);
+#else
+ locale = g_win32_getlocale ();
+#endif
+
+ if (!locale || !strcmp (locale, "C") || !strcmp (locale, "POSIX")) {
+ /* The locale "C" or "POSIX" is a portable locale; its
+ * LC_CTYPE part corresponds to the 7-bit ASCII character
+ * set.
+ */
+
+ locale_charset = NULL;
+ locale_lang = NULL;
+ } else {
+#ifdef G_OS_WIN32
+ g_get_charset (&locale_charset);
+ locale_charset = g_strdup (locale_charset);
+ e_strdown (locale_charset);
+#else
+#ifdef HAVE_CODESET
+ locale_charset = g_strdup (nl_langinfo (CODESET));
+ e_strdown (locale_charset);
+#else
+ /* A locale name is typically of the form language[_terri-
+ * tory][ codeset][ modifier], where language is an ISO 639
+ * language code, territory is an ISO 3166 country code, and
+ * codeset is a character set or encoding identifier like
+ * ISO-8859-1 or UTF-8.
+ */
+ char *codeset, *p;
+
+ codeset = strchr (locale, '.');
+ if (codeset) {
+ codeset++;
+
+ /* ; is a hack for debian systems and / is a hack for Solaris systems */
+ for (p = codeset; *p && !strchr ("@;/", *p); p++);
+ locale_charset = g_strndup (codeset, p - codeset);
+ e_strdown (locale_charset);
+ } else {
+ /* charset unknown */
+ locale_charset = NULL;
+ }
+#endif
+#endif /* !G_OS_WIN32 */
+
+ /* parse the locale lang */
+ locale_parse_lang (locale);
+
+ }
+
+#ifdef G_OS_WIN32
+ g_free (locale);
+#endif
+ if (!keep)
+ UNLOCK();
+}
+
+const gchar *
+camel_iconv_charset_name (const gchar *charset)
+{
+ char *name, *ret, *tmp;
+
+ if (charset == NULL)
+ return NULL;
+
+ name = g_alloca (strlen (charset) + 1);
+ strcpy (name, charset);
+ e_strdown (name);
+
+ camel_iconv_init(TRUE);
+ ret = g_hash_table_lookup(iconv_charsets, name);
+ if (ret != NULL) {
+ UNLOCK();
+ return ret;
+ }
+
+ /* Unknown, try canonicalise some basic charset types to something that should work */
+ if (strncmp(name, "iso", 3) == 0) {
+ /* Convert iso-nnnn-n or isonnnn-n or iso_nnnn-n to iso-nnnn-n or isonnnn-n */
+ int iso, codepage;
+ char *p;
+
+ tmp = name + 3;
+ if (*tmp == '-' || *tmp == '_')
+ tmp++;
+
+ iso = strtoul (tmp, &p, 10);
+
+ if (iso == 10646) {
+ /* they all become ICONV_10646 */
+ ret = g_strdup (ICONV_10646);
+ } else {
+ tmp = p;
+ if (*tmp == '-' || *tmp == '_')
+ tmp++;
+
+ codepage = strtoul (tmp, &p, 10);
+
+ if (p > tmp) {
+ /* codepage is numeric */
+#ifdef __aix__
+ if (codepage == 13)
+ ret = g_strdup ("IBM-921");
+ else
+#endif /* __aix__ */
+ ret = g_strdup_printf (ICONV_ISO_D_FORMAT, iso, codepage);
+ } else {
+ /* codepage is a string - probably iso-2022-jp or something */
+ ret = g_strdup_printf (ICONV_ISO_S_FORMAT, iso, p);
+ }
+ }
+ } else if (strncmp(name, "windows-", 8) == 0) {
+ /* Convert windows-nnnnn or windows-cpnnnnn to cpnnnn */
+ tmp = name+8;
+ if (!strncmp(tmp, "cp", 2))
+ tmp+=2;
+ ret = g_strdup_printf("CP%s", tmp);
+ } else if (strncmp(name, "microsoft-", 10) == 0) {
+ /* Convert microsoft-nnnnn or microsoft-cpnnnnn to cpnnnn */
+ tmp = name+10;
+ if (!strncmp(tmp, "cp", 2))
+ tmp+=2;
+ ret = g_strdup_printf("CP%s", tmp);
+ } else {
+ /* Just assume its ok enough as is, case and all */
+ ret = g_strdup(charset);
+ }
+
+ g_hash_table_insert(iconv_charsets, g_strdup(name), ret);
+ UNLOCK();
+
+ return ret;
+}
+
+static void
+flush_entry(struct _iconv_cache *ic)
+{
+ struct _iconv_cache_node *in, *nn;
+
+ in = (struct _iconv_cache_node *)ic->open.head;
+ nn = in->next;
+ while (nn) {
+ if (in->ip != (iconv_t)-1) {
+ g_hash_table_remove(iconv_cache_open, in->ip);
+ iconv_close(in->ip);
+ }
+ g_free(in);
+ in = nn;
+ nn = in->next;
+ }
+ g_free(ic->conv);
+ g_free(ic);
+}
+
+/* This should run pretty quick, its called a lot */
+iconv_t
+camel_iconv_open (const gchar *oto, const gchar *ofrom)
+{
+ const char *to, *from;
+ char *tofrom;
+ struct _iconv_cache *ic;
+ struct _iconv_cache_node *in;
+ int errnosav;
+ iconv_t ip;
+
+ if (oto == NULL || ofrom == NULL) {
+ errno = EINVAL;
+ return (iconv_t) -1;
+ }
+
+ to = camel_iconv_charset_name (oto);
+ from = camel_iconv_charset_name (ofrom);
+ tofrom = g_alloca (strlen (to) + strlen (from) + 2);
+ sprintf(tofrom, "%s%%%s", to, from);
+
+ LOCK();
+
+ ic = g_hash_table_lookup(iconv_cache, tofrom);
+ if (ic) {
+ e_dlist_remove((EDListNode *)ic);
+ } else {
+ struct _iconv_cache *last = (struct _iconv_cache *)iconv_cache_list.tailpred;
+ struct _iconv_cache *prev;
+
+ prev = last->prev;
+ while (prev && iconv_cache_size > E_ICONV_CACHE_SIZE) {
+ in = (struct _iconv_cache_node *)last->open.head;
+ if (in->next && !in->busy) {
+ cd(printf("Flushing iconv converter '%s'\n", last->conv));
+ e_dlist_remove((EDListNode *)last);
+ g_hash_table_remove(iconv_cache, last->conv);
+ flush_entry(last);
+ iconv_cache_size--;
+ }
+ last = prev;
+ prev = last->prev;
+ }
+
+ iconv_cache_size++;
+
+ ic = g_malloc(sizeof(*ic));
+ e_dlist_init(&ic->open);
+ ic->conv = g_strdup(tofrom);
+ g_hash_table_insert(iconv_cache, ic->conv, ic);
+
+ cd(printf("Creating iconv converter '%s'\n", ic->conv));
+ }
+ e_dlist_addhead(&iconv_cache_list, (EDListNode *)ic);
+
+ /* If we have a free iconv, use it */
+ in = (struct _iconv_cache_node *)ic->open.tailpred;
+ if (in->prev && !in->busy) {
+ cd(printf("using existing iconv converter '%s'\n", ic->conv));
+ ip = in->ip;
+ if (ip != (iconv_t)-1) {
+ /* work around some broken iconv implementations
+ * that die if the length arguments are NULL
+ */
+ size_t buggy_iconv_len = 0;
+ char *buggy_iconv_buf = NULL;
+
+ /* resets the converter */
+ iconv(ip, &buggy_iconv_buf, &buggy_iconv_len, &buggy_iconv_buf, &buggy_iconv_len);
+ in->busy = TRUE;
+ e_dlist_remove((EDListNode *)in);
+ e_dlist_addhead(&ic->open, (EDListNode *)in);
+ }
+ } else {
+ cd(printf("creating new iconv converter '%s'\n", ic->conv));
+ ip = iconv_open(to, from);
+ in = g_malloc(sizeof(*in));
+ in->ip = ip;
+ in->parent = ic;
+ e_dlist_addhead(&ic->open, (EDListNode *)in);
+ if (ip != (iconv_t)-1) {
+ g_hash_table_insert(iconv_cache_open, ip, in);
+ in->busy = TRUE;
+ } else {
+ errnosav = errno;
+ g_warning("Could not open converter for '%s' to '%s' charset", from, to);
+ in->busy = FALSE;
+ errno = errnosav;
+ }
+ }
+
+ UNLOCK();
+
+ return ip;
+}
+
+gsize
+camel_iconv (iconv_t cd, const gchar **inbuf, gsize *inbytesleft,
+ gchar ** outbuf, gsize *outbytesleft)
+{
+ return iconv(cd, (char **) inbuf, inbytesleft, outbuf, outbytesleft);
+}
+
+void
+camel_iconv_close (iconv_t ip)
+{
+ struct _iconv_cache_node *in;
+
+ if (ip == (iconv_t)-1)
+ return;
+
+ LOCK();
+ in = g_hash_table_lookup(iconv_cache_open, ip);
+ if (in) {
+ cd(printf("closing iconv converter '%s'\n", in->parent->conv));
+ e_dlist_remove((EDListNode *)in);
+ in->busy = FALSE;
+ e_dlist_addtail(&in->parent->open, (EDListNode *)in);
+ } else {
+ g_warning("trying to close iconv i dont know about: %p", ip);
+ iconv_close(ip);
+ }
+ UNLOCK();
+
+}
+
+const gchar *
+camel_iconv_locale_charset (void)
+{
+ camel_iconv_init(FALSE);
+
+ return locale_charset;
+}
+
+
+const gchar *
+camel_iconv_locale_language (void)
+{
+ camel_iconv_init (FALSE);
+
+ return locale_lang;
+}
+
+/* map CJKR charsets to their language code */
+/* NOTE: only support charset names that will be returned by
+ * camel_iconv_charset_name() so that we don't have to keep track of all
+ * the aliases too. */
+static struct {
+ char *charset;
+ char *lang;
+} cjkr_lang_map[] = {
+ { "Big5", "zh" },
+ { "BIG5HKSCS", "zh" },
+ { "gb2312", "zh" },
+ { "gb18030", "zh" },
+ { "gbk", "zh" },
+ { "euc-tw", "zh" },
+ { "iso-2022-jp", "ja" },
+ { "sjis", "ja" },
+ { "ujis", "ja" },
+ { "eucJP", "ja" },
+ { "euc-jp", "ja" },
+ { "euc-kr", "ko" },
+ { "koi8-r", "ru" },
+ { "koi8-u", "uk" }
+};
+
+const gchar *
+camel_iconv_charset_language (const gchar *charset)
+{
+ int i;
+
+ if (!charset)
+ return NULL;
+
+ charset = camel_iconv_charset_name (charset);
+ for (i = 0; i < G_N_ELEMENTS (cjkr_lang_map); i++) {
+ if (!g_ascii_strcasecmp (cjkr_lang_map[i].charset, charset))
+ return cjkr_lang_map[i].lang;
+ }
+
+ return NULL;
+}
Modified: trunk/camel/camel-iconv.h
==============================================================================
--- trunk/camel/camel-iconv.h (original)
+++ trunk/camel/camel-iconv.h Wed May 7 02:15:39 2008
@@ -26,19 +26,24 @@
#include <sys/types.h>
#include <iconv.h>
+#include <glib.h>
G_BEGIN_DECLS
-const char *camel_iconv_locale_charset (void);
-const char *camel_iconv_locale_language (void);
+const gchar * camel_iconv_locale_charset (void);
+const gchar * camel_iconv_locale_language (void);
-const char *camel_iconv_charset_name (const char *charset);
+const gchar * camel_iconv_charset_name (const gchar *charset);
+const gchar * camel_iconv_charset_language (const gchar *charset);
-const char *camel_iconv_charset_language (const char *charset);
-
-iconv_t camel_iconv_open (const char *to, const char *from);
-size_t camel_iconv (iconv_t cd, const char **inbuf, size_t *inleft, char **outbuf, size_t *outleft);
-void camel_iconv_close (iconv_t cd);
+iconv_t camel_iconv_open (const gchar *to,
+ const gchar *from);
+gsize camel_iconv (iconv_t cd,
+ const gchar **inbuf,
+ gsize *inleft,
+ gchar **outbuf,
+ gsize *outleft);
+void camel_iconv_close (iconv_t cd);
G_END_DECLS
Modified: trunk/camel/camel-mime-filter-charset.c
==============================================================================
--- trunk/camel/camel-mime-filter-charset.c (original)
+++ trunk/camel/camel-mime-filter-charset.c Wed May 7 02:15:39 2008
@@ -27,9 +27,8 @@
#include <errno.h>
#include <string.h>
-#include <libedataserver/e-iconv.h>
-
#include "camel-charset-map.h"
+#include "camel-iconv.h"
#include "camel-mime-filter-charset.h"
#define d(x)
@@ -67,7 +66,7 @@
g_free(f->from);
g_free(f->to);
if (f->ic != (iconv_t) -1) {
- e_iconv_close (f->ic);
+ camel_iconv_close (f->ic);
f->ic = (iconv_t) -1;
}
}
@@ -83,7 +82,7 @@
/* what happens with the output bytes if this resets the state? */
if (f->ic != (iconv_t) -1) {
buffer = buf;
- e_iconv (f->ic, NULL, NULL, &buffer, &outlen);
+ camel_iconv (f->ic, NULL, NULL, &buffer, &outlen);
}
}
@@ -107,7 +106,7 @@
if (inleft > 0) {
do {
- converted = e_iconv (charset->ic, &inbuf, &inleft, &outbuf, &outleft);
+ converted = camel_iconv (charset->ic, &inbuf, &inleft, &outbuf, &outleft);
if (converted == (size_t) -1) {
if (errno == E2BIG) {
/*
@@ -147,7 +146,7 @@
}
/* flush the iconv conversion */
- e_iconv (charset->ic, NULL, NULL, &outbuf, &outleft);
+ camel_iconv (charset->ic, NULL, NULL, &outbuf, &outleft);
*out = mf->outbuf;
*outlen = mf->outsize - outleft;
@@ -181,7 +180,7 @@
inleft = len;
do {
- converted = e_iconv (charset->ic, &inbuf, &inleft, &outbuf, &outleft);
+ converted = camel_iconv (charset->ic, &inbuf, &inleft, &outbuf, &outleft);
if (converted == (size_t) -1) {
if (errno == E2BIG || errno == EINVAL)
break;
@@ -273,7 +272,7 @@
new = CAMEL_MIME_FILTER_CHARSET (camel_object_new (camel_mime_filter_charset_get_type ()));
- new->ic = e_iconv_open (to_charset, from_charset);
+ new->ic = camel_iconv_open (to_charset, from_charset);
if (new->ic == (iconv_t) -1) {
w(g_warning ("Cannot create charset conversion from %s to %s: %s",
from_charset ? from_charset : "(null)",
Modified: trunk/camel/camel-mime-message.c
==============================================================================
--- trunk/camel/camel-mime-message.c (original)
+++ trunk/camel/camel-mime-message.c Wed May 7 02:15:39 2008
@@ -32,9 +32,9 @@
#include <stdio.h>
#include <string.h>
-#include <libedataserver/e-iconv.h>
#include <libedataserver/e-time-utils.h>
+#include "camel-iconv.h"
#include "camel-mime-filter-bestenc.h"
#include "camel-mime-filter-charset.h"
#include "camel-mime-message.h"
@@ -692,7 +692,7 @@
g_free (message->subject);
if (((CamelDataWrapper *) message)->mime_type) {
charset = camel_content_type_param (((CamelDataWrapper *) message)->mime_type, "charset");
- charset = e_iconv_charset_name (charset);
+ charset = camel_iconv_charset_name (charset);
} else
charset = NULL;
Modified: trunk/camel/camel-mime-part-utils.c
==============================================================================
--- trunk/camel/camel-mime-part-utils.c (original)
+++ trunk/camel/camel-mime-part-utils.c Wed May 7 02:15:39 2008
@@ -32,8 +32,6 @@
#include <string.h>
#include <unistd.h>
-#include <libedataserver/e-iconv.h>
-
#include "camel-charset-map.h"
#include "camel-html-parser.h"
#include "camel-mime-filter-basic.h"
Modified: trunk/camel/camel-mime-part.c
==============================================================================
--- trunk/camel/camel-mime-part.c (original)
+++ trunk/camel/camel-mime-part.c Wed May 7 02:15:39 2008
@@ -33,10 +33,9 @@
#include <stdio.h>
#include <string.h>
-#include <libedataserver/e-iconv.h>
-
#include "camel-charset-map.h"
#include "camel-exception.h"
+#include "camel-iconv.h"
#include "camel-mime-filter-basic.h"
#include "camel-mime-filter-charset.h"
#include "camel-mime-filter-crlf.h"
@@ -228,7 +227,7 @@
g_free (mime_part->description);
if (((CamelDataWrapper *) mime_part)->mime_type) {
charset = camel_content_type_param (((CamelDataWrapper *) mime_part)->mime_type, "charset");
- charset = e_iconv_charset_name (charset);
+ charset = camel_iconv_charset_name (charset);
} else
charset = NULL;
mime_part->description = g_strstrip (camel_header_decode_string (value, charset));
@@ -832,8 +831,8 @@
part_charset = camel_content_type_param (dw->mime_type, "charset");
if (content_charset && part_charset) {
- content_charset = e_iconv_charset_name (content_charset);
- part_charset = e_iconv_charset_name (part_charset);
+ content_charset = camel_iconv_charset_name (content_charset);
+ part_charset = camel_iconv_charset_name (part_charset);
}
}
Modified: trunk/camel/camel-mime-utils.c
==============================================================================
--- trunk/camel/camel-mime-utils.c (original)
+++ trunk/camel/camel-mime-utils.c Wed May 7 02:15:39 2008
@@ -46,10 +46,10 @@
#include <glib.h>
-#include <libedataserver/e-iconv.h>
#include <libedataserver/e-time-utils.h>
#include "camel-charset-map.h"
+#include "camel-iconv.h"
#include "camel-mime-utils.h"
#include "camel-net-utils.h"
#include "camel-utf8.h"
@@ -915,7 +915,7 @@
if (default_charset && g_ascii_strcasecmp (default_charset, "UTF-8") != 0)
charsets[i++] = default_charset;
- locale_charset = e_iconv_locale_charset ();
+ locale_charset = camel_iconv_locale_charset ();
if (locale_charset && g_ascii_strcasecmp (locale_charset, "UTF-8") != 0)
charsets[i++] = locale_charset;
@@ -926,7 +926,7 @@
out = g_malloc (outlen + 1);
for (i = 0; charsets[i]; i++) {
- if ((cd = e_iconv_open ("UTF-8", charsets[i])) == (iconv_t) -1)
+ if ((cd = camel_iconv_open ("UTF-8", charsets[i])) == (iconv_t) -1)
continue;
outleft = outlen;
@@ -961,7 +961,7 @@
rc = iconv (cd, NULL, NULL, &outbuf, &outleft);
*outbuf = '\0';
- e_iconv_close (cd);
+ camel_iconv_close (cd);
if (rc != (size_t) -1 && n == 0)
return out;
@@ -976,7 +976,7 @@
* try to find the one that fit the best and use that to convert what we can,
* replacing any byte we can't convert with a '?' */
- if ((cd = e_iconv_open ("UTF-8", best)) == (iconv_t) -1) {
+ if ((cd = camel_iconv_open ("UTF-8", best)) == (iconv_t) -1) {
/* this shouldn't happen... but if we are here, then
* it did... the only thing we can do at this point
* is replace the 8bit garbage and pray */
@@ -1028,7 +1028,7 @@
iconv (cd, NULL, NULL, &outbuf, &outleft);
*outbuf = '\0';
- e_iconv_close (cd);
+ camel_iconv_close (cd);
return out;
}
@@ -1116,9 +1116,9 @@
}
if (charset[0])
- charset = e_iconv_charset_name (charset);
+ charset = camel_iconv_charset_name (charset);
- if (!charset[0] || (cd = e_iconv_open ("UTF-8", charset)) == (iconv_t) -1) {
+ if (!charset[0] || (cd = camel_iconv_open ("UTF-8", charset)) == (iconv_t) -1) {
w(g_warning ("Cannot convert from %s to UTF-8, header display may "
"be corrupt: %s", charset[0] ? charset : "unspecified charset",
g_strerror (errno)));
@@ -1127,7 +1127,7 @@
}
buf = camel_iconv_strndup (cd, (char *) decoded, declen);
- e_iconv_close (cd);
+ camel_iconv_close (cd);
if (buf != NULL)
return buf;
@@ -1167,26 +1167,26 @@
size_t outlen;
iconv_t ic;
- ic = e_iconv_open ("UTF-8", charset);
+ ic = camel_iconv_open ("UTF-8", charset);
if (ic == (iconv_t) -1)
return FALSE;
outlen = inlen * 6 + 16;
outbuf = outbase = g_malloc(outlen);
- if (e_iconv (ic, &inbuf, &inlen, &outbuf, &outlen) == (size_t) -1) {
+ if (camel_iconv (ic, &inbuf, &inlen, &outbuf, &outlen) == (size_t) -1) {
w(g_warning("Conversion to '%s' failed: %s", charset, strerror (errno)));
g_free(outbase);
- e_iconv_close (ic);
+ camel_iconv_close (ic);
return FALSE;
}
- e_iconv (ic, NULL, NULL, &outbuf, &outlen);
+ camel_iconv (ic, NULL, NULL, &outbuf, &outlen);
*outbuf = 0;
g_string_append(out, outbase);
g_free(outbase);
- e_iconv_close (ic);
+ camel_iconv_close (ic);
return TRUE;
@@ -1391,7 +1391,7 @@
ascii = g_alloca (bufflen);
if (g_ascii_strcasecmp (type, "UTF-8") != 0)
- ic = e_iconv_open (type, "UTF-8");
+ ic = camel_iconv_open (type, "UTF-8");
while (inlen) {
ssize_t convlen, proclen;
@@ -1444,13 +1444,13 @@
hopefully-small-enough chunks, and leave it at that */
convlen = MIN(inlen, CAMEL_FOLD_PREENCODED);
p = inptr;
- if (e_iconv (ic, &inptr, &convlen, &out, &outlen) == (size_t) -1 && errno != EINVAL) {
+ if (camel_iconv (ic, &inptr, &convlen, &out, &outlen) == (size_t) -1 && errno != EINVAL) {
w(g_warning("Conversion problem: conversion truncated: %s", strerror (errno)));
/* blah, we include it anyway, better than infinite loop ... */
inptr += convlen;
} else {
/* make sure we flush out any shift state */
- e_iconv (ic, NULL, 0, &out, &outlen);
+ camel_iconv (ic, NULL, 0, &out, &outlen);
}
inlen -= (inptr - p);
}
@@ -1475,7 +1475,7 @@
}
if (ic != (iconv_t) -1)
- e_iconv_close (ic);
+ camel_iconv_close (ic);
}
@@ -2074,20 +2074,20 @@
size_t outlen, ret;
char *outbuf, *outbase, *result = NULL;
- ic = e_iconv_open(to, from);
+ ic = camel_iconv_open(to, from);
if (ic == (iconv_t) -1)
return NULL;
outlen = inlen * 6 + 16;
outbuf = outbase = g_malloc(outlen);
- ret = e_iconv(ic, &in, &inlen, &outbuf, &outlen);
+ ret = camel_iconv(ic, &in, &inlen, &outbuf, &outlen);
if (ret != (size_t) -1) {
- e_iconv(ic, NULL, 0, &outbuf, &outlen);
+ camel_iconv(ic, NULL, 0, &outbuf, &outlen);
*outbuf = '\0';
result = g_strdup(outbase);
}
- e_iconv_close(ic);
+ camel_iconv_close(ic);
g_free(outbase);
return result;
@@ -2112,7 +2112,7 @@
encoding = g_alloca(inptr-in+1);
memcpy(encoding, in, inptr-in);
encoding[inptr-in] = 0;
- charset = e_iconv_charset_name (encoding);
+ charset = camel_iconv_charset_name (encoding);
inptr = memchr (inptr + 1, '\'', inend - inptr - 1);
if (!inptr)
@@ -2658,7 +2658,7 @@
const char *locale_charset;
GString *out;
- locale_charset = e_iconv_locale_charset ();
+ locale_charset = camel_iconv_locale_charset ();
out = g_string_new ("");
@@ -3163,7 +3163,7 @@
&& (node->value = header_decode_text(value, FALSE, NULL))) {
g_free(value);
} else if (g_ascii_strcasecmp (name, "boundary") != 0 && !g_utf8_validate(value, -1, NULL)) {
- const char *charset = e_iconv_locale_charset();
+ const char *charset = camel_iconv_locale_charset();
if ((node->value = header_convert("UTF-8", charset?charset:"ISO-8859-1", value, strlen(value)))) {
g_free(value);
Added: trunk/camel/camel-msgport.c
==============================================================================
--- (empty file)
+++ trunk/camel/camel-msgport.c Wed May 7 02:15:39 2008
@@ -0,0 +1,424 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright 2007 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef HAVE_NSS
+#include <nspr.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <winsock2.h>
+#endif
+
+#include "camel-msgport.h"
+
+#ifdef G_OS_WIN32
+#define MP_CLOSE(socket) closesocket (socket)
+#define MP_READ(socket, buf, nbytes) recv((socket), (buf), (nbytes), 0)
+#define MP_WRITE(socket, buf, nbytes) send((socket), (buf), (nbytes), 0)
+#define MP_IS_STATUS_INTR() 0 /* No WSAEINTR errors in WinSock2 */
+#else
+#define MP_CLOSE(socket) close (socket)
+#define MP_READ(socket, buf, nbytes) read((socket), (buf), (nbytes))
+#define MP_WRITE(socket, buf, nbytes) write((socket), (buf), (nbytes))
+#define MP_IS_STATUS_INTR() (errno == EINTR)
+#endif
+
+/* message flags */
+enum {
+ MSG_FLAG_SYNC_WITH_PIPE = 1 << 0,
+ MSG_FLAG_SYNC_WITH_PR_PIPE = 1 << 1
+};
+
+struct _CamelMsgPort {
+ GAsyncQueue *queue;
+ gint pipe[2]; /* on Win32, actually a pair of SOCKETs */
+#ifdef HAVE_NSS
+ PRFileDesc *prpipe[2];
+#endif
+};
+
+static int
+msgport_pipe (int *fds)
+{
+#ifndef G_OS_WIN32
+ if (pipe (fds) != -1)
+ return 0;
+
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return -1;
+#else
+ SOCKET temp, socket1 = -1, socket2 = -1;
+ struct sockaddr_in saddr;
+ int len;
+ u_long arg;
+ fd_set read_set, write_set;
+ struct timeval tv;
+
+ temp = socket (AF_INET, SOCK_STREAM, 0);
+
+ if (temp == INVALID_SOCKET) {
+ goto out0;
+ }
+
+ arg = 1;
+ if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out0;
+ }
+
+ memset (&saddr, 0, sizeof (saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0;
+ saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+
+ if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr))) {
+ goto out0;
+ }
+
+ if (listen (temp, 1) == SOCKET_ERROR) {
+ goto out0;
+ }
+
+ len = sizeof (saddr);
+ if (getsockname (temp, (struct sockaddr *)&saddr, &len)) {
+ goto out0;
+ }
+
+ socket1 = socket (AF_INET, SOCK_STREAM, 0);
+
+ if (socket1 == INVALID_SOCKET) {
+ goto out0;
+ }
+
+ arg = 1;
+ if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out1;
+ }
+
+ if (connect (socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
+ WSAGetLastError () != WSAEWOULDBLOCK) {
+ goto out1;
+ }
+
+ FD_ZERO (&read_set);
+ FD_SET (temp, &read_set);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) {
+ goto out1;
+ }
+
+ if (!FD_ISSET (temp, &read_set)) {
+ goto out1;
+ }
+
+ socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
+ if (socket2 == INVALID_SOCKET) {
+ goto out1;
+ }
+
+ FD_ZERO (&write_set);
+ FD_SET (socket1, &write_set);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ if (!FD_ISSET (socket1, &write_set)) {
+ goto out2;
+ }
+
+ arg = 0;
+ if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ arg = 0;
+ if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ fds[0] = socket1;
+ fds[1] = socket2;
+
+ closesocket (temp);
+
+ return 0;
+
+out2:
+ closesocket (socket2);
+out1:
+ closesocket (socket1);
+out0:
+ closesocket (temp);
+ errno = EMFILE; /* FIXME: use the real syscall errno? */
+
+ fds[0] = -1;
+ fds[1] = -1;
+
+ return -1;
+
+#endif
+}
+
+#ifdef HAVE_NSS
+static int
+msgport_prpipe (PRFileDesc **fds)
+{
+#ifdef G_OS_WIN32
+ if (PR_NewTCPSocketPair (fds) != PR_FAILURE)
+ return 0;
+#else
+ if (PR_CreatePipe (&fds[0], &fds[1]) != PR_FAILURE)
+ return 0;
+#endif
+
+ fds[0] = NULL;
+ fds[1] = NULL;
+
+ return -1;
+}
+#endif
+
+static void
+msgport_sync_with_pipe (gint fd)
+{
+ gchar buffer[1];
+
+ while (fd >= 0) {
+ if (MP_READ (fd, buffer, 1) > 0)
+ break;
+ else if (!MP_IS_STATUS_INTR ()) {
+ g_warning ("%s: Failed to read from pipe: %s",
+ G_STRFUNC, g_strerror (errno));
+ break;
+ }
+ }
+}
+
+#ifdef HAVE_NSS
+static void
+msgport_sync_with_prpipe (PRFileDesc *prfd)
+{
+ gchar buffer[1];
+
+ while (prfd != NULL) {
+ if (PR_Read (prfd, buffer, 1) > 0)
+ break;
+ else if (PR_GetError () != PR_PENDING_INTERRUPT_ERROR) {
+ gchar *text = g_alloca (PR_GetErrorTextLength ());
+ PR_GetErrorText (text);
+ g_warning ("%s: Failed to read from NSPR pipe: %s",
+ G_STRFUNC, text);
+ break;
+ }
+ }
+}
+#endif
+
+CamelMsgPort *
+camel_msgport_new (void)
+{
+ CamelMsgPort *msgport;
+
+ msgport = g_slice_new (CamelMsgPort);
+ msgport->queue = g_async_queue_new ();
+ msgport->pipe[0] = -1;
+ msgport->pipe[1] = -1;
+#ifdef HAVE_NSS
+ msgport->prpipe[0] = NULL;
+ msgport->prpipe[1] = NULL;
+#endif
+
+ return msgport;
+}
+
+void
+camel_msgport_destroy (CamelMsgPort *msgport)
+{
+ g_return_if_fail (msgport != NULL);
+
+ if (msgport->pipe[0] >= 0) {
+ MP_CLOSE (msgport->pipe[0]);
+ MP_CLOSE (msgport->pipe[1]);
+ }
+#ifdef HAVE_NSS
+ if (msgport->prpipe[0] != NULL) {
+ PR_Close (msgport->prpipe[0]);
+ PR_Close (msgport->prpipe[1]);
+ }
+#endif
+
+ g_async_queue_unref (msgport->queue);
+ g_slice_free (CamelMsgPort, msgport);
+}
+
+gint
+camel_msgport_fd (CamelMsgPort *msgport)
+{
+ gint fd;
+
+ g_return_val_if_fail (msgport != NULL, -1);
+
+ g_async_queue_lock (msgport->queue);
+ fd = msgport->pipe[0];
+ if (fd < 0 && msgport_pipe (msgport->pipe) == 0)
+ fd = msgport->pipe[0];
+ g_async_queue_unlock (msgport->queue);
+
+ return fd;
+}
+
+#ifdef HAVE_NSS
+PRFileDesc *
+camel_msgport_prfd (CamelMsgPort *msgport)
+{
+ PRFileDesc *prfd;
+
+ g_return_val_if_fail (msgport != NULL, NULL);
+
+ g_async_queue_lock (msgport->queue);
+ prfd = msgport->prpipe[0];
+ if (prfd == NULL && msgport_prpipe (msgport->prpipe) == 0)
+ prfd = msgport->prpipe[0];
+ g_async_queue_unlock (msgport->queue);
+
+ return prfd;
+}
+#endif
+
+void
+camel_msgport_push (CamelMsgPort *msgport, CamelMsg *msg)
+{
+ gint fd;
+#ifdef HAVE_NSS
+ PRFileDesc *prfd;
+#endif
+
+ g_return_if_fail (msgport != NULL);
+ g_return_if_fail (msg != NULL);
+
+ g_async_queue_lock (msgport->queue);
+
+ msg->flags = 0;
+
+ fd = msgport->pipe[1];
+ while (fd >= 0) {
+ if (MP_WRITE (fd, "E", 1) > 0) {
+ msg->flags |= MSG_FLAG_SYNC_WITH_PIPE;
+ break;
+ } else if (!MP_IS_STATUS_INTR ()) {
+ g_warning ("%s: Failed to write to pipe: %s",
+ G_STRFUNC, g_strerror (errno));
+ break;
+ }
+ }
+
+#ifdef HAVE_NSS
+ prfd = msgport->prpipe[1];
+ while (prfd != NULL) {
+ if (PR_Write (prfd, "E", 1) > 0) {
+ msg->flags |= MSG_FLAG_SYNC_WITH_PR_PIPE;
+ break;
+ } else if (PR_GetError () != PR_PENDING_INTERRUPT_ERROR) {
+ gchar *text = g_alloca (PR_GetErrorTextLength ());
+ PR_GetErrorText (text);
+ g_warning ("%s: Failed to write to NSPR pipe: %s",
+ G_STRFUNC, text);
+ break;
+ }
+ }
+#endif
+
+ g_async_queue_push_unlocked (msgport->queue, msg);
+ g_async_queue_unlock (msgport->queue);
+}
+
+CamelMsg *
+camel_msgport_pop (CamelMsgPort *msgport)
+{
+ CamelMsg *msg;
+
+ g_return_val_if_fail (msgport != NULL, NULL);
+
+ g_async_queue_lock (msgport->queue);
+
+ msg = g_async_queue_pop_unlocked (msgport->queue);
+
+ g_assert (msg != NULL);
+
+ if (msg->flags & MSG_FLAG_SYNC_WITH_PIPE)
+ msgport_sync_with_pipe (msgport->pipe[0]);
+#ifdef HAVE_NSS
+ if (msg->flags & MSG_FLAG_SYNC_WITH_PR_PIPE)
+ msgport_sync_with_prpipe (msgport->prpipe[0]);
+#endif
+
+ g_async_queue_unlock (msgport->queue);
+
+ return msg;
+}
+
+CamelMsg *
+camel_msgport_try_pop (CamelMsgPort *msgport)
+{
+ CamelMsg *msg;
+
+ g_return_val_if_fail (msgport != NULL, NULL);
+
+ g_async_queue_lock (msgport->queue);
+
+ msg = g_async_queue_try_pop_unlocked (msgport->queue);
+
+ if (msg != NULL && msg->flags & MSG_FLAG_SYNC_WITH_PIPE)
+ msgport_sync_with_pipe (msgport->pipe[0]);
+#ifdef HAVE_NSS
+ if (msg != NULL && msg->flags & MSG_FLAG_SYNC_WITH_PR_PIPE)
+ msgport_sync_with_prpipe (msgport->prpipe[0]);
+#endif
+
+ g_async_queue_unlock (msgport->queue);
+
+ return msg;
+}
+
+void
+camel_msgport_reply (CamelMsg *msg)
+{
+ g_return_if_fail (msg != NULL);
+
+ if (msg->reply_port)
+ camel_msgport_push (msg->reply_port, msg);
+
+ /* else lost? */
+}
Added: trunk/camel/camel-msgport.h
==============================================================================
--- (empty file)
+++ trunk/camel/camel-msgport.h Wed May 7 02:15:39 2008
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright 2007 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef CAMEL_MSGPORT_H
+#define CAMEL_MSGPORT_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _CamelMsg CamelMsg;
+typedef struct _CamelMsgPort CamelMsgPort;
+
+struct _CamelMsg {
+ CamelMsgPort *reply_port;
+ gint flags;
+};
+
+CamelMsgPort * camel_msgport_new (void);
+void camel_msgport_destroy (CamelMsgPort *msgport);
+gint camel_msgport_fd (CamelMsgPort *msgport);
+void camel_msgport_push (CamelMsgPort *msgport,
+ CamelMsg *msg);
+CamelMsg * camel_msgport_pop (CamelMsgPort *msgport);
+CamelMsg * camel_msgport_try_pop (CamelMsgPort *msgport);
+void camel_msgport_reply (CamelMsg *msg);
+
+#ifdef HAVE_NSS
+struct PRFileDesc * camel_msgport_prfd (CamelMsgPort *msgport);
+#endif
+
+G_END_DECLS
+
+#endif /* CAMEL_MSGPORT_H */
Modified: trunk/camel/camel-net-utils.c
==============================================================================
--- trunk/camel/camel-net-utils.c (original)
+++ trunk/camel/camel-net-utils.c Wed May 7 02:15:39 2008
@@ -36,9 +36,8 @@
#include <sys/poll.h>
#endif
-#include <libedataserver/e-msgport.h>
-
#include "camel-exception.h"
+#include "camel-msgport.h"
#include "camel-net-utils.h"
#include "camel-operation.h"
@@ -407,7 +406,7 @@
/* ********************************************************************** */
struct _addrinfo_msg {
- EMsg msg;
+ CamelMsg msg;
unsigned int cancelled:1;
/* for host lookup */
@@ -449,7 +448,7 @@
static int
cs_waitinfo(void *(worker)(void *), struct _addrinfo_msg *msg, const char *error, CamelException *ex)
{
- EMsgPort *reply_port;
+ CamelMsgPort *reply_port;
pthread_t id;
int err, cancel_fd, cancel = 0, fd;
@@ -459,8 +458,8 @@
return 0;
}
- reply_port = msg->msg.reply_port = e_msgport_new();
- fd = e_msgport_fd(msg->msg.reply_port);
+ reply_port = msg->msg.reply_port = camel_msgport_new();
+ fd = camel_msgport_fd(msg->msg.reply_port);
if ((err = pthread_create(&id, NULL, worker, msg)) == 0) {
int status;
#ifndef G_OS_WIN32
@@ -514,7 +513,7 @@
pthread_cancel(id);
cancel = 1;
} else {
- struct _addrinfo_msg *reply = (struct _addrinfo_msg *)e_msgport_get(reply_port);
+ struct _addrinfo_msg *reply = (struct _addrinfo_msg *)camel_msgport_try_pop(reply_port);
g_assert(reply == msg);
d(printf("waiting for child to exit\n"));
@@ -524,7 +523,7 @@
} else {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, "%s: %s: %s", error, _("cannot create thread"), g_strerror(err));
}
- e_msgport_destroy(reply_port);
+ camel_msgport_destroy(reply_port);
return cancel;
}
@@ -630,7 +629,7 @@
}
}
reply:
- e_msgport_reply((EMsg *)msg);
+ camel_msgport_reply((CamelMsg *)msg);
return NULL;
cancel:
cs_freeinfo(msg);
@@ -647,7 +646,7 @@
if (info->cancelled) {
cs_freeinfo(info);
} else {
- e_msgport_reply((EMsg *)info);
+ camel_msgport_reply((CamelMsg *)info);
}
return NULL;
@@ -766,7 +765,7 @@
if (msg->serv)
sprintf(msg->serv, "%d", sin->sin_port);
- e_msgport_reply((EMsg *)msg);
+ camel_msgport_reply((CamelMsg *)msg);
return NULL;
cancel:
cs_freeinfo(msg);
@@ -784,7 +783,7 @@
if (msg->cancelled)
cs_freeinfo(msg);
else
- e_msgport_reply((EMsg *)msg);
+ camel_msgport_reply((CamelMsg *)msg);
return NULL;
}
Modified: trunk/camel/camel-operation.c
==============================================================================
--- trunk/camel/camel-operation.c (original)
+++ trunk/camel/camel-operation.c Wed May 7 02:15:39 2008
@@ -35,9 +35,10 @@
#include <glib.h>
-#include <libedataserver/e-msgport.h>
+#include <libedataserver/e-msgport.h> /* for EDList */
#include "camel-operation.h"
+#include "camel-msgport.h"
#define d(x)
@@ -67,7 +68,7 @@
GSList *status_stack;
struct _status_stack *lastreport;
- EMsgPort *cancel_port;
+ CamelMsgPort *cancel_port;
int cancel_fd;
#ifdef HAVE_NSS
PRFileDesc *cancel_prfd;
@@ -91,7 +92,7 @@
static pthread_once_t operation_once = PTHREAD_ONCE_INIT;
typedef struct _CamelOperationMsg {
- EMsg msg;
+ CamelMsg msg;
} CamelOperationMsg ;
static void
@@ -134,7 +135,7 @@
cc->refcount = 1;
cc->status = status;
cc->status_data = status_data;
- cc->cancel_port = e_msgport_new();
+ cc->cancel_port = camel_msgport_new();
cc->cancel_fd = -1;
LOCK();
@@ -211,10 +212,10 @@
e_dlist_remove((EDListNode *)cc);
- while ((msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port)))
+ while ((msg = (CamelOperationMsg *)camel_msgport_pop(cc->cancel_port)))
g_free(msg);
- e_msgport_destroy(cc->cancel_port);
+ camel_msgport_destroy(cc->cancel_port);
n = cc->status_stack;
while (n) {
@@ -294,7 +295,7 @@
while (cn) {
cc->flags |= CAMEL_OPERATION_CANCELLED;
msg = g_malloc0(sizeof(*msg));
- e_msgport_put(cc->cancel_port, (EMsg *)msg);
+ camel_msgport_push(cc->cancel_port, (CamelMsg *)msg);
cc = cn;
cn = cn->next;
}
@@ -303,7 +304,7 @@
cc->flags |= CAMEL_OPERATION_CANCELLED;
msg = g_malloc0(sizeof(*msg));
- e_msgport_put(cc->cancel_port, (EMsg *)msg);
+ camel_msgport_push(cc->cancel_port, (CamelMsg *)msg);
}
UNLOCK();
@@ -330,7 +331,7 @@
CamelOperationMsg *msg;
LOCK();
- while ((msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port)))
+ while ((msg = (CamelOperationMsg *)camel_msgport_try_pop(cc->cancel_port)))
g_free(msg);
cc->flags &= ~CAMEL_OPERATION_CANCELLED;
@@ -403,11 +404,11 @@
} else if (cc->flags & CAMEL_OPERATION_CANCELLED) {
d(printf("previously cancelled\n"));
cancelled = TRUE;
- } else if ((msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port))) {
+ } else if ((msg = (CamelOperationMsg *)camel_msgport_try_pop(cc->cancel_port))) {
d(printf("Got cancellation message\n"));
do {
g_free(msg);
- } while ((msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port)));
+ } while ((msg = (CamelOperationMsg *)camel_msgport_try_pop(cc->cancel_port)));
cc->flags |= CAMEL_OPERATION_CANCELLED;
cancelled = TRUE;
} else
@@ -440,7 +441,7 @@
LOCK();
if (cc->cancel_fd == -1)
- cc->cancel_fd = e_msgport_fd(cc->cancel_port);
+ cc->cancel_fd = camel_msgport_fd(cc->cancel_port);
UNLOCK();
@@ -470,7 +471,7 @@
LOCK();
if (cc->cancel_prfd == NULL)
- cc->cancel_prfd = e_msgport_prfd(cc->cancel_port);
+ cc->cancel_prfd = camel_msgport_prfd(cc->cancel_port);
UNLOCK();
Modified: trunk/camel/camel-sasl-digest-md5.c
==============================================================================
--- trunk/camel/camel-sasl-digest-md5.c (original)
+++ trunk/camel/camel-sasl-digest-md5.c Wed May 7 02:15:39 2008
@@ -32,9 +32,8 @@
#include <glib.h>
#include <glib/gi18n-lib.h>
-#include <libedataserver/e-iconv.h>
-
#include "camel-charset-map.h"
+#include "camel-iconv.h"
#include "camel-mime-utils.h"
#include "camel-net-utils.h"
#include "camel-sasl-digest-md5.h"
@@ -736,18 +735,18 @@
const char *inbuf;
iconv_t cd;
- charset = e_iconv_locale_charset ();
+ charset = camel_iconv_locale_charset ();
if (!charset)
charset = "iso-8859-1";
- cd = e_iconv_open (resp->charset, charset);
+ cd = camel_iconv_open (resp->charset, charset);
len = strlen (resp->username);
outlen = 2 * len; /* plenty of space */
outbuf = username = g_malloc0 (outlen + 1);
inbuf = resp->username;
- if (cd == (iconv_t) -1 || e_iconv (cd, &inbuf, &len, &outbuf, &outlen) == (size_t) -1) {
+ if (cd == (iconv_t) -1 || camel_iconv (cd, &inbuf, &len, &outbuf, &outlen) == (size_t) -1) {
/* We can't convert to UTF-8 - pretend we never got a charset param? */
g_free (resp->charset);
resp->charset = NULL;
@@ -758,7 +757,7 @@
}
if (cd != (iconv_t) -1)
- e_iconv_close (cd);
+ camel_iconv_close (cd);
g_byte_array_append (buffer, (guint8 *) username, strlen (username));
g_free (username);
Modified: trunk/camel/camel-session.h
==============================================================================
--- trunk/camel/camel-session.h (original)
+++ trunk/camel/camel-session.h Wed May 7 02:15:39 2008
@@ -27,12 +27,11 @@
#ifndef CAMEL_SESSION_H
#define CAMEL_SESSION_H 1
+#include <camel/camel-msgport.h>
#include <camel/camel-object.h>
#include <camel/camel-provider.h>
#include <camel/camel-junk-plugin.h>
-#include <libedataserver/e-msgport.h>
-
#define CAMEL_SESSION_TYPE (camel_session_get_type ())
#define CAMEL_SESSION(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SESSION_TYPE, CamelSession))
#define CAMEL_SESSION_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SESSION_TYPE, CamelSessionClass))
@@ -191,7 +190,7 @@
};
struct _CamelSessionThreadMsg {
- EMsg msg;
+ CamelMsg msg;
int id;
Added: trunk/camel/camel-trie.c
==============================================================================
--- (empty file)
+++ trunk/camel/camel-trie.c Wed May 7 02:15:39 2008
@@ -0,0 +1,382 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright 2007 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include <libedataserver/e-memory.h>
+
+#include "camel-trie.h"
+
+#define d(x)
+
+struct _trie_state {
+ struct _trie_state *next;
+ struct _trie_state *fail;
+ struct _trie_match *match;
+ unsigned int final;
+ int id;
+};
+
+struct _trie_match {
+ struct _trie_match *next;
+ struct _trie_state *state;
+ gunichar c;
+};
+
+/**
+ * CamelTrie:
+ *
+ * A trie data structure.
+ **/
+struct _CamelTrie {
+ struct _trie_state root;
+ GPtrArray *fail_states;
+ gboolean icase;
+
+ EMemChunk *match_chunks;
+ EMemChunk *state_chunks;
+};
+
+
+static inline gunichar
+trie_utf8_getc (const unsigned char **in, size_t inlen)
+{
+ register const unsigned char *inptr = *in;
+ const unsigned char *inend = inptr + inlen;
+ register unsigned char c, r;
+ register gunichar u, m;
+
+ if (inlen == 0)
+ return 0;
+
+ r = *inptr++;
+ if (r < 0x80) {
+ *in = inptr;
+ u = r;
+ } else if (r < 0xfe) { /* valid start char? */
+ u = r;
+ m = 0x7f80; /* used to mask out the length bits */
+ do {
+ if (inptr >= inend)
+ return 0;
+
+ c = *inptr++;
+ if ((c & 0xc0) != 0x80)
+ goto error;
+
+ u = (u << 6) | (c & 0x3f);
+ r <<= 1;
+ m <<= 5;
+ } while (r & 0x40);
+
+ *in = inptr;
+
+ u &= ~m;
+ } else {
+ error:
+ *in = (*in)+1;
+ u = 0xfffe;
+ }
+
+ return u;
+}
+
+/**
+ * camel_trie_new:
+ * @icase: Case sensitivity for the #CamelTrie.
+ *
+ * Creates a new #CamelTrie. If @icase is %TRUE, then pattern matching
+ * done by the CamelTrie will be case insensitive.
+ *
+ * Returns: The newly-created #CamelTrie.
+ **/
+CamelTrie *
+camel_trie_new (gboolean icase)
+{
+ CamelTrie *trie;
+
+ trie = g_new (CamelTrie, 1);
+ trie->root.next = NULL;
+ trie->root.fail = NULL;
+ trie->root.match = NULL;
+ trie->root.final = 0;
+
+ trie->fail_states = g_ptr_array_sized_new (8);
+ trie->icase = icase;
+
+ trie->match_chunks = e_memchunk_new (8, sizeof (struct _trie_match));
+ trie->state_chunks = e_memchunk_new (8, sizeof (struct _trie_state));
+
+ return trie;
+}
+
+/**
+ * camel_trie_free:
+ * @trie: The #CamelTrie to free.
+ *
+ * Frees the memory associated with the #CamelTrie @trie.
+ **/
+void
+camel_trie_free (CamelTrie *trie)
+{
+ g_ptr_array_free (trie->fail_states, TRUE);
+ e_memchunk_destroy (trie->match_chunks);
+ e_memchunk_destroy (trie->state_chunks);
+ g_free (trie);
+}
+
+
+
+static struct _trie_match *
+g (struct _trie_state *s, gunichar c)
+{
+ struct _trie_match *m = s->match;
+
+ while (m && m->c != c)
+ m = m->next;
+
+ return m;
+}
+
+static struct _trie_state *
+trie_insert (CamelTrie *trie, int depth, struct _trie_state *q, gunichar c)
+{
+ struct _trie_match *m;
+
+ m = e_memchunk_alloc (trie->match_chunks);
+ m->next = q->match;
+ m->c = c;
+
+ q->match = m;
+ q = m->state = e_memchunk_alloc (trie->state_chunks);
+ q->match = NULL;
+ q->fail = &trie->root;
+ q->final = 0;
+ q->id = -1;
+
+ if (trie->fail_states->len < depth + 1) {
+ unsigned int size = trie->fail_states->len;
+
+ size = MAX (size + 64, depth + 1);
+ g_ptr_array_set_size (trie->fail_states, size);
+ }
+
+ q->next = trie->fail_states->pdata[depth];
+ trie->fail_states->pdata[depth] = q;
+
+ return q;
+}
+
+
+#if 1
+static void
+dump_trie (struct _trie_state *s, int depth)
+{
+ char *p = g_alloca ((depth * 2) + 1);
+ struct _trie_match *m;
+
+ memset (p, ' ', depth * 2);
+ p[depth * 2] = '\0';
+
+ fprintf (stderr, "%s[state] %p: final=%d; pattern-id=%d; fail=%p\n",
+ p, s, s->final, s->id, s->fail);
+ m = s->match;
+ while (m) {
+ fprintf (stderr, " %s'%c' -> %p\n", p, m->c, m->state);
+ if (m->state)
+ dump_trie (m->state, depth + 1);
+
+ m = m->next;
+ }
+}
+#endif
+
+
+/*
+ * final = empty set
+ * FOR p = 1 TO #pat
+ * q = root
+ * FOR j = 1 TO m[p]
+ * IF g(q, pat[p][j]) == null
+ * insert(q, pat[p][j])
+ * ENDIF
+ * q = g(q, pat[p][j])
+ * ENDFOR
+ * final = union(final, q)
+ * ENDFOR
+*/
+
+/**
+ * camel_trie_add:
+ * @trie: The #CamelTrie to add a pattern to.
+ * @pattern: The pattern to add.
+ * @pattern_id: The id to use for the pattern.
+ *
+ * Add a new pattern to the #CamelTrie @trie.
+ **/
+void
+camel_trie_add (CamelTrie *trie, const gchar *pattern, gint pattern_id)
+{
+ const unsigned char *inptr = (const unsigned char *) pattern;
+ struct _trie_state *q, *q1, *r;
+ struct _trie_match *m, *n;
+ int i, depth = 0;
+ gunichar c;
+
+ /* Step 1: add the pattern to the trie */
+
+ q = &trie->root;
+
+ while ((c = trie_utf8_getc (&inptr, -1))) {
+ if (trie->icase)
+ c = g_unichar_tolower (c);
+
+ m = g (q, c);
+ if (m == NULL) {
+ q = trie_insert (trie, depth, q, c);
+ } else {
+ q = m->state;
+ }
+
+ depth++;
+ }
+
+ q->final = depth;
+ q->id = pattern_id;
+
+ /* Step 2: compute failure graph */
+
+ for (i = 0; i < trie->fail_states->len; i++) {
+ q = trie->fail_states->pdata[i];
+ while (q) {
+ m = q->match;
+ while (m) {
+ c = m->c;
+ q1 = m->state;
+ r = q->fail;
+ while (r && (n = g (r, c)) == NULL)
+ r = r->fail;
+
+ if (r != NULL) {
+ q1->fail = n->state;
+ if (q1->fail->final > q1->final)
+ q1->final = q1->fail->final;
+ } else {
+ if ((n = g (&trie->root, c)))
+ q1->fail = n->state;
+ else
+ q1->fail = &trie->root;
+ }
+
+ m = m->next;
+ }
+
+ q = q->next;
+ }
+ }
+
+ d(fprintf (stderr, "\nafter adding pattern '%s' to trie %p:\n", pattern, trie));
+ d(dump_trie (&trie->root, 0));
+}
+
+/*
+ * Aho-Corasick
+ *
+ * q = root
+ * FOR i = 1 TO n
+ * WHILE q != fail AND g(q, text[i]) == fail
+ * q = h(q)
+ * ENDWHILE
+ * IF q == fail
+ * q = root
+ * ELSE
+ * q = g(q, text[i])
+ * ENDIF
+ * IF isElement(q, final)
+ * RETURN TRUE
+ * ENDIF
+ * ENDFOR
+ * RETURN FALSE
+ */
+
+/**
+ * camel_trie_search:
+ * @trie: The #CamelTrie to search in.
+ * @buffer: The string to match against a pattern in @trie.
+ * @buflen: The length of @buffer.
+ * @matched_id: An integer address to store the matched pattern id in.
+ *
+ * Try to match the string @buffer with a pattern in @trie.
+ *
+ * Returns: The matched pattern, or %NULL if no pattern is matched.
+ **/
+const gchar *
+camel_trie_search (CamelTrie *trie, const gchar *buffer, gsize buflen,
+ gint *matched_id)
+{
+ const unsigned char *inptr, *inend, *prev, *pat;
+ register size_t inlen = buflen;
+ struct _trie_state *q;
+ struct _trie_match *m = NULL; /* init to please gcc */
+ gunichar c;
+
+ inptr = (const unsigned char *) buffer;
+ inend = inptr + buflen;
+
+ q = &trie->root;
+ pat = prev = inptr;
+ while ((c = trie_utf8_getc (&inptr, inlen))) {
+ inlen = (inend - inptr);
+
+ if (c != 0xfffe) {
+ if (trie->icase)
+ c = g_unichar_tolower (c);
+
+ while (q != NULL && (m = g (q, c)) == NULL)
+ q = q->fail;
+
+ if (q == &trie->root)
+ pat = prev;
+
+ if (q == NULL) {
+ q = &trie->root;
+ pat = inptr;
+ } else if (m != NULL) {
+ q = m->state;
+
+ if (q->final) {
+ if (matched_id)
+ *matched_id = q->id;
+
+ return (const char *) pat;
+ }
+ }
+ }
+
+ prev = inptr;
+ }
+
+ return NULL;
+}
Added: trunk/camel/camel-trie.h
==============================================================================
--- (empty file)
+++ trunk/camel/camel-trie.h Wed May 7 02:15:39 2008
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright 2007 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef CAMEL_TRIE_H
+#define CAMEL_TRIE_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _CamelTrie CamelTrie;
+
+CamelTrie * camel_trie_new (gboolean icase);
+void camel_trie_free (CamelTrie *trie);
+void camel_trie_add (CamelTrie *trie,
+ const gchar *pattern,
+ gint pattern_id);
+const gchar * camel_trie_search (CamelTrie *trie,
+ const gchar *buffer,
+ gsize buflen,
+ gint *matched_id);
+
+G_END_DECLS
+
+#endif /* CAMEL_TRIE_H */
Modified: trunk/camel/camel-url-scanner.c
==============================================================================
--- trunk/camel/camel-url-scanner.c (original)
+++ trunk/camel/camel-url-scanner.c Wed May 7 02:15:39 2008
@@ -29,14 +29,13 @@
#include <stdio.h>
#include <string.h>
-#include <libedataserver/e-trie.h>
-
+#include "camel-trie.h"
#include "camel-url-scanner.h"
#include "camel-utf8.h"
struct _CamelUrlScanner {
GPtrArray *patterns;
- ETrie *trie;
+ CamelTrie *trie;
};
@@ -47,7 +46,7 @@
scanner = g_new (CamelUrlScanner, 1);
scanner->patterns = g_ptr_array_new ();
- scanner->trie = e_trie_new (TRUE);
+ scanner->trie = camel_trie_new (TRUE);
return scanner;
}
@@ -59,7 +58,7 @@
g_return_if_fail (scanner != NULL);
g_ptr_array_free (scanner->patterns, TRUE);
- e_trie_free (scanner->trie);
+ camel_trie_free (scanner->trie);
g_free (scanner);
}
@@ -69,7 +68,7 @@
{
g_return_if_fail (scanner != NULL);
- e_trie_add (scanner->trie, pattern->pattern, scanner->patterns->len);
+ camel_trie_add (scanner->trie, pattern->pattern, scanner->patterns->len);
g_ptr_array_add (scanner->patterns, pattern);
}
@@ -89,7 +88,7 @@
inend = inptr + inlen;
do {
- if (!(pos = e_trie_search (scanner->trie, (const char *)inptr, inlen, &pattern)))
+ if (!(pos = camel_trie_search (scanner->trie, (const char *)inptr, inlen, &pattern)))
return FALSE;
pat = g_ptr_array_index (scanner->patterns, pattern);
Modified: trunk/camel/camel.h
==============================================================================
--- trunk/camel/camel.h (original)
+++ trunk/camel/camel.h Wed May 7 02:15:39 2008
@@ -82,6 +82,7 @@
#include <camel/camel-mime-part-utils.h>
#include <camel/camel-mime-utils.h>
#include <camel/camel-movemail.h>
+#include <camel/camel-msgport.h>
#include <camel/camel-multipart.h>
#include <camel/camel-multipart-encrypted.h>
#include <camel/camel-multipart-signed.h>
@@ -127,6 +128,7 @@
#include <camel/camel-tcp-stream-ssl.h>
#include <camel/camel-text-index.h>
#include <camel/camel-transport.h>
+#include <camel/camel-trie.h>
#include <camel/camel-types.h>
#include <camel/camel-uid-cache.h>
#include <camel/camel-url.h>
Modified: trunk/camel/providers/imapp/camel-imapp-driver.c
==============================================================================
--- trunk/camel/providers/imapp/camel-imapp-driver.c (original)
+++ trunk/camel/providers/imapp/camel-imapp-driver.c Wed May 7 02:15:39 2008
@@ -927,7 +927,7 @@
int go = TRUE;
do {
- /*m = (CamelIMAPPMsg *)e_msgport_get(id->queue);*/
+ /*m = (CamelIMAPPMsg *)camel_msgport_try_pop(id->queue);*/
switch (m->type) {
case CAMEL_IMAPP_MSG_FETCH:
/*e_dlist_addtail(&id->fetch_queue, (EDListNode *)m);*/
Modified: trunk/camel/providers/imapp/camel-imapp-engine.c
==============================================================================
--- trunk/camel/providers/imapp/camel-imapp-engine.c (original)
+++ trunk/camel/providers/imapp/camel-imapp-engine.c Wed May 7 02:15:39 2008
@@ -44,7 +44,7 @@
e_dlist_init(&ie->active);
e_dlist_init(&ie->done);
- ie->port = e_msgport_new();
+ ie->port = camel_msgport_new();
ie->tagprefix = ieclass->tagprefix;
ieclass->tagprefix++;
@@ -688,7 +688,7 @@
if (ic->mem)
imap_engine_command_complete(imap, ic);
- e_msgport_put(imap->port, (EMsg *)ic);
+ camel_msgport_push(imap->port, (EMsg *)ic);
}
CamelIMAPPCommand *
Modified: trunk/docs/reference/camel/camel-docs.sgml
==============================================================================
--- trunk/docs/reference/camel/camel-docs.sgml (original)
+++ trunk/docs/reference/camel/camel-docs.sgml Wed May 7 02:15:39 2008
@@ -20,11 +20,13 @@
<!ENTITY CamelGPGContext SYSTEM "xml/camel-gpg-context.xml">
<!ENTITY CamelHTMLParser SYSTEM "xml/camel-html-parser.xml">
<!ENTITY CamelHTTPStream SYSTEM "xml/camel-http-stream.xml">
+<!ENTITY CamelIconv SYSTEM "xml/camel-iconv.xml">
<!ENTITY CamelIndex SYSTEM "xml/camel-index.xml">
<!ENTITY CamelInternetAddress SYSTEM "xml/camel-internet-address.xml">
<!ENTITY CamelListUtils SYSTEM "xml/camel-list-utils.xml">
<!ENTITY CamelLock SYSTEM "xml/camel-lock.xml">
<!ENTITY CamelLockClient SYSTEM "xml/camel-lock-client.xml">
+<!ENTITY CamelMD5Utils SYSTEM "xml/camel-md5-utils.xml">
<!ENTITY CamelMedium SYSTEM "xml/camel-medium.xml">
<!ENTITY CamelMIMEFilter SYSTEM "xml/camel-mime-filter.xml">
<!ENTITY CamelMIMEFilterBasic SYSTEM "xml/camel-mime-filter-basic.xml">
@@ -46,6 +48,7 @@
<!ENTITY CamelMIMEPart SYSTEM "xml/camel-mime-part.xml">
<!ENTITY CamelMIMEPartUtils SYSTEM "xml/camel-mime-part-utils.xml">
<!ENTITY CamelMIMEUtils SYSTEM "xml/camel-mime-utils.xml">
+<!ENTITY CamelMsgPort SYSTEM "xml/camel-msgport.xml">
<!ENTITY CamelMultipart SYSTEM "xml/camel-multipart.xml">
<!ENTITY CamelMultipartEncrypted SYSTEM "xml/camel-multipart-encrypted.xml">
<!ENTITY CamelMultipartSigned SYSTEM "xml/camel-multipart-signed.xml">
@@ -88,6 +91,7 @@
<!ENTITY CamelTcpStreamSSL SYSTEM "xml/camel-tcp-stream-ssl.xml">
<!ENTITY CamelTextIndex SYSTEM "xml/camel-text-index.xml">
<!ENTITY CamelTransport SYSTEM "xml/camel-transport.xml">
+<!ENTITY CamelTrie SYSTEM "xml/camel-trie.xml">
<!ENTITY CamelUIDCache SYSTEM "xml/camel-uid-cache.xml">
<!ENTITY CamelURL SYSTEM "xml/camel-url.xml">
<!ENTITY CamelURLScanner SYSTEM "xml/camel-url-scanner.xml">
Modified: trunk/docs/reference/camel/camel-sections.txt
==============================================================================
--- trunk/docs/reference/camel/camel-sections.txt (original)
+++ trunk/docs/reference/camel/camel-sections.txt Wed May 7 02:15:39 2008
@@ -635,6 +635,16 @@
</SECTION>
<SECTION>
+<FILE>camel-md5-utils</FILE>
+CamelMD5Context
+camel_md5_get_digest
+camel_md5_get_digest_from_file
+camel_md5_init
+camel_md5_update
+camel_md5_final
+</SECTION>
+
+<SECTION>
<FILE>camel-medium</FILE>
<TITLE>CamelMedium</TITLE>
CamelMedium
@@ -1083,6 +1093,21 @@
</SECTION>
<SECTION>
+<FILE>camel-msgport</FILE>
+<TITLE>CamelMsgPort</TITLE>
+CamelMsg
+CamelMsgPort
+camel_msgport_new
+camel_msgport_destroy
+camel_msgport_fd
+camel_msgport_push
+camel_msgport_pop
+camel_msgport_try_pop
+camel_msgport_reply
+camel_msgport_prfd
+</SECTION>
+
+<SECTION>
<FILE>camel-multipart-encrypted</FILE>
<TITLE>CamelMultipartEncrypted</TITLE>
CamelMultipartEncrypted
@@ -1966,6 +1991,15 @@
</SECTION>
<SECTION>
+<FILE>camel-trie</FILE>
+CamelTrie
+camel_trie_new
+camel_trie_free
+camel_trie_add
+camel_trie_search
+</SECTION>
+
+<SECTION>
<FILE>camel-vee-folder</FILE>
<TITLE>CamelVeeFolder</TITLE>
CamelVeeFolder
Modified: trunk/docs/reference/camel/tmpl/camel-unused.sgml
==============================================================================
--- trunk/docs/reference/camel/tmpl/camel-unused.sgml (original)
+++ trunk/docs/reference/camel/tmpl/camel-unused.sgml Wed May 7 02:15:39 2008
@@ -286,6 +286,12 @@
@search_lock:
+<!-- ##### STRUCT CamelMD5Context ##### -->
+<para>
+
+</para>
+
+
<!-- ##### STRUCT CamelMimeFilterChomp ##### -->
<para>
@@ -458,6 +464,47 @@
@Returns:
+<!-- ##### FUNCTION camel_md5_final ##### -->
+<para>
+
+</para>
+
+ ctx:
+ digest:
+
+<!-- ##### FUNCTION camel_md5_get_digest ##### -->
+<para>
+
+</para>
+
+ buffer:
+ buffer_size:
+ digest:
+
+<!-- ##### FUNCTION camel_md5_get_digest_from_file ##### -->
+<para>
+
+</para>
+
+ filename:
+ digest:
+
+<!-- ##### FUNCTION camel_md5_init ##### -->
+<para>
+
+</para>
+
+ ctx:
+
+<!-- ##### FUNCTION camel_md5_update ##### -->
+<para>
+
+</para>
+
+ ctx:
+ buf:
+ len:
+
<!-- ##### FUNCTION camel_partition_table_get_type ##### -->
<para>
Modified: trunk/docs/reference/libebackend/libebackend-sections.txt
==============================================================================
--- trunk/docs/reference/libebackend/libebackend-sections.txt (original)
+++ trunk/docs/reference/libebackend/libebackend-sections.txt Wed May 7 02:15:39 2008
@@ -22,6 +22,7 @@
e_file_cache_get_type
E_FILE_CACHE_CLASS
E_IS_FILE_CACHE_CLASS
+EFileCacheClass
</SECTION>
<SECTION>
Modified: trunk/docs/reference/libedataserver/libedataserver-sections.txt
==============================================================================
--- trunk/docs/reference/libedataserver/libedataserver-sections.txt (original)
+++ trunk/docs/reference/libedataserver/libedataserver-sections.txt Wed May 7 02:15:39 2008
@@ -340,6 +340,8 @@
e_categories_get_icon_file_for
e_categories_set_icon_file_for
e_categories_is_searchable
+e_categories_register_change_listener
+e_categories_unregister_change_listener
</SECTION>
<SECTION>
Modified: trunk/libedataserver/e-iconv.h
==============================================================================
--- trunk/libedataserver/e-iconv.h (original)
+++ trunk/libedataserver/e-iconv.h Wed May 7 02:15:39 2008
@@ -22,9 +22,13 @@
* 02110-1301, USA.
*/
+/* This API has been moved to Camel. */
+
#ifndef _E_ICONV_H_
#define _E_ICONV_H_
+#ifndef EDS_DISABLE_DEPRECATED
+
#include <iconv.h>
#ifdef __cplusplus
@@ -46,4 +50,6 @@
}
#endif /* __cplusplus */
+#endif /* EDS_DISABLE_DEPRECATED */
+
#endif /* !_E_ICONV_H_ */
Modified: trunk/libedataserver/e-msgport.h
==============================================================================
--- trunk/libedataserver/e-msgport.h (original)
+++ trunk/libedataserver/e-msgport.h Wed May 7 02:15:39 2008
@@ -48,6 +48,7 @@
void em_cache_add(EMCache *emc, EMCacheNode *n);
void em_cache_clear(EMCache *emc);
+#ifndef EDS_DISABLE_DEPRECATED
/* message ports - a simple inter-thread 'ipc' primitive */
/* opaque handle */
typedef struct _EMsgPort EMsgPort;
@@ -70,6 +71,7 @@
#ifdef HAVE_NSS
struct PRFileDesc *e_msgport_prfd(EMsgPort *mp);
#endif
+#endif /* EDS_DISABLE_DEPRECATED */
#ifndef EDS_DISABLE_DEPRECATED
/* e threads, a server thread with a message based request-response, and flexible queuing */
@@ -93,7 +95,7 @@
void e_thread_set_msg_received(EThread *e, EThreadFunc received, void *data);
void e_thread_put(EThread *e, EMsg *msg);
int e_thread_busy(EThread *e);
-#endif
+#endif /* EDS_DISABLE_DEPRECATED */
#ifndef EDS_DISABLE_DEPRECATED
/* sigh, another mutex interface, this one allows different mutex types, portably */
@@ -111,6 +113,6 @@
void e_mutex_assert_locked(EMutex *m);
/* this uses pthread cond's */
int e_mutex_cond_wait(void *cond, EMutex *m);
-#endif
+#endif /* EDS_DISABLE_DEPRECATED */
#endif
Modified: trunk/libedataserver/e-trie.h
==============================================================================
--- trunk/libedataserver/e-trie.h (original)
+++ trunk/libedataserver/e-trie.h Wed May 7 02:15:39 2008
@@ -20,10 +20,13 @@
*
*/
+/* This API has been moved to Camel. */
#ifndef __E_TRIE_H__
#define __E_TRIE_H__
+#ifndef EDS_DISABLE_DEPRECATED
+
#ifdef __cplusplus
extern "C" {
#pragma }
@@ -44,4 +47,6 @@
}
#endif /* __cplusplus */
+#endif /* EDS_DISABLE_DEPRECATED */
+
#endif /* __E_TRIE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]