/* $Id: cs_imp.h,v 1.118 2006/04/09 07:37:05 hurtta Exp $ */

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.118 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
 *****************************************************************************/

typedef void cs_init_string P_((struct string *str));
typedef void cs_free_string P_((struct string *str));

typedef int cs_add_streambyte_to_string P_((struct string *str,int ch));

typedef void cs_add_intdata_to_string P_((struct string *str,
					  const struct string *data));

/* Does compression, recalculation and so on ... 
   so 'const' is not very const
 */
typedef void cs_check_length_string P_((const struct string *str));

typedef uint16 cs_give_unicode_from_string P_((const struct string *str,
					       int pos, int *found));

typedef void cs_add_unicodedata_to_string P_((struct string *str,
					      int len, const uint16 *data));

typedef int cs_cmp_string P_((const struct string *str1,
			      const struct string *str2));
				              
typedef unsigned char *cs_stream_from_string P_((const struct string *str, 
						 int printable,
						 screen_info_p terminal,
						 int *reslen));

typedef unsigned char *cs_streamclip_from_string P_((const struct string *str,
						     int *pos, int len,
						     screen_info_p terminal,
						     struct cs_printable_len *printable_len
						     ));

typedef int cs_can_ascii_string P_((const struct string *str));

typedef void cs_clip_from_string P_((struct string *ret,
				     const struct string *str,
				     int *pos, int len));

typedef int cs_find_pattern_from_string P_((const struct string *str,
					    const struct string *pattern,
					    int ignore_case));

typedef int cs_add_streambytes_to_string P_((struct string *str, 
					     int count, 
					     const unsigned char *data,
					     int *errors));

typedef struct  map_info * cs_find_map_type P_((const char * map_name));

typedef void cs_remove_control P_((const struct string *str));


typedef void cs_init_state P_((struct charset_state *str));
typedef void cs_free_state P_((struct charset_state *str));
typedef int cs_add_streambyte_to_state P_((struct charset_state *str, int ch));
typedef void cs_soft_reset_state P_((struct charset_state *str));

typedef void cs_add_state_to_string P_((struct string *str, 
					struct charset_state *ch));  
typedef uint16 cs_give_unicode_from_state P_((struct charset_state *st,
					      int *found));
typedef int cs_state_same_char P_((struct charset_state *A,
				   struct charset_state *B,
				   int ignore_case));
typedef int cs_state_printable P_((struct charset_state *st));
typedef int cs_state_is_onebyte P_((struct charset_state *st));

typedef int cs_set_properties P_((charset_t st));

typedef int cs_estimate_clip_string P_((const struct string *str,
					int pos, 
					int len      /* UPPER LIMIT */,
					screen_info_p terminal,
					struct cs_printable_len *printable_len));

typedef int cs_iso2022_info_set P_((struct charcode_info *new_vals,
				    struct setlist       *new_setlist,
				    int setcount));

extern struct  charset_type {
    CONST   char                  * type_name;
    cs_init_string                * cs_init_it;
    cs_free_string                * cs_free_it;
    cs_add_streambyte_to_string   * cs_add_streambyte_to_it;
    cs_add_intdata_to_string      * cs_add_intdata_to_it;
    cs_check_length_string        * cs_check_length_it;
    cs_give_unicode_from_string   * cs_give_unicode_from_it;
    cs_add_unicodedata_to_string  * cs_add_unicodedata_to_it;
    cs_cmp_string                 * cs_cmp_it;
    cs_stream_from_string         * cs_stream_from_it;
    cs_can_ascii_string           * cs_can_ascii_it;
    cs_streamclip_from_string     * cs_streamclip_from_it;
    cs_clip_from_string           * cs_clip_from_it;
    cs_find_pattern_from_string   * cs_find_pattern_from_it;
    cs_add_streambytes_to_string  * cs_add_streambytes_to_it;
    cs_find_map_type              * find_map_type;
    cs_remove_control             * cs_remove_control_it;
    cs_add_state_to_string        * cs_add_state_to_it;

    cs_init_state                 * cs_init_s_it;
    cs_free_state                 * cs_free_s_it; 
    cs_add_streambyte_to_state    * cs_add_streambyte_to_s_it;
    cs_soft_reset_state           * cs_soft_reset_s_it;
    cs_give_unicode_from_state    * cs_give_unicode_from_s_it;
    cs_state_same_char            * cs_s_it_same_char;
    cs_state_printable            * cs_s_it_printable;
    cs_state_is_onebyte           * cs_s_it_is_onebyte;
    cs_set_properties             * cs_it_properties;
    cs_estimate_clip_string       * cs_estimate_clip_it;
    cs_iso2022_info_set           * cs_iso2022_info_set_it;

    struct  charset_type    * next_type;
			    
} * cs_first_type;


