static char rcsid[] = "@(#)$Id: charset_input.c,v 1.8 2006/04/09 07:37:07 hurtta Exp $"; /****************************************************************************** * The Elm (ME+) Mail System - $Revision: 1.8 $ $State: Exp $ * * Author: Kari Hurtta (was hurtta+elm@ozone.FMI.FI) *****************************************************************************/ #include "headers.h" #include "s_me.h" #include "cs_imp.h" DEBUG_VAR(Debug,__FILE__,"charset"); struct charset_state * new_state_1(set) charset_t set; { struct charset_state * res = safe_malloc(sizeof (struct charset_state)); /* defined in hdrs/defs.h */ bzero((void *)res,sizeof (struct charset_state)); if (CS_charset_magic != set->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"new_state_1", "Bad magic number (set)",0); res->charset = set; res->caller_flags = 0; /* Not used here, but maybe by caller */ res->p = safe_malloc(sizeof (struct state_private_data)); /* defined in hdrs/defs.h */ bzero((void *)res->p,sizeof (struct state_private_data)); res->p->ready = 0; res->charset->charset_type->cs_init_s_it(res); return res; } struct charset_state * new_state(set) charset_t set; { struct charset_state * res; DPRINT(Debug,60,(&Debug, "new_state(%p) ('%s'; type=%p '%s')\n", set, set->MIME_name ? set->MIME_name : "", set->charset_type, set->charset_type->type_name)); if (CS_charset_magic != set->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"new_state_1", "Bad magic number (set)",0); /* Initialize associated map if not done already ... */ if (set->map_info && !set->map_info->map_initialized) set->map_info->map_init_it(set->map_info); res = new_state_1(set); DPRINT(Debug,60,(&Debug, "new_state=%p\n",res)); return res; } void free_state_internal(state) struct charset_state **state; { (*state)->charset->charset_type->cs_free_s_it(*state); free((*state)->p); (*state)->p = NULL; (*state)->charset = NULL; free(*state); *state = NULL; } void free_state(state) struct charset_state **state; { if (CS_charset_magic != (*state)->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"free_state", "Bad magic number (charset)",0); DPRINT(Debug,60,(&Debug, "free_state((*state)=%p) ('%s'; type=%p '%s')\n", (*state), (*state)->charset->MIME_name ? (*state)->charset->MIME_name : "", (*state)->charset->charset_type, (*state)->charset->charset_type->type_name)); free_state_internal(state); } int state_ready(st) struct charset_state *st; { if (CS_charset_magic != st->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"ready_state", "Bad magic number (charset)",0); DPRINT(Debug,60,(&Debug, "ready_state(%p)=%d ('%s'; type=%p '%s')\n", st,st->p->ready, st->charset->MIME_name ? st->charset->MIME_name : "", st->charset->charset_type, st->charset->charset_type->type_name)); if (st->p->ready) { DPRINT(Debug,61,(&Debug," .... character: %C\n",st)); } return st->p->ready; } /* Unready state */ void reset_state(st, hard) struct charset_state *st; int hard; { if (CS_charset_magic != st->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"ready_state", "Bad magic number (charset)",0); DPRINT(Debug,60,(&Debug, "reset_state(%p,hard=%d) (ready=%d; '%s'; type=%p '%s')\n", st,hard, st->p->ready, st->charset->MIME_name ? st->charset->MIME_name : "", st->charset->charset_type, st->charset->charset_type->type_name)); if (hard) { st->charset->charset_type->cs_free_s_it(st); st->charset->charset_type->cs_init_s_it(st); } else { st->charset->charset_type->cs_soft_reset_s_it(st); } } int add_streambyte_to_state(st,ch) struct charset_state *st; int ch; { int res; if (CS_charset_magic != st->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"ready_state", "Bad magic number (charset)",0); DPRINT(Debug,60,(&Debug, "add_streambyte_to_state(%p) ('%s'; type=%p '%s')\n", st, st->charset->MIME_name ? st->charset->MIME_name : "", st->charset->charset_type, st->charset->charset_type->type_name)); if (st->charset == display_charset) { DPRINT(Debug,61,(&Debug, "add_streambyte_to_state -- ch=%d '%c'\n",ch,ch)); } else { DPRINT(Debug,61,(&Debug, "add_streambyte_to_state -- ch=%d\n",ch)); } res = st->charset->charset_type->cs_add_streambyte_to_s_it(st,ch); DPRINT(Debug,60,(&Debug, "add_streambyte_to_state=%d\n",res)); return res; } int state_same_char(A,B,ignore_case) struct charset_state *A; struct charset_state *B; int ignore_case; { int ret = -1; if (CS_charset_magic != A->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_same_char", "Bad magic number (A, charset)",0); if (CS_charset_magic != B->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_same_char", "Bad magic number (B, charset)",0); DPRINT(Debug,60,(&Debug, "state_same_state(%p,%p) ('%s'; type=%p '%s', '%s'; type=%p '%s')\n", A,B, A->charset->MIME_name ? A->charset->MIME_name : "", A->charset->charset_type, A->charset->charset_type->type_name, B->charset->MIME_name ? B->charset->MIME_name : "", B->charset->charset_type, B->charset->charset_type->type_name)); if (!A->p->ready) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_same_state", "State not ready (A)",0); if (!B->p->ready) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_same_state", "State not ready (B)",0); if (A->charset == B->charset) ret = A->charset->charset_type->cs_s_it_same_char(A,B,ignore_case); /* -1 indicates that unicode values should be used on comparision ... */ if (ret < 0) { int found1, found2; uint16 val1 = A->charset->charset_type->cs_give_unicode_from_s_it(A,&found1); uint16 val2 = A->charset->charset_type->cs_give_unicode_from_s_it(B,&found2); if (found1 && found2) { if (ignore_case) { /* TODO: Should lowercase ANY unicode value ... */ val1 = unicode_ch(val1,UOP_lowercase); val2 = unicode_ch(val2,UOP_lowercase); if (!val1 || !val2) { ret = 0; goto fail; } } ret = (val1 == val2); } else ret = 0; } fail: DPRINT(Debug,60,(&Debug, "state_same_char=%d\n",ret)); return ret; } int state_printable(st) struct charset_state *st; { int ret; if (CS_charset_magic != st->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_printable", "Bad magic number (A, charset)",0); DPRINT(Debug,60,(&Debug, "state_printable(%p) ('%s'; type=%p '%s')\n", st, st->charset->MIME_name ? st->charset->MIME_name : "", st->charset->charset_type, st->charset->charset_type->type_name)); if (!st->p->ready) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_printable", "State not ready",0); ret = st->charset->charset_type->cs_s_it_printable(st); if (ret < 0) { /* Use unicode values ... */ int found; uint16 val = st->charset->charset_type->cs_give_unicode_from_s_it(st,&found); if (!found) ret = 0; else if (unicode_ch(val,UOP_printable)) ret = 1; else ret = 0; } DPRINT(Debug,60,(&Debug, "state_printable=%d\n",ret)); return ret; } int state_is_onebyte(st) struct charset_state *st; { int ret; /* If character corresponds one byte on stream, returns it. * Otherwise returns 0. This is used implement ReadCh(). * It is assumend that returned character corresponds to * code characterter set (and perhaps also US-ASCII) */ if (CS_charset_magic != st->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_is_onebyte", "Bad magic number (A, charset)",0); DPRINT(Debug,60,(&Debug, "state_is_onebyte(%p) ('%s'; type=%p '%s')\n", st, st->charset->MIME_name ? st->charset->MIME_name : "", st->charset->charset_type, st->charset->charset_type->type_name)); if (!st->p->ready) panic("CHARSET STATE PANIC",__FILE__,__LINE__,"state_is_onebyte", "State not ready",0); ret = st->charset->charset_type->cs_s_it_is_onebyte(st); DPRINT(Debug,60,(&Debug, "state_is_onebyte=%d\n",ret)); return ret; } uint16 give_unicode_from_state(st) struct charset_state *st; { int found; uint16 val; if (CS_charset_magic != st->charset->magic) panic("CHARSET STATE PANIC",__FILE__,__LINE__, "give_unicode_from_state", "Bad magic number (charset)",0); DPRINT(Debug,60,(&Debug, "give_unicode_from_state(%p) ('%s'; type=%p '%s')\n", st, st->charset->MIME_name ? st->charset->MIME_name : "", st->charset->charset_type, st->charset->charset_type->type_name)); if (!st->p->ready) panic("CHARSET STATE PANIC",__FILE__,__LINE__, "give_unicode_from_state", "State not ready",0); val = st->charset->charset_type->cs_give_unicode_from_s_it(st,&found); DPRINT(Debug,60,(&Debug, "give_unicode_from_state=%d (found=%d)\n",val,found)); return val; } /* * Local Variables: * mode:c * c-basic-offset:4 * buffer-file-coding-system: iso-8859-1 * End: */