static char rcsid[] = "@(#)$Id: cs_wfallback.c,v 1.4 2006/04/09 07:37:08 hurtta Exp $";

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

#include "headers.h"
#include "s_me.h"
#include "cs_imp.h"

#ifdef __STDC_ISO_10646__

uint16 map_wfallback(c)
     wint_t c;
{
    if (c >= 0 && c <= 0xFFFF)
	return c;

    return MAPPING_NONE;	
}

wchar_t map_wfallback_rev(val, found)
     unsigned int val;
     int *found;
{
    *found = 1;
    return val;
}

#else

DEBUG_VAR(Debug,__FILE__,"charset");

static struct wfallback {
    wchar_t c;
    uint16 c1;
} fallback_table[] = {
    { L'\r', 0x000D },
    { L'\n', 0x000A },
    { L'\t', 0x0009 },
    /* This table defines mapping between charset used in string
     * constants and unicode. This includes only characters, which
     * are likely to be existed in all sets.
     */  
    { L' ', 0x0020        /* ;*;SPACE;;; */            },
    { L'!', 0x0021        /* ;*;EXCLAMATION MARK;;; */ },
    { L'"', 0x0022        /* ;*;QUOTATION MARK;;; */   },
    { L'%', 0x0025        /* ;*;PERCENT SIGN;;; */     },
    { L'&', 0x0026        /* ;*;AMPERSAND;;; */        },
    { L'(', 0x0028        /* ;*;LEFT PARENTHESIS;;OPENING PARENTHESIS; */ },
    { L')', 0x0029        /* ;*;RIGHT PARENTHESIS;;CLOSING PARENTHESIS; */ },
    { L'*', 0x002A        /* ;*;ASTERISK;;; */  },
    { L'+', 0x002B        /* ;*;PLUS SIGN;;; */ },
    { L',', 0x002C        /* ;*;COMMA;;;  */ },
    { L'-', 0x002D        /* ;*;HYPHEN-MINUS;;; */ },
    { L'.', 0x002E        /* ;*;FULL STOP;;PERIOD; */ },
    { L'/', 0x002F        /* ;*;SOLIDUS;;SLASH; */ },
    { L'0', 0x0030        /* ;*;DIGIT ZERO;;; */ },
    { L'1', 0x0031        /* ;*;DIGIT ONE;;; */ },
    { L'2', 0x0032        /* ;*;DIGIT TWO;;; */ },
    { L'3', 0x0033        /* ;*;DIGIT THREE;;; */ },
    { L'4', 0x0034        /* ;*;DIGIT FOUR;;; */ },
    { L'5', 0x0035        /* ;*;DIGIT FIVE;;; */ },
    { L'6', 0x0036        /* ;*;DIGIT SIX;;; */ },
    { L'7', 0x0037        /* ;*;DIGIT SEVEN;;; */ },
    { L'8', 0x0038        /* ;*;DIGIT EIGHT;;; */ },
    { L'9', 0x0039        /* ;*;DIGIT NINE;;; */ },
    { L':', 0x003A        /* ;*;COLON;;; */ },
    { L';', 0x003B        /* ;*;SEMICOLON;;; */ },
    { L'<', 0x003C        /* ;*;LESS-THAN SIGN;;; */ },
    { L'=', 0x003D        /* ;*;EQUALS SIGN;;; */ },
    { L'>', 0x003E        /* ;*;GREATER-THAN SIGN;;; */ },
    { L'?', 0x003F        /* ;*;QUESTION MARK;;; */ },
    { L'A', 0x0041        /* ;*;LATIN CAPITAL LETTER A;;; */ },
    { L'B', 0x0042        /* ;*;LATIN CAPITAL LETTER B;;; */ },
    { L'C', 0x0043        /* ;*;LATIN CAPITAL LETTER C;;; */ },
    { L'D', 0x0044        /* ;*;LATIN CAPITAL LETTER D;;; */ },
    { L'E', 0x0045        /* ;*;LATIN CAPITAL LETTER E;;; */ },
    { L'F', 0x0046        /* ;*;LATIN CAPITAL LETTER F;;; */ },
    { L'G', 0x0047        /* ;*;LATIN CAPITAL LETTER G;;; */ },
    { L'H', 0x0048        /* ;*;LATIN CAPITAL LETTER H;;; */ },
    { L'I', 0x0049        /* ;*;LATIN CAPITAL LETTER I;;; */ },
    { L'J', 0x004A        /* ;*;LATIN CAPITAL LETTER J;;; */ },
    { L'K', 0x004B        /* ;*;LATIN CAPITAL LETTER K;;; */ },
    { L'L', 0x004C        /* ;*;LATIN CAPITAL LETTER L;;; */ },
    { L'M', 0x004D        /* ;*;LATIN CAPITAL LETTER M;;; */ },
    { L'N', 0x004E        /* ;*;LATIN CAPITAL LETTER N;;; */ },
    { L'O', 0x004F        /* ;*;LATIN CAPITAL LETTER O;;; */ },
    { L'P', 0x0050        /* ;*;LATIN CAPITAL LETTER P;;; */ },
    { L'Q', 0x0051        /* ;*;LATIN CAPITAL LETTER Q;;; */ },
    { L'R', 0x0052        /* ;*;LATIN CAPITAL LETTER R;;; */ },
    { L'S', 0x0053        /* ;*;LATIN CAPITAL LETTER S;;; */ },
    { L'T', 0x0054        /* ;*;LATIN CAPITAL LETTER T;;; */ },
    { L'U', 0x0055        /* ;*;LATIN CAPITAL LETTER U;;; */ },
    { L'V', 0x0056        /* ;*;LATIN CAPITAL LETTER V;;; */ },
    { L'W', 0x0057        /* ;*;LATIN CAPITAL LETTER W;;; */ },
    { L'X', 0x0058        /* ;*;LATIN CAPITAL LETTER X;;; */ },
    { L'Y', 0x0059        /* ;*;LATIN CAPITAL LETTER Y;;; */ },
    { L'Z', 0x005A        /* ;*;LATIN CAPITAL LETTER Z;;; */ },
    
    { L'a', 0x0061        /* ;*;LATIN SMALL LETTER A;;; */ },
    { L'b', 0x0062        /* ;*;LATIN SMALL LETTER B;;; */ },
    { L'c', 0x0063        /* ;*;LATIN SMALL LETTER C;;; */ },
    { L'd', 0x0064        /* ;*;LATIN SMALL LETTER D;;; */ },
    { L'e', 0x0065        /* ;*;LATIN SMALL LETTER E;;; */ },
    { L'f', 0x0066        /* ;*;LATIN SMALL LETTER F;;; */ },
    { L'g', 0x0067        /* ;*;LATIN SMALL LETTER G;;; */ },
    { L'h', 0x0068        /* ;*;LATIN SMALL LETTER H;;; */ },
    { L'i', 0x0069        /* ;*;LATIN SMALL LETTER I;;; */ },
    { L'j', 0x006A        /* ;*;LATIN SMALL LETTER J;;; */ },
    { L'k', 0x006B        /* ;*;LATIN SMALL LETTER K;;; */ },
    { L'l', 0x006C        /* ;*;LATIN SMALL LETTER L;;; */ },
    { L'm', 0x006D        /* ;*;LATIN SMALL LETTER M;;; */ },
    { L'n', 0x006E        /* ;*;LATIN SMALL LETTER N;;; */ },
    { L'o', 0x006F        /* ;*;LATIN SMALL LETTER O;;; */ },
    { L'p', 0x0070        /* ;*;LATIN SMALL LETTER P;;; */ },
    { L'q', 0x0071        /* ;*;LATIN SMALL LETTER Q;;; */ },
    { L'r', 0x0072        /* ;*;LATIN SMALL LETTER R;;; */ },
    { L's', 0x0073        /* ;*;LATIN SMALL LETTER S;;; */ },
    { L't', 0x0074        /* ;*;LATIN SMALL LETTER T;;; */ },
    { L'u', 0x0075        /* ;*;LATIN SMALL LETTER U;;; */ },
    { L'v', 0x0076        /* ;*;LATIN SMALL LETTER V;;; */ },
    { L'w', 0x0077        /* ;*;LATIN SMALL LETTER W;;; */ },
    { L'x', 0x0078        /* ;*;LATIN SMALL LETTER X;;; */ },
    { L'y', 0x0079        /* ;*;LATIN SMALL LETTER Y;;; */ },
    { L'z', 0x007A        /* ;*;LATIN SMALL LETTER Z;;; */ }
};