#if defined(WCHAR) && defined(__STDC_ISO_10646__)
extern void change_system_charset P_((void));
extern void change_system_charset_1 P_((void));
#endif 



extern unsigned char map_fallback_rev P_((unsigned int val, int *found));
extern uint16 map_fallback P_((unsigned int c));

#ifdef WCHAR
#include <wctype.h>
#include <wchar.h>

extern uint16 map_wfallback P_((wint_t c));
extern wchar_t map_wfallback_rev P_((unsigned int val, int *found));
#endif



#define CS_str_magic            0xF300

struct str_private_data {
    unsigned short       magic;          /* CS_str_magic    */
    int len;
    struct charset_state *state;
    int private_flag;
    union {
	unsigned char   *bytes;
	uint16          *words;
	struct mb_data  *data;            /* NOT VECTOR, just one structure */
#ifdef WCHAR
        wchar_t         *wchars;
#endif
    } a;
    char                *lang;
};

struct state_utf8 {
    unsigned char  bytes;
    unsigned char  idx;
    long           value;
};

struct state_utf7 {
    unsigned char  encoded;
    unsigned char  bitcount;
    unsigned long  bitval;
    long           value;
};

#ifdef WCHAR
#define STATE_WCHAR_magic       0xF305
 
struct state_wchar {
    unsigned short magic;     /* STATE_WCHAR_magic */

    mbstate_t  s;
    wchar_t    value;
};
#endif

struct state_private_data {
    unsigned char ready;
    union {
	unsigned char      byte;
	struct state_utf8  utf8;
	struct state_utf7  utf7;
#ifdef WCHAR
        struct state_wchar  wchar;
#endif
	struct state_generic_1   *g1;
	struct state_iso2022     *iso2022;
    } a;
};

extern struct charset_type cs_ascii;
extern struct charset_type cs_unknown;
extern struct charset_type cs_onebyte;
extern struct charset_type cs_iso646;
extern struct charset_type cs_euc;
extern struct charset_type cs_utf8;
extern struct charset_type cs_utf7;
extern struct charset_type cs_imap;
extern struct charset_type cs_iso2022; 

typedef void map_init_map P_((struct  map_info *map));

#define MAPPING_NONE         0xFFFF
#define MAP_REV_MAP_DIV      511        /* Large enough? */

struct map_ascii_upper {
    uint16        map_ascii_upper[128];
    unsigned char map_ascii_rev[MAP_REV_MAP_DIV];
};

struct bytemap {
    uint16        map[256];
    unsigned char map_bytemap_rev[MAP_REV_MAP_DIV];
};

struct utfmap {
    int elem_count;
    struct utfelem * elems;  
};

#define  ISO2022_SET_COUNT           10

struct iso2022_m {
    /* Indexes to iso2022_map_list[] */
    int                        setlist[ISO2022_SET_COUNT]; 
};

struct iso646_m {
    uint16                     iso646[12];
};

typedef uint16 cs_map_bindataXX P_((unsigned int ch,
				    struct  map_info *map,
				    int *found));


typedef unsigned char cs_map_bindataXX_rev P_((struct map_info *map,
					       unsigned int val,
					       int *found));

struct bindata_ops {
    cs_map_bindataXX          * map_it;
    cs_map_bindataXX_rev      * map_rev_it;
};


