diff options
Diffstat (limited to 'camel/camel-charset-map.c')
-rw-r--r-- | camel/camel-charset-map.c | 308 |
1 files changed, 0 insertions, 308 deletions
diff --git a/camel/camel-charset-map.c b/camel/camel-charset-map.c index fd530165ed..ff63f86844 100644 --- a/camel/camel-charset-map.c +++ b/camel/camel-charset-map.c @@ -203,7 +203,6 @@ void main(void) #include <string.h> #include <ctype.h> #include <glib.h> -#include <e-util/e-msgport.h> #ifdef ENABLE_THREADS #include <pthread.h> #endif @@ -211,157 +210,6 @@ void main(void) #include <alloca.h> #endif -#define cd(x) /* 'cache debug' */ - -#ifdef ENABLE_THREADS -static pthread_mutex_t iconv_charsets_lock = PTHREAD_MUTEX_INITIALIZER; -#define ICONV_CHARSETS_LOCK() pthread_mutex_lock (&iconv_charsets_lock) -#define ICONV_CHARSETS_UNLOCK() pthread_mutex_unlock (&iconv_charsets_lock) -#else -#define ICONV_CHARSETS_LOCK() -#define ICONV_CHARSETS_UNLOCK() -#endif /* ENABLE_THREADS */ - -struct _iconv_cache_node { - EDListNode ln; - - iconv_t ip; -}; - -struct _iconv_cache { - EDListNode ln; - - char *conv; - - EDList inuse; /* opened ic's in use - if both these lists empty == failed to open conversion */ - EDList free; /* opened ic's free */ -}; - -#define CAMEL_ICONV_CACHE_SIZE (16) - -static EDList iconv_cache_list; - -static GHashTable *iconv_charsets = NULL; -static char *locale_charset = NULL; - -struct { - char *charset; - char *iconv_name; -} known_iconv_charsets[] = { - /* 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_charset_map_to_iconv() 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_charset_map_to_iconv() so I'm not going to bother - putting them all in here either... */ - { "ks_c_5601-1987", "euc-kr" }, - { NULL, NULL } -}; - - -static void -shutdown_foreach (gpointer key, gpointer value, gpointer data) -{ - g_free (key); - g_free (value); -} - -static void -flush_iconv_entry(struct _iconv_cache *ic) -{ - struct _iconv_cache_node *node; - - cd(printf("Flushing iconv cache entry: %s\n", ic->conv)); - - while ( (node = (struct _iconv_cache_node *)e_dlist_remhead(&ic->inuse)) ) { - iconv_close(node->ip); - g_free(node); - } - while ( (node = (struct _iconv_cache_node *)e_dlist_remhead(&ic->free)) ) { - iconv_close(node->ip); - g_free(node); - } - g_free(ic->conv); - g_free(ic); -} - -static void -camel_charset_map_shutdown (void) -{ - struct _iconv_cache *ic, *in; - - g_hash_table_foreach (iconv_charsets, shutdown_foreach, NULL); - g_hash_table_destroy (iconv_charsets); - g_free (locale_charset); - - ic = (struct _iconv_cache *)iconv_cache_list.head; - in = (struct _iconv_cache *)ic->ln.next; - while (in) { - flush_iconv_entry(ic); - ic = in; - in = (struct _iconv_cache *)in->ln.next; - } -} - -void -camel_charset_map_init (void) -{ - char *locale; - int i; - - if (iconv_charsets) - return; - - iconv_charsets = g_hash_table_new (g_strcase_hash, g_strcase_equal); - for (i = 0; known_iconv_charsets[i].charset != NULL; i++) { - g_hash_table_insert (iconv_charsets, g_strdup (known_iconv_charsets[i].charset), - g_strdup (known_iconv_charsets[i].iconv_name)); - } - - e_dlist_init(&iconv_cache_list); - - locale = setlocale (LC_ALL, NULL); - - 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; - } 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 *p; - int len; - - p = strchr (locale, '@'); - if (p == NULL) - p = strchr (locale, '/'); /* This is a hack for Solaris systems */ - - len = p ? (p - locale) : strlen (locale); - if ((p = strchr (locale, '.'))) { - locale_charset = g_strndup (p + 1, len - (p - locale) + 1); - g_strdown (locale_charset); - } - } - - g_atexit (camel_charset_map_shutdown); -} - void camel_charset_init (CamelCharset *c) { @@ -444,161 +292,5 @@ camel_charset_best (const char *in, int len) return camel_charset_best_name (&charset); } -const char * -camel_charset_locale_name (void) -{ - return locale_charset; -} - -const char * -camel_charset_to_iconv (const char *name) -{ - const char *charset; - - if (name == NULL) - return NULL; - - ICONV_CHARSETS_LOCK (); - charset = g_hash_table_lookup (iconv_charsets, name); - if (!charset) { - /* Attempt to friendlyify the charset */ - char *new_charset, *p; - int len; - - if (!g_strncasecmp (name, "iso", 3) && name[3] != '-' && name[3] != '_') { - /* Hack to convert charsets like ISO8859-1 to iconv-friendly ISO-8859-1 */ - len = strlen (name); - new_charset = g_malloc (len + 2); - memcpy (new_charset, name, 3); - new_charset[3] = '-'; - memcpy (new_charset + 4, name + 3, len - 3); - new_charset[len + 1] = '\0'; - } else if (!g_strncasecmp (name, "windows-", 8)) { - /* Convert charsets like windows-1251 and windows-cp1251 to iconv-friendly cp1251 */ - new_charset = (char *) name + 8; - if (!g_strncasecmp (new_charset, "cp", 2)) - new_charset += 2; - - for (p = new_charset; *p && isdigit ((unsigned) *p); p++); - if (*p == '\0') - new_charset = g_strdup_printf ("cp%s", new_charset); - else - new_charset = g_strdup (name); - } else { - /* *shrug* - add it to the hash table just the way it is? */ - new_charset = g_strdup (name); - } - - g_hash_table_insert (iconv_charsets, g_strdup (name), new_charset); - charset = new_charset; - } - ICONV_CHARSETS_UNLOCK (); - - return charset; -} - -iconv_t camel_charset_iconv_open(const char *oto, const char *ofrom) -{ - const char *to, *from; - char *tofrom; - struct _iconv_cache *ic, *icnew = NULL; - struct _iconv_cache_node *node; - iconv_t ip; - - to = camel_charset_to_iconv(oto); - from = camel_charset_to_iconv(ofrom); - tofrom = alloca(strlen(to) +strlen(from) + 1); - sprintf(tofrom, "%s%s", to, from); - - ICONV_CHARSETS_LOCK(); - ic = (struct _iconv_cache *)iconv_cache_list.head; - while (ic->ln.next) { - if (!strcasecmp(ic->conv, tofrom)) - break; - ic = (struct _iconv_cache *)ic->ln.next; - } - - if (ic->ln.next == NULL) { - int extra = e_dlist_length(&iconv_cache_list) - CAMEL_ICONV_CACHE_SIZE; - struct _iconv_cache *old = (struct _iconv_cache *)iconv_cache_list.head, - *next = (struct _iconv_cache *)old->ln.next; - - /* flush any 'old' entries out, if we can */ - while (extra>0 && next) { - if (e_dlist_empty(&old->inuse)) { - e_dlist_remove(&old->ln); - flush_iconv_entry(old); - extra--; - } - old = next; - next = (struct _iconv_cache *)old->ln.next; - } - - icnew = ic = g_malloc(sizeof(*ic)); - e_dlist_init(&ic->inuse); - e_dlist_init(&ic->free); - ic->conv = g_strdup(tofrom); - } else { - e_dlist_remove(&ic->ln); - } - - node = (struct _iconv_cache_node *)e_dlist_remhead(&ic->free); - if (node) { - cd(printf("Returning cached success of: %s to %s\n", from, to)); - e_dlist_addhead(&ic->inuse, &node->ln); - ip = node->ip; - } else { - if (e_dlist_empty(&ic->inuse) && icnew == NULL) { - cd(printf("returning cached failure of conversion: %s to %s\n", from, to)); - ip = (iconv_t)-1; - } else { - ip = iconv_open(to, from); - if (ip != (iconv_t)-1) { - cd(printf("Creating cached opening of: %s to %s = %p\n", from, to, ip)); - node = g_malloc(sizeof(*node)); - node->ip = ip; - e_dlist_addhead(&ic->inuse, &node->ln); - } - } - } - - e_dlist_addtail(&iconv_cache_list, &ic->ln); - - ICONV_CHARSETS_UNLOCK(); - - return ip; -} - -void camel_charset_iconv_close(iconv_t ip) -{ - struct _iconv_cache *ic; - struct _iconv_cache_node *node; - - if (ip == (iconv_t)-1) - return; - - ICONV_CHARSETS_LOCK(); - ic = (struct _iconv_cache *)iconv_cache_list.tailpred; - while (ic->ln.prev) { - cd(printf("closing iconv %p, checking against name '%s'\n", ip, ic->conv)); - node = (struct _iconv_cache_node *)ic->inuse.head; - while (node->ln.next) { - cd(printf("closing iconv %p, checking against node '%p'\n", ip, node->ip)); - if (node->ip == ip) { - e_dlist_remove(&node->ln); - e_dlist_addhead(&ic->free, &node->ln); - ICONV_CHARSETS_UNLOCK(); - return; - } - node = (struct _iconv_cache_node *)node->ln.next; - } - ic = (struct _iconv_cache *)ic->ln.prev; - } - - ICONV_CHARSETS_UNLOCK(); - - g_warning("Trying to close iconv i dont know about: %p", ip); -} - #endif /* !BUILD_MAP */ |