struct wfallback *wchar2unicode_hash[MAP_REV_MAP_DIV], 
                 *unicode2wchar_hash[MAP_REV_MAP_DIV];
    

static int initialized = 0;

static void init_fallback P_((void));
static void init_fallback() {
    int i;

    int col1 = 0, col2 = 0;  

    for (i = 0; i < MAP_REV_MAP_DIV; i++) {
	wchar2unicode_hash[i]  = NULL;
	unicode2wchar_hash[i]  = NULL;
    }

    for (i = 0; i < sizeof fallback_table / sizeof fallback_table[0]; i++) {
	int x1 = fallback_table[i].c % MAP_REV_MAP_DIV;
	int x2 = fallback_table[i].c1 % MAP_REV_MAP_DIV;

	if (wchar2unicode_hash[x1])
	    col1++;
        else
	    wchar2unicode_hash[x1] = & (fallback_table[i]);

	if (unicode2wchar_hash[x1])
	    col2++;
        else
	    unicode2wchar_hash[x1] = & (fallback_table[i]);

    }

    DPRINT(Debug,4,(&Debug, 
		    "Wide fallback map initialized: wchar2unicode_hash %d collisions, unicode2wchar_hash %d collisions\n",
		    col1,col2));

    initialized = 1;
}

uint16 map_wfallback(c)
     wint_t c;
{
    int x,i;

    if (!initialized)
	init_fallback();

    x = c % MAP_REV_MAP_DIV;

    if (!wchar2unicode_hash[x]) 
	return MAPPING_NONE;

    if (wchar2unicode_hash[x]->c == c)
	return wchar2unicode_hash[x]->c1;

    for (i = 0; i < sizeof fallback_table / sizeof fallback_table[0]; i++) {
	if (fallback_table[i].c == c) {
	    return fallback_table[i].c1;
	}
    }
    return MAPPING_NONE;
}

wchar_t map_wfallback_rev(val, found)
     unsigned int val;
     int *found;
{
    int x,i;

    if (!initialized)
	init_fallback();

    x = val % MAP_REV_MAP_DIV;

    if (! unicode2wchar_hash[x]) {
	*found = 0;

	return L'?';
    }

    if (unicode2wchar_hash[x]->c1 == val) {
	*found = 1;
	return unicode2wchar_hash[x]->c;
    }

    for (i = 0; i < sizeof fallback_table / sizeof fallback_table[0]; i++) {
	if (fallback_table[i].c1 == val) {
	    *found = 1;
	    return fallback_table[i].c;
	}
    }

    *found = 0;
    return L'?';  /* Not found */
}

#endif

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


syntax highlighted by Code2HTML, v. 0.9.1