extern struct  map_info {
    struct charset_type *map_type;
    char                *map_name;
    int                 map_initialized;
    map_init_map        *map_init_it;
    union {
	void                       * dummy;
	struct map_ascii_upper     * ascii;	
	struct bytemap             * bytemap;
	struct iso646_m            * iso646;
	struct utfmap              * utfmap;
	struct iso2022_m           * setlist;
    } b;
    union {
	void                       * dummy;
	struct bindata_map         * bindata;
    } c;

    union {
	void                       * dummy;
	struct bindata_ops         * binary_ops;
    } d;

} map_ascii, map_latin1, map_koi8r, map_cp1251, map_invariant, map_utf8, 
	map_utf7, map_cp1252, map_koi8u, map_885915,
	map_ISO2022_ascii, map_ISO2022_ascii_latin1,
	map_EUC_ascii,     map_EUC_ascii_latin1;

#define CS_charset_magic	0xF306


extern void free_state_internal P_((struct charset_state **state));

typedef FILE *charmap_copy_callback P_((const char *name, 
					const char *pathname));

extern void set_charmap_copy_callback P_((charmap_copy_callback *cb));

enum iso2022_settype { iso2022_other,
		       iso2022_94,
		       iso2022_96,
		       iso2022_94x94,
		       iso2022_96x96      /* Perhaps not exists */
};

enum iso2022_bank { bank_unspecified = -1, 
		    bank_G0 = 0, 
		    bank_G1 = 1, 
		    bank_G2 = 2, 
		    bank_G3 = 3,
		    ISO2022_BANK_NUM };

#define ISO2022_SETID_LEN     4

extern struct iso2022_setid { 
    enum iso2022_bank         bank;
    enum iso2022_settype      type;
    unsigned char             bytes[ISO2022_SETID_LEN];
} return_to_iso2022;
	
extern struct setlist {
    int initial_bank[ISO2022_BANK_NUM];
    struct iso2022_setid * sets[ISO2022_SET_COUNT];
    enum iso2022_bank initial_L;
    enum iso2022_bank initial_R;
} sets_iso_8859_X[], 
    set_utf8, set_latin7, set_latin8, set_latin9, set_iso885916,
    set_ISO2022KR, set_EUCKR, 
    set_ISO2022JP, set_ISO646JP, set_ISO2022JP2, set_EUCJP,
    set_ISO2022CN, set_ISO2022CNEXT, set_EUCCN, set_koi8e,
    set_iso_ir_2, set_iso_ir_4, set_iso_ir_8_1, set_iso_ir_8_2,
    set_iso_ir_9_1, set_iso_ir_9_2, set_iso_ir_10, set_iso_ir_11,
    set_iso_ir_149, set_iso_ir_13, set_iso_ir_15, set_iso_ir_16,
    set_iso_ir_17, set_iso_ir_18, set_iso_ir_19, set_iso_ir_21,
    set_iso_ir_25, set_iso_ir_27, set_iso_ir_37, set_iso_ir_42,
    set_iso_ir_47, set_iso_ir_49, set_iso_ir_50, set_iso_ir_51,
    set_iso_ir_54, set_iso_ir_55, set_iso_ir_57, set_iso_ir_58,
    set_iso_ir_60, set_iso_ir_61, set_iso_ir_69, set_iso_ir_70,
    set_iso_ir_84, set_iso_ir_85, set_iso_ir_86, set_iso_ir_87,
    set_iso_ir_89, set_iso_ir_90, set_iso_ir_91, set_iso_ir_92,
    set_iso_ir_93, set_iso_ir_94, set_iso_ir_95, set_iso_ir_96,
    set_iso_ir_98, set_iso_ir_99, set_iso_ir_102, set_iso_ir_103,
    set_iso_ir_121, set_iso_ir_122, set_iso_ir_123,
    set_iso_ir_128, set_iso_ir_139, set_iso_ir_141,
    set_iso_ir_142, set_iso_ir_143, set_iso_ir_146,
    set_iso_ir_147, set_iso_ir_150, set_iso_ir_151,
    set_iso_ir_152, set_iso_ir_153, set_iso_ir_154,
    set_iso_ir_155, set_iso_ir_158, set_iso_ir_159;
    

