#include <wchar.h>
/* 7-bit ASCII maps to bottom 128 characters of UCS */
struct asciimap_t
{
wchar_t ucs;
char ascii;
} ascii437_to_ucs[128] =
{
{ 0x0092, 0x9f },
{ 0x00A0, 0xff },
{ 0x00A1, 0xad },
{ 0x00A2, 0xbd },
{ 0x00A3, 0x9c },
{ 0x00A4, 0xcf },
{ 0x00A5, 0xbe },
{ 0x00A6, 0xdd },
{ 0x00A7, 0xf5 },
{ 0x00A8, 0xf9 },
{ 0x00A9, 0xb8 },
{ 0x00AA, 0xa6 },
{ 0x00AB, 0xae },
{ 0x00AC, 0xaa },
{ 0x00AD, 0xf0 },
{ 0x00AE, 0xa9 },
{ 0x00AF, 0xee },
{ 0x00B0, 0xf8 },
{ 0x00B1, 0xf1 },
{ 0x00B2, 0xfd },
{ 0x00B3, 0xfc },
{ 0x00B4, 0xef },
{ 0x00B5, 0xe6 },
{ 0x00B6, 0xf4 },
{ 0x00B7, 0xfa },
{ 0x00B8, 0xf7 },
{ 0x00B9, 0xfb },
{ 0x00BA, 0xa7 },
{ 0x00BB, 0xaf },
{ 0x00BC, 0xac },
{ 0x00BD, 0xab },
{ 0x00BE, 0xf3 },
{ 0x00BF, 0xa8 },
{ 0x00C0, 0xb7 },
{ 0x00C1, 0xb5 },
{ 0x00C2, 0xb6 },
{ 0x00C3, 0xc7 },
{ 0x00C4, 0x8e },
{ 0x00C5, 0x8f },
{ 0x00C6, 0x92 },
{ 0x00C7, 0x80 },
{ 0x00C8, 0xd4 },
{ 0x00C9, 0x90 },
{ 0x00CA, 0xd2 },
{ 0x00CB, 0xd3 },
{ 0x00CC, 0xde },
{ 0x00CD, 0xd6 },
{ 0x00CE, 0xd7 },
{ 0x00CF, 0xd8 },
{ 0x00D0, 0xd1 },
{ 0x00D1, 0xa5 },
{ 0x00D2, 0xe3 },
{ 0x00D3, 0xe0 },
{ 0x00D4, 0xe2 },
{ 0x00D5, 0xe5 },
{ 0x00D6, 0x99 },
{ 0x00D7, 0x9e },
{ 0x00D8, 0x9d },
{ 0x00D9, 0xeb },
{ 0x00DA, 0xe9 },
{ 0x00DB, 0xea },
{ 0x00DC, 0x9a },
{ 0x00DD, 0xed },
{ 0x00DE, 0xe8 },
{ 0x00DF, 0xe1 },
{ 0x00E0, 0x85 },
{ 0x00E0, 0xa1 },
{ 0x00E1, 0xa0 },
{ 0x00E2, 0x83 },
{ 0x00E3, 0xc6 },
{ 0x00E4, 0x84 },
{ 0x00E5, 0x86 },
{ 0x00E6, 0x91 },
{ 0x00E7, 0x87 },
{ 0x00E8, 0x8a },
{ 0x00E9, 0x82 },
{ 0x00EA, 0x88 },
{ 0x00EB, 0x89 },
{ 0x00EC, 0x8d },
{ 0x00EE, 0x8c },
{ 0x00EF, 0x8b },
{ 0x00F0, 0xd0 },
{ 0x00F1, 0xa4 },
{ 0x00F2, 0x95 },
{ 0x00F3, 0xa2 },
{ 0x00F4, 0x93 },
{ 0x00F5, 0xe4 },
{ 0x00F6, 0x94 },
{ 0x00F7, 0xf6 },
{ 0x00F8, 0x9b },
{ 0x00F9, 0x97 },
{ 0x00FA, 0xa3 },
{ 0x00FB, 0x96 },
{ 0x00FC, 0x81 },
{ 0x00FD, 0xec },
{ 0x00FE, 0xe7 },
{ 0x00FF, 0x98 },
{ 0x0131, 0xd5 },
{ 0x2017, 0xf2 },
{ 0x20A0, 0xfe },
{ 0x2500, 0xc4 },
{ 0x2502, 0xb3 },
{ 0x250C, 0xda },
{ 0x2510, 0xbf },
{ 0x2514, 0xc0 },
{ 0x2518, 0xd9 },
{ 0x251C, 0xc3 },
{ 0x2524, 0xb4 },
{ 0x252C, 0xc2 },
{ 0x2534, 0xc1 },
{ 0x253C, 0xc5 },
{ 0x2550, 0xcd },
{ 0x2551, 0xba },
{ 0x2554, 0xc9 },
{ 0x2557, 0xbb },
{ 0x255A, 0xc8 },
{ 0x255D, 0xbc },
{ 0x2560, 0xcc },
{ 0x2563, 0xb9 },
{ 0x2566, 0xcb },
{ 0x2569, 0xca },
{ 0x256C, 0xce },
{ 0x2580, 0xdf },
{ 0x2584, 0xdc },
{ 0x2588, 0xdb },
{ 0x2591, 0xb0 },
{ 0x2592, 0xb1 },
{ 0x2593, 0xb2 },
};
void *
bsearch(const void *key, const void *base0, size_t nelem,
size_t size, int (*cmp)(const void *ck, const void *ce))
{
char *base = (char*) base0;
int lim, cmpval;
void *p;
for (lim = nelem; lim != 0; lim >>= 1)
{
p = base + (lim >> 1) * size;
cmpval = (*cmp)(key, p);
if (cmpval == 0)
return p;
if (cmpval > 0)
{ /* key > p: move right */
base = (char *)p + size;
lim--;
} /*,lse move left */
}
return 0;
}
static int asciimap_search(const void* ck, const void* ce)
{
const wchar_t* key = (const wchar_t*) ck;
const struct asciimap_t* elem = (const struct asciimap_t*) ce;
return *key - elem->ucs;
}
size_t wcstombs(char *mbstr, const wchar_t *wcstr, size_t count)
{
struct asciimap_t* map;
int i;
for (i = 0; *wcstr && i < count; i++)
{
if (*wcstr < 128)
*mbstr = (unsigned char) *wcstr;
else
{
map = (struct asciimap_t*) bsearch(wcstr, ascii437_to_ucs,
sizeof(ascii437_to_ucs) / sizeof(ascii437_to_ucs[0]),
sizeof(struct asciimap_t), asciimap_search);
if (map)
*mbstr = map->ascii;
else
*mbstr = '?';
}
wcstr++;
mbstr++;
}
*mbstr = 0;
return i;
}