extern void iso2022_clear_setlist P_((struct setlist *X));

extern struct iso2022_setid * CONST ASCII_BANK;
extern struct iso2022_setid * CONST LATIN1_BANK;

/* May be called from signal handler -- on that situation use
   buffer specified as argument
   -- otherwise result is malloced
*/
extern char * iso2022_setid_stream P_((const struct iso2022_setid  c,
				       char *buffer, int size
				       ));
/* Special return values:    0    Not a setid 
 *                          -1    Incomplete setid
 *                          > 0   len of setid
 */
extern int eat_iso2022_setid P_((struct iso2022_setid *result, 
				 const unsigned char *buffer, int len));


extern char * lock_shift P_((int r, enum iso2022_bank bank,
			     char *buffer, int size));

enum shift_mode { lock_shift_left  = 0,  lock_shift_right = 1,
		  single_shift = 2 /* Normally left, but EUC uses rigth bank */		  
};
	   

/* Special return values:    0    Not a bank switch
 *                          -1    Incomplete switch
 *                          > 0   len of switch
 */
extern int eat_iso2022_bank_switch P_((enum iso2022_bank *bank,
				       enum shift_mode *left_right,
				       CONST unsigned char *buffer,
				       int len));

extern int parse_iso2022_specification P_((const char     *param,
					   const char     *value,
					   int            *count,
					   struct setlist *list));
extern struct setlist *loc_setlist P_((const struct setlist l));
extern void print_setlist(FILE *f,struct setlist *l);

extern void dump_map_info P_((FILE *f,struct charcode_info *info));
extern int parse_gen_spec P_((const char *val, 
			      unsigned char *bytes,
			      int size));
extern char * iso2022_codestr P_((unsigned char *bytes, int size));

extern char * terminal_charset_post_init P_((screen_info_p    terminal_info,
					     struct setlist * iso2022_info));

enum unicode_op { UOP_none, UOP_lowercase, UOP_noctrl, 
		  UOP_printable, UOP_space };

/* Returns 0 if char not OK, otherwise char or converted char */
extern uint16 unicode_ch P_((unsigned int ch, enum unicode_op op)); 

/* Returns 1 converted / processed */
extern int compress_unicode P_((uint16  *words, int *len));

extern struct charset_state * new_state_1 P_((charset_t set));
extern FILE * open_mapname P_((const char *name, char **fn));
extern int is_on_mapdir P_((CONST char *name));

extern struct charcode_info precompiled_sets[];
extern CONST int precompiled_size;
extern CONST charset_t INVARIANT_SET;

extern struct iso2022_map_list {
    struct iso2022_setid    *setid;
    struct iso2022_mapinfo  *map;
    enum map_list_mode      mode;
}        *  iso2022_map_list;
extern  struct iso2022_map_list INITIAL_iso2022_map_list[];
extern  int iso2022_map_list_count;

#define ISO2022_MAP_LIST_ALLOCED    (iso2022_map_list !=  INITIAL_iso2022_map_list)

extern struct iso2022_mapinfo latin_iso2022_map_ascii;
extern struct  iso2022_mapinfo latin_iso2022_map_latin1;

#define     PF_IS_BUILTIN            0x400
#define     PF_type_mask            0xF000
#define     PF_ascii                0x1000
#define     PF_bytemap              0x2000

extern int iso2022_parseflag_ok P_((const char * flag));
extern struct iso2022_mapinfo * read_iso2022_map P_((const char *filaname,
						     enum iso2022_settype type,
						     int code,
						     const char *flag
						     ));
extern struct iso2022_mapinfo * make_iso2022_map P_((struct  map_info 
						     *builtin_map,
						     enum iso2022_settype type,
						     int code,
						     CONST char *flag));

extern CONST char * iso2022_mapname P_((struct iso2022_mapinfo *map));
extern CONST char * iso2022_mapflags P_((struct iso2022_mapinfo *map));

/* l1 is first intresting value on line, l2 is unicode  */
typedef int set_map_callmap P_((const char *name,
				struct map_info *map_info,
				long l1,
				long l2,
				const char *fn
				));

enum  field_type {   
    val_ignore,  val_byte,  val_iso2022_mb, val_unicode, val_comment };

void read_map_format_a P_((const char *name, struct map_info *map_info,
			   struct iso2022_mapinfo *iso2022_map_info,
			   FILE *F, 
			   set_map_callmap * pass_caller,
			   int field_count,
			   enum  field_type  *vector,
			   const char *fn
));

extern uint16 ISO2022_1byte_to_word P_((int ch1));
extern uint16 ISO2022_2byte_to_word P_((int ch1, int ch2));


/* -1 == not found, otherwise index to iso2022_map_list[] */
extern int find_iso2022_map_spec P_((char *name));


/* -1 == not found, otherwise index to iso2022_map_list[] 
                    index must exist on index_list
*/
extern int give_iso2022_index P_((int *index_list, int index_count,
				  struct iso2022_setid * set_text));


/* 0 == not found, 1 == found */
extern int map_ISO2022_word_to_unicode P_((unsigned word,
					   enum iso2022_settype type,
					   int iso2022_map_index,
					   uint16  *ret));


extern uint16 cs_unicode_bytemap_helper_1 P_((unsigned int ch,
					      struct  map_info *map, 
					      int *found));
extern unsigned char cs_map_bytemap_rev P_((struct map_info *map,
					    unsigned int val, int *found)); 


extern uint16 cs_unicode_ascii_helper_1 P_((unsigned int ch,
					    struct  map_info *map, 
					    int *found));
extern unsigned char cs_map_ascii_rev P_((struct map_info *map,
					  unsigned int val,
					  int *found)); 

/* 0 == not found, 1 == found */
extern int  map_unicode_to_ISO2022_word_1 P_((unsigned unicode,
					      enum iso2022_settype * type,
					      int iso2022_map_index,
					      uint16               * iso2022_word));

extern void fill_iso2022_map_setlist_bytes P_((int iso2022_map_index,
					       enum iso2022_settype type,
					       unsigned char *bytes,
					       int bytes_size));

extern int same_setid P_((const struct iso2022_setid A,
			  const struct iso2022_setid B));

extern int cs_info_set_scan P_((struct charcode_info *new_vals,
				struct setlist       *new_setlist,
				int setcount,
				int *ptr_94, int *ptr_96,
				int banks[ISO2022_BANK_NUM]));

/* -1 == no space, 0 == not available, > 0 result len */
extern int do_single_shift P_((unsigned char buffer[], 
			       int size, 
			       enum iso2022_bank bank,
			       int is_upper));

extern int iso2022_give_setpos P_((struct iso2022_setid   *ID, 
				   screen_info_p  output_state));
extern void iso2022_merge_old_info P_((struct setlist *new_setlist,
				       int setcount,
				       struct setlist *old_info));
/* bindata.c */

extern struct bindata_mapped_data * default_bindata P_((void));

/* cs_binary.c */

#ifndef ASCII_CTYPE
extern void cs_remove_control_locale P_((const struct string *str,
					 unsigned int repl));
extern unsigned char *cs_stream_from_locale P_((const struct string *str,
						int *reslen));
extern int cs_s_locale_printable P_((struct charset_state *st));
extern unsigned char *cs_streamclip_from_locale P_((const struct string *str,
						    int *pos, int len));
extern int cs_find_pattern_from_locale P_((const struct string *str,
					   const struct string *pattern));

#endif

/* ------------------------------------------------------------------ */

struct charset_map_item {
    char       *match;
    int        is_def;   /* 0 == mapping, 1 == defination, 2 == alias */
    charset_t  charset;
};

extern void free_charset_map P_((struct charset_map_item **map));

extern struct charset_alias {
       char *                name;
       charset_t             set;
} * charset_alias_list;
extern int charset_alias_count;

#define MIBenum_class_divide 1000

extern struct MIBenum_class {
    struct charcode_info ** MIBenum_array;
    int                     MIBenum_array_len;
} MIBenum_CLASS[];
extern CONST int MIBenum_CLASS_len;

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1