Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP 3.0.18-ja-3 patch for modern linux
--- i18n_ja_jp_filter.c.orig 2000-04-04 09:18:32.000000000 +0900
+++ i18n_ja_jp_filter.c 2014-04-08 18:07:28.723051000 +0900
@@ -97,5392 +97,7 @@
/* unicode support by */
#define UNDEFCHAR_JIS 0x2126
#define UNDEFCHAR_UNICODE 0x30FB
-extern const unsigned short u2jtable[];
-extern const unsigned short j2utable[];
-extern const int u2jtable_size;
-extern const int j2utable_size;
-
-
-/* language description structure */
-const char *mbfl_language_ja_jp_aliases[] = {"japanese", NULL};
-mbfl_language mbfl_language_unknown = {mbfl_no_language_unknown, "unknown", NULL};
-mbfl_language mbfl_language_universal = {mbfl_no_language_universal, "universal", NULL};
-mbfl_language mbfl_language_en_us = {mbfl_no_language_en_us, "en_US", NULL};
-mbfl_language mbfl_language_ja_jp = {mbfl_no_language_ja_jp, "ja_JP", &mbfl_language_ja_jp_aliases};
-
-mbfl_language_ptr mbfl_language_ptr_table[] = {
- &mbfl_language_unknown,
- &mbfl_language_universal,
- &mbfl_language_en_us,
- &mbfl_language_ja_jp,
- NULL
-};
-
-/* encoding description structure */
-const char *mbfl_encoding_auto_aliases[] = {"unknown", NULL};
-const char *mbfl_encoding_pass_aliases[] = {"none", NULL};
-const char *mbfl_encoding_qprint_aliases[] = {"qprint", NULL};
-const char *mbfl_encoding_ja_jp_euc_aliases[] = {"EUC", "EUC_JP", "eucJP", "x-euc-jp", NULL};
-const char *mbfl_encoding_ja_jp_sjis_aliases[] = {"x-sjis", "MS_Kanji", NULL};
-mbfl_encoding mbfl_encoding_auto = {mbfl_no_encoding_auto, "auto", &mbfl_encoding_auto_aliases, "", &mbfl_language_unknown};
-mbfl_encoding mbfl_encoding_pass = {mbfl_no_encoding_pass, "pass", &mbfl_encoding_pass_aliases, "", &mbfl_language_unknown};
-mbfl_encoding mbfl_encoding_wchar = {mbfl_no_encoding_wchar, "wchar", NULL, "", &mbfl_language_unknown};
-mbfl_encoding mbfl_encoding_base64 = {mbfl_no_encoding_base64, "BASE64", NULL, "", &mbfl_language_unknown};
-mbfl_encoding mbfl_encoding_qprint = {mbfl_no_encoding_qprint, "Quoted-Printable", &mbfl_encoding_qprint_aliases, "", &mbfl_language_unknown};
-mbfl_encoding mbfl_encoding_utf8 = {mbfl_no_encoding_utf8, "UTF-8", NULL, "UTF-8", &mbfl_language_universal};
-mbfl_encoding mbfl_encoding_ucs = {mbfl_no_encoding_ucs, "UCS", NULL, "", &mbfl_language_universal};
-mbfl_encoding mbfl_encoding_en_us_ascii = {mbfl_no_encoding_en_us_ascii, "ASCII", NULL, "US-ASCII", &mbfl_language_en_us};
-mbfl_encoding mbfl_encoding_ja_jp_euc = {mbfl_no_encoding_ja_jp_euc, "EUC-JP", &mbfl_encoding_ja_jp_euc_aliases, "EUC-JP", &mbfl_language_ja_jp};
-mbfl_encoding mbfl_encoding_ja_jp_sjis = {mbfl_no_encoding_ja_jp_sjis, "SJIS", &mbfl_encoding_ja_jp_sjis_aliases, "Shift_JIS", &mbfl_language_ja_jp};
-mbfl_encoding mbfl_encoding_ja_jp_jis = {mbfl_no_encoding_ja_jp_jis, "JIS", NULL, "ISO-2022-JP", &mbfl_language_ja_jp};
-
-mbfl_encoding_ptr mbfl_encoding_ptr_table[] = {
- &mbfl_encoding_auto,
- &mbfl_encoding_pass,
- &mbfl_encoding_wchar,
- &mbfl_encoding_base64,
- &mbfl_encoding_qprint,
- &mbfl_encoding_utf8,
- &mbfl_encoding_ucs,
- &mbfl_encoding_en_us_ascii,
- &mbfl_encoding_ja_jp_euc,
- &mbfl_encoding_ja_jp_sjis,
- &mbfl_encoding_ja_jp_jis,
- NULL
-};
-
-mbfl_encoding_ptr
-mbfl_name2encoding(const char *name)
-{
- mbfl_encoding_ptr penc;
- int i, j;
-
- if (name == NULL) {
- return NULL;
- }
-
- i = 0;
- while((penc = mbfl_encoding_ptr_table[i++]) != NULL){
- if(strcasecmp(penc->name, name) == 0) {
- return penc;
- }
- }
-
- /* serch MIME charset name */
- i = 0;
- while((penc = mbfl_encoding_ptr_table[i++]) != NULL){
- if(strcasecmp(penc->mime_name, name) == 0) {
- return penc;
- }
- }
-
- /* serch aliases */
- i = 0;
- while((penc = mbfl_encoding_ptr_table[i++]) != NULL){
- if(penc->aliases != NULL) {
- j = 0;
- while((*penc->aliases)[j] != NULL) {
- if(strcasecmp((*penc->aliases)[j], name) == 0)
- return penc;
- j++;
- }
- }
- }
-
- return NULL;
-}
-
-mbfl_encoding_ptr
-mbfl_no2encoding(int no_encoding)
-{
- mbfl_encoding_ptr penc;
- int i;
-
- i = 0;
- while((penc = mbfl_encoding_ptr_table[i++]) != NULL){
- if(penc->no_encoding == no_encoding) {
- return penc;
- }
- }
-
- return NULL;
-}
-
-
-
-/*
- * メモリに出力するoutput_function
- * あとで使用する。
- */
-int
-memory_device_output(int c, void* data)
-{
- if (((struct memory_device*)data)->pos >= ((struct memory_device*)data)->length) {
- /* バッファの長さを調節 */
- int newlen = ((struct memory_device*)data)->length + MBFL_MEMORY_DEVICE_ALLOC_SIZE;
- char *tmp = (char*)realloc((void*)((struct memory_device*)data)->buffer, newlen);
- if (tmp == NULL) {
- return -1;
- }
- ((struct memory_device*)data)->length = newlen;
- ((struct memory_device*)data)->buffer = tmp;
- }
-
- ((struct memory_device*)data)->buffer[((struct memory_device*)data)->pos++] = (char)c;
- return c;
-}
-
-int
-memory_device_cat(struct memory_device *pd, const char *psrc)
-{
- int len;
- const char *p;
-
- len = 0;
- p = psrc;
- while (*p) {
- p++;
- len++;
- }
-
- if ((pd->pos + len) >= pd->length) {
- /* バッファの長さを調節 */
- int newlen = pd->length + len + MBFL_MEMORY_DEVICE_ALLOC_SIZE;
- char *tmp = (char*)realloc((void*)pd->buffer, newlen);
- if (tmp == NULL) {
- return 0;
- }
- pd->length = newlen;
- pd->buffer = tmp;
- }
-
- p = psrc;
- while (*p) {
- pd->buffer[pd->pos++] = *p++;
- }
- return 1;
-}
-
-int
-memory_device_ncat(struct memory_device *pd, const char *psrc, int len)
-{
- if ((pd->pos + len) >= pd->length) {
- /* バッファの長さを調節 */
- int newlen = pd->length + len + MBFL_MEMORY_DEVICE_ALLOC_SIZE;
- char *tmp = (char*)realloc((void*)pd->buffer, newlen);
- if (tmp == NULL) {
- return 0;
- }
- pd->length = newlen;
- pd->buffer = tmp;
- }
-
- while (len > 0) {
- pd->buffer[pd->pos++] = *psrc++;
- len--;
- }
- return 1;
-}
-
-int
-wchar_device_output(int c, void* data)
-{
- if (((struct wchar_device*)data)->pos >= ((struct wchar_device*)data)->length) {
- /* バッファの長さを調節 */
- int newlen = ((struct wchar_device*)data)->length + MBFL_MEMORY_DEVICE_ALLOC_SIZE;
- int *tmp = (int*)realloc((void*)((struct wchar_device*)data)->buffer, newlen*sizeof(int));
- if (tmp == NULL) {
- return -1;
- }
- ((struct wchar_device*)data)->length = newlen;
- ((struct wchar_device*)data)->buffer = tmp;
- }
-
- ((struct wchar_device*)data)->buffer[((struct wchar_device*)data)->pos++] = c;
- return c;
-}
-
-/*
- *
- * kanji code filter
- *
- */
-struct mbfl_output_filter {
- const struct filter_vtbl* vptr;
- /* 行うべき変換によって異なるポインタを保持する。*/
-
- int (*output_function)(int c, void* data);
- /* 利用側が用意。エラーのときはマイナス値。*/
-
- int (*flush_function)(void* data);
- /* 利用側が用意。出力をフラッシュする。ヌルならば使用されない。*/
-
- void* data;
- /* 利用側が用意。(*output_function)()の1番目の引数に渡される。*/
-
- int status;
- /* vptr->filter_functionによって使用方法は異なる。*/
-
- int cache;
- /* vptr->filter_functionによって使用方法は異なる。*/
-
- enum mbfl_no_encoding from;
- enum mbfl_no_encoding to;
- /* 変換前と後の漢字コード */
-};
-
-struct filter_vtbl {
- void (*filter_ctor)(
- struct mbfl_output_filter* filter,
- enum mbfl_no_encoding from,
- enum mbfl_no_encoding to,
- int (*output_function)(int, void*),
- int (*flush_function)(void*),
- void* data);
- /* mbfl_output_filterの内容を初期化する。*/
-
- void (*filter_dtor)(struct mbfl_output_filter* filter);
- /* mbfl_output_filterの削除前処理を行う。*/
-
- int (*filter_function)(struct mbfl_output_filter* filter, int c);
- /* 変換を行う関数へのポインタ。エラーのときはマイナス値。*/
-
- int (*flush_function)(struct mbfl_output_filter* filter);
- /* フラッシュを行う関数へのポインタ。*/
-};
-
-#define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
-
-
-/*
- * commonly used constructor and destructor
- */
-static void
-filt_common_ctor(
- struct mbfl_output_filter* filter,
- enum mbfl_no_encoding from, /* ignored */
- enum mbfl_no_encoding to, /* ignored */
- int (*output_function)(int, void*),
- int (*flush_function)(void*),
- void* data)
-{
- filter->output_function = output_function;
- filter->flush_function = flush_function;
- filter->data = data;
- filter->status = 0;
- filter->cache = 0;
- filter->from = from;
- filter->to = to;
-}
-
-static int
-filt_common_flush(struct mbfl_output_filter* filter)
-{
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_common_dtor(struct mbfl_output_filter* filter)
-{
- /* flush */
- if (filter->flush_function) {
- (void)(*filter->flush_function)(filter->data);
- }
-
- /* destruct */
-}
-
-static int
-filt_pass(struct mbfl_output_filter* filter, int c)
-{
- return (*filter->output_function)(c, filter->data);
-}
-
-/*
- * EUC-JP => JIS
- */
-static int
-filt_eucjp_jis(struct mbfl_output_filter* filter, int c)
-{
- switch (filter->status) {
- case 0: /* roman */
- case 10: /* kana */
- case 20: /* kanji */
- if (c == 0x8e) { /* kana first char */
- filter->status++; /* 0->1, 10->11, 20->21 */
- break;
- } if (c >= 0x80) { /* kanji first char */
- filter->status += 2; /* 0->2, 10->12, 20->22 */
- filter->cache = c;
- break;
- }
- if (filter->status != 0) {
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('B', filter->data));
- filter->status = 0;
- }
- CK((*filter->output_function)(c, filter->data));
- break;
-
- case 1: /* roman got 0x8e */
- case 21: /* kanji got 0x8e */
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('I', filter->data));
- case 11: /* kana got 0x8e */
- filter->status = 10;
- CK((*filter->output_function)(c & 0x7f, filter->data));
- break;
-
- case 2: /* roman got first half */
- case 12: /* kana got first half */
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('$', filter->data));
- CK((*filter->output_function)('B', filter->data));
- case 22: /* kanji got first half */
- filter->status = 20;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else {
- CK((*filter->output_function)(filter->cache & 0x7f, filter->data));
- CK((*filter->output_function)(c & 0x7f, filter->data));
- }
- break;
- }
-
- return c;
-}
-
-static int
-filt_eucjp_jis_flush(struct mbfl_output_filter* filter)
-{
- /* back to roman */
- if (filter->status / 10 != 0) { /* upper digit of the status */
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_eucjp_jis_dtor(struct mbfl_output_filter* filter)
-{
- (void)filt_eucjp_jis_flush(filter);
-}
-
-/*
- * EUC-JP => SJIS
- */
-static int
-filt_eucjp_sjis(struct mbfl_output_filter* filter, int c)
-{
- int c1;
-
- switch (filter->status) {
- case 0: /* roman */
- if (c == 0x8e) { /* kana first char */
- filter->status = 1;
- break;
- }
- if (c >= 0x80) { /* kanji first char */
- filter->status = 2;
- filter->cache = c;
- break;
- }
- CK((*filter->output_function)(c, filter->data));
- break;
-
- case 1: /* got 0x8e */
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- break;
-
- case 2: /* got first half */
- filter->status = 0;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else {
- c1 = filter->cache & 0x7f;
- c &= 0x7f;
- c += ((c1 % 2) ? (c > 0x5f ? 0x20 : 0x1f) : 0x7e);
- CK((*filter->output_function)(((c1 + 1) >> 1) + (c1 < 0x5f ? 0x70 : 0xb0), filter->data));
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- }
-
- return c;
-}
-
-/*
- * SJIS => JIS
- */
-static int
-filt_sjis_jis(struct mbfl_output_filter* filter, int c)
-{
- int next; /* next status */
- int c1, row;
-
- if (filter->status >= 10) { /* kanji second char */
- filter->status %= 10;
- next = 2;
- } else if (c >= 0xa1 && c <= 0xdf) { /* kana */
- next = 1;
- } else if (c >= 0x80) { /* kanji first char */
- filter->status += 10;
- filter->cache = c;
- return c;
- } else { /* roman */
- next = 0;
- }
-
- switch (next) {
- case 0: /* roman */
- if (filter->status != 0) {
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('B', filter->data));
- filter->status = 0;
- }
- CK((*filter->output_function)(c, filter->data));
- break;
-
- case 1: /* kana */
- if (filter->status != 1) {
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('I', filter->data));
- filter->status = 1;
- }
- CK((*filter->output_function)(c & 0x7f, filter->data));
- break;
-
- case 2: /* kanji second char */
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else {
- if (filter->status != 2) {
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('$', filter->data));
- CK((*filter->output_function)('B', filter->data));
- filter->status = 2;
- }
- c1 = filter->cache;
- row = (c1 < 0xa0 ? 0x70 : 0xb0);
- if (c < 0x9f) {
- c1 = ((c1 - row) << 1) - 1;
- c -= (c > 0x7f ? 0x20 : 0x1f);
- } else {
- c1 = ((c1 - row) << 1);
- c -= 0x7e;
- }
- CK((*filter->output_function)(c1, filter->data));
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- }
-
- return c;
-}
-
-static int
-filt_sjis_jis_flush(struct mbfl_output_filter* filter)
-{
- /* back to roman */
- if (filter->status != 0) {
- (*filter->output_function)('\033', filter->data);
- (*filter->output_function)('(', filter->data);
- (*filter->output_function)('B', filter->data);
- }
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_sjis_jis_dtor(struct mbfl_output_filter* filter)
-{
- (void)filt_sjis_jis_flush(filter);
-}
-
-/*
- * SJIS => EUC-JP
- */
-static int
-filt_sjis_eucjp(struct mbfl_output_filter* filter, int c)
-{
- int c1, row;
-
- if (filter->status == 1) { /* kanji second char */
- filter->status = 0;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else {
- c1 = filter->cache;
- row = (c1 < 0xa0 ? 0x70 : 0xb0);
- if (c < 0x9f) {
- c1 = ((c1 - row) << 1) - 1;
- c -= (c > 0x7f ? 0x20 : 0x1f);
- } else {
- c1 = ((c1 - row) << 1);
- c -= 0x7e;
- }
- CK((*filter->output_function)(c1 | 0x80, filter->data));
- CK((*filter->output_function)(c | 0x80, filter->data));
- }
- } else if (c >= 0xa1 && c <= 0xdf) { /* kana */
- CK((*filter->output_function)(0x8e, filter->data));
- CK((*filter->output_function)(c, filter->data));
- } else if (c >= 0x80) { /* kanji first char */
- filter->status = 1;
- filter->cache = c;
- } else { /* roman */
- CK((*filter->output_function)(c, filter->data));
- }
-
- return c;
-}
-
-/*
- * JIS => EUC-JP
- */
-static int
-filt_jis_eucjp(struct mbfl_output_filter* filter, int c)
-{
-retry:
- switch (filter->status) {
- case 0: /* roman */
- case 10: /* kana */
- case 20: /* kanji */
- if (c == 0x1b) {
- filter->status++;
- } else if (c == 0x0e) { /* "kana in" */
- filter->status = 10;
- } else if (c == 0x0f) { /* "kana out" */
- filter->status = 0;
- } else if (c >= 0x21 && c <= 0x7e) {
- if (filter->status == 20) { /* kanji first char */
- filter->cache = c;
- filter->status = 25;
- } else if (filter->status == 10) { /* kana */
- CK((*filter->output_function)(0x8e, filter->data));
- CK((*filter->output_function)(c | 0x80, filter->data));
- } else { /* ascii */
- CK((*filter->output_function)(c, filter->data));
- }
- } else if (c >= 0xa1 && c <= 0xdf) { /* GR kana */
- CK((*filter->output_function)(0x8e, filter->data));
- CK((*filter->output_function)(c, filter->data));
- } else { /* CR, LF, CTLs */
- CK((*filter->output_function)(c, filter->data));
- }
- break;
-
- case 25: /* kanji second char */
- filter->status = 20;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else if (c == 0x1b) {
- goto retry;
- } else {
- CK((*filter->output_function)(filter->cache | 0x80, filter->data));
- CK((*filter->output_function)(c | 0x80, filter->data));
- }
- break;
-
- case 1: /* ESC */
- case 11: /* ESC */
- case 21: /* ESC */
- if (c == 0x24) {
- filter->status++;
- } else if (c == 0x28) {
- filter->status += 3;
- } else {
- filter->status--;
- CK((*filter->output_function)(0x1b, filter->data));
- goto retry;
- }
- break;
-
- case 2: /* ESC 0x24 */
- case 12: /* ESC 0x24 */
- case 22: /* ESC 0x24 */
- if (c == 0x40 || c == 0x42) {
- filter->status = 20;
- } else if (c == 0x28) {
- filter->status++;
- } else {
- filter->status -= 2;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- goto retry;
- }
- break;
-
- case 3: /* ESC 0x24 0x28 */
- case 13: /* ESC 0x24 0x28 */
- case 23: /* ESC 0x24 0x28 */
- if (c == 0x44) {
- filter->status = 20;
- } else {
- filter->status -= 3;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
-
- case 4: /* ESC 0x28 */
- case 14: /* ESC 0x28 */
- case 24: /* ESC 0x28 */
- switch (c) {
- case 0x42:
- case 0x48:
- case 0x4a:
- filter->status = 0;
- break;
-
- case 0x49:
- filter->status = 10;
- break;
-
- default:
- filter->status -= 4;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- break;
- }
- break;
- }
-
- return c;
-}
-
-/*
- * JIS => SJIS
- */
-static int
-filt_jis_sjis(struct mbfl_output_filter* filter, int c)
-{
- int c1;
-
-retry:
- switch (filter->status) {
- case 0: /* roman */
- case 10: /* kana */
- case 20: /* kanji */
- if (c == 0x1b) {
- filter->status++;
- } else if (c == 0x0e) { /* "kana in" */
- filter->status = 10;
- } else if (c == 0x0f) { /* "kana out" */
- filter->status = 0;
- } else if (c >= 0x21 && c <= 0x7e) {
- if (filter->status == 20) { /* kanji first char */
- filter->cache = c;
- filter->status = 25;
- } else if (filter->status == 10) { /* kana */
- CK((*filter->output_function)(c | 0x80, filter->data));
- } else { /* ascii */
- CK((*filter->output_function)(c, filter->data));
- }
- } else { /* CR, LF, CTLs or maybe GR kana */
- CK((*filter->output_function)(c, filter->data));
- }
- break;
-
- case 25: /* kanji second char */
- filter->status = 20;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else if (c == 0x1b) {
- goto retry;
- } else {
- c1 = filter->cache;
- c &= 0x7f;
- c += ((c1 % 2) ? (c > 0x5f ? 0x20 : 0x1f) : 0x7e);
- CK((*filter->output_function)(((c1 + 1) >> 1) + (c1 < 0x5f ? 0x70 : 0xb0), filter->data));
- CK((*filter->output_function)(c, filter->data));
- }
- break;
-
- case 1: /* ESC */
- case 11: /* ESC */
- case 21: /* ESC */
- if (c == 0x24) {
- filter->status++;
- } else if (c == 0x28) {
- filter->status += 3;
- } else {
- filter->status--;
- CK((*filter->output_function)(0x1b, filter->data));
- goto retry;
- }
- break;
-
- case 2: /* ESC 0x24 */
- case 12: /* ESC 0x24 */
- case 22: /* ESC 0x24 */
- if (c == 0x40 || c == 0x42) {
- filter->status = 20;
- } else if (c == 0x28) {
- filter->status++;
- } else {
- filter->status -= 2;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- goto retry;
- }
- break;
-
- case 3: /* ESC 0x24 0x28 */
- case 13: /* ESC 0x24 0x28 */
- case 23: /* ESC 0x24 0x28 */
- if (c == 0x44) {
- filter->status = 20;
- } else {
- filter->status -= 3;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
-
- case 4: /* ESC 0x28 */
- case 14: /* ESC 0x28 */
- case 24: /* ESC 0x28 */
- switch (c) {
- case 0x42:
- case 0x48:
- case 0x4a:
- filter->status = 0;
- break;
-
- case 0x49:
- filter->status = 10;
- break;
-
- default:
- filter->status -= 4;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- break;
- }
- break;
- }
-
- return c;
-}
-
-/*
- * EUC-JP => UTF-8
- */
-static int
-filt_eucjp_utf8(struct mbfl_output_filter* filter, int c)
-{
- int p, s;
-
- switch (filter->status) {
- case 0: /* roman */
- if (c == 0x8e) { /* kana first char */
- filter->status = 1;
- } else if (c >= 0x80) { /* kanji first char */
- filter->status = 2;
- filter->cache = c;
- } else {
- CK((*filter->output_function)(c, filter->data));
- }
- break;
-
- case 1: /* got 0x8e */
- filter->status = 0;
- if (c >= 0xa1 && c <= 0xdf) {
- s = 0xfec0 + c;
- CK((*filter->output_function)(((s >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((s >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- } else if (c < 0x80) {
- CK((*filter->output_function)(c, filter->data));
- }
- break;
-
- case 2: /* got first half */
- filter->status = 0;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else {
- p = (filter->cache - 0xa1) * 94 + c - 0xa1;
- s = 0;
- if (p >= 0 && p < j2utable_size)
- s = j2utable[p];
- if (s == 0)
- s = UNDEFCHAR_UNICODE;
- if (s < 0x80) {
- CK((*filter->output_function)(s, filter->data));
- } else if (s < 0x800) {
- CK((*filter->output_function)(((s >> 6) & 0x1f) | 0xc0, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- } else {
- CK((*filter->output_function)(((s >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((s >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- }
- }
- break;
- }
-
- return c;
-}
-
-/*
- * SJIS => UTF8
- */
-static int
-filt_sjis_utf8(struct mbfl_output_filter* filter, int c)
-{
- int p, s;
-
- if (filter->status == 1) { /* kanji second char */
- filter->status = 0;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else {
- p = filter->cache;
- if (p < 0xa0)
- p -= 0x81;
- else
- p -= 0xc1;
- p *= 188;
- if (c < 0x7f)
- p += c - 0x40;
- else
- p += c - 0x41;
- s = 0;
- if (p >= 0 && p < j2utable_size)
- s = j2utable[p];
- if (s == 0)
- s = UNDEFCHAR_UNICODE;
- if (s < 0x80) {
- CK((*filter->output_function)(s, filter->data));
- } else if (s < 0x800) {
- CK((*filter->output_function)(((s >> 6) & 0x1f) | 0xc0, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- } else {
- CK((*filter->output_function)(((s >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((s >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- }
- }
- } else if (c >= 0xa1 && c <= 0xdf) { /* kana */
- filter->status = 0;
- s = 0xfec0 + c;
- CK((*filter->output_function)(((s >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((s >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- } else if (c >= 0x80) { /* kanji first char */
- filter->status = 1;
- filter->cache = c;
- } else { /* roman */
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- }
-
- return c;
-}
-
-/*
- * JIS => UTF-8
- */
-static int
-filt_jis_utf8(struct mbfl_output_filter* filter, int c)
-{
- int p, s;
-
-retry:
- switch (filter->status) {
- case 0: /* roman */
- case 10: /* kana */
- case 20: /* kanji */
- if (c == 0x1b) {
- filter->status++;
- } else if (c == 0x0e) { /* "kana in" */
- filter->status = 10;
- } else if (c == 0x0f) { /* "kana out" */
- filter->status = 0;
- } else if (c >= 0x21 && c <= 0x7e) {
- if (filter->status == 20) { /* kanji first char */
- filter->cache = c;
- filter->status = 25;
- } else if (filter->status == 10) { /* kana */
- s = 0xff40 + c;
- CK((*filter->output_function)(((s >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((s >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- } else { /* ascii */
- CK((*filter->output_function)(c, filter->data));
- }
- } else if (c >= 0xa1 && c <= 0xdf) { /* GR kana */
- s = 0xfec0 + c;
- CK((*filter->output_function)(((s >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((s >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- } else { /* CR, LF, CTLs */
- CK((*filter->output_function)(c, filter->data));
- }
- break;
-
- case 25: /* kanji second char */
- filter->status = 20;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else if (c == 0x1b) {
- goto retry;
- } else {
- p = (filter->cache - 0x21) * 94 + c - 0x21;
- s = 0;
- if (p >= 0 && p < j2utable_size)
- s = j2utable[p];
- if (s == 0)
- s = UNDEFCHAR_UNICODE;
- if (s < 0x80) {
- CK((*filter->output_function)(s, filter->data));
- } else if (s < 0x800) {
- CK((*filter->output_function)(((s >> 6) & 0x1f) | 0xc0, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- } else {
- CK((*filter->output_function)(((s >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((s >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0x3f) | 0x80, filter->data));
- }
- }
- break;
-
- case 1: /* ESC */
- case 11: /* ESC */
- case 21: /* ESC */
- if (c == 0x24) {
- filter->status++;
- } else if (c == 0x28) {
- filter->status += 3;
- } else {
- filter->status--;
- CK((*filter->output_function)(0x1b, filter->data));
- goto retry;
- }
- break;
-
- case 2: /* ESC 0x24 */
- case 12: /* ESC 0x24 */
- case 22: /* ESC 0x24 */
- if (c == 0x40 || c == 0x42) {
- filter->status = 20;
- } else if (c == 0x28) {
- filter->status++;
- } else {
- filter->status -= 2;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- goto retry;
- }
- break;
-
- case 3: /* ESC 0x24 0x28 */
- case 13: /* ESC 0x24 0x28 */
- case 23: /* ESC 0x24 0x28 */
- if (c == 0x44) {
- filter->status = 20;
- } else {
- filter->status -= 3;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
-
- case 4: /* ESC 0x28 */
- case 14: /* ESC 0x28 */
- case 24: /* ESC 0x28 */
- switch (c) {
- case 0x42:
- case 0x48:
- case 0x4a:
- filter->status = 0;
- break;
- case 0x49:
- filter->status = 10;
- break;
- default:
- filter->status -= 4;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
- }
-
- return c;
-}
-
-
-/*
- * UTF-8 => EUC-JP
- */
-static int
-filt_utf8_euc(struct mbfl_output_filter* filter, int c)
-{
- int s;
-
- if (c < 0x80) {
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- } else if (c < 0xc0) {
- switch (filter->status) {
- case 0x20: /* 3 byte code second char */
- filter->cache += ((c & 0x3f) << 6);
- filter->status++;
- break;
-
- case 0x10: /* 2 byte code second char */
- case 0x21: /* 3 byte code third char */
- filter->status = 0;
- s = u2jtable[filter->cache + (c & 0x3f)];
- if (s == 0)
- s = UNDEFCHAR_JIS;
- if(s < 0x80) {
- CK((*filter->output_function)(s, filter->data));
- } else if (s < 0x100) {
- CK((*filter->output_function)(0x8e, filter->data));
- CK((*filter->output_function)(s, filter->data));
- } else {
- CK((*filter->output_function)(((s >> 8) & 0xff) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0xff) | 0x80, filter->data));
- }
- break;
-
- default:
- filter->status = 0;
- break;
- }
- } else if (c < 0xe0) { /* 2 byte code first char */
- filter->status = 0x10;
- filter->cache = (c & 0x1f) << 6;
- } else if (c < 0xf0) { /* 3 byte code first char */
- filter->status = 0x20;
- filter->cache = (c & 0xf) << 12;
- } else { /* 4, 5 or 6 byte code first char */
- filter->status = 0;
- }
-
- return c;
-}
-
-/*
- * UTF-8 => SJIS
- */
-static int
-filt_utf8_sjis(struct mbfl_output_filter* filter, int c)
-{
- int c1, c2, s1, s2;
-
- if (c < 0x80) {
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- } else if (c < 0xc0) {
- switch (filter->status & 0xff) {
- case 0x20: /* 3 byte code second char */
- filter->cache += ((c & 0x3f) << 6);
- filter->status++;
- break;
-
- case 0x10: /* 2 byte code second char */
- case 0x21: /* 3 byte code third char */
- filter->status = 0;
- s1 = u2jtable[filter->cache + (c & 0x3f)];
- if (s1 == 0)
- s1 = UNDEFCHAR_JIS;
- if(s1 < 0x100) {
- CK((*filter->output_function)(s1, filter->data));
- } else {
- c1 = (s1 >> 8) & 0xff;
- c2 = s1 & 0xff;
- s1 = ((c1 + 1) >> 1) + (c1 < 0x5f ? 0x70 : 0xb0);
- s2 = c2 + (c1 & 1 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e);
- CK((*filter->output_function)(s1, filter->data));
- CK((*filter->output_function)(s2, filter->data));
- }
- break;
-
- default:
- filter->status = 0;
- break;
- }
- } else if (c < 0xe0) { /* 2 byte code first char */
- filter->status = 0x10;
- filter->cache = ((c & 0x1f) << 6);
- } else if (c < 0xf0) { /* 3 byte code first char */
- filter->status = 0x20;
- filter->cache = ((c & 0xf) << 12);
- } else { /* 4, 5 or 6 byte code first char */
- filter->status = 0;
- }
-
- return c;
-}
-
-/*
- * UTF-8 => JIS
- */
-static int
-filt_utf8_jis(struct mbfl_output_filter* filter, int c)
-{
- int s;
-
- if (c < 0x80) {
- if ((filter->status & 0xff00) != 0) {
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- } else if (c < 0xc0) {
- switch(filter->status & 0xff) {
- case 0x20: /* 3 byte code second char */
- filter->cache += ((c & 0x3f) << 6);
- filter->status++;
- break;
-
- case 0x10: /* 2 byte code second char */
- case 0x21: /* 3 byte code third char */
- s = u2jtable[filter->cache + (c & 0x3f)];
- if(s == 0)
- s = UNDEFCHAR_JIS;
- if(s < 0x80) { /* roman */
- if((filter->status & 0xff00) != 0) {
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
- filter->status = 0;
- CK((*filter->output_function)(s, filter->data));
- } else if(s < 0x100) { /* kana */
- if((filter->status & 0xff00) != 0x100){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('I', filter->data));
- }
- filter->status = 0x30100;
- CK((*filter->output_function)(s & 0x7f, filter->data));
- } else { /* kanji */
- if((filter->status & 0xff00) != 0x200){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('$', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
- filter->status = 0x30200;
- CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
- CK((*filter->output_function)(s & 0x7f, filter->data));
- }
- break;
-
- default:
- filter->status &= ~0xff;
- break;
- }
- } else if (c < 0xe0) { /* 2 byte code first char */
- filter->status &= ~0xff;
- filter->status |= 0x10;
- filter->cache = (c & 0x1f) << 6;
- } else if (c < 0xf0) { /* 3 byte code first char */
- filter->status &= ~0xff;
- filter->status |= 0x20;
- filter->cache = (c & 0xf) << 12;
- } else { /* 4, 5 or 6 byte code first char */
- filter->status &= ~0xff;
- }
-
- return c;
-}
-
-static int
-filt_ucs_jis_flush(struct mbfl_output_filter* filter)
-{
- /* back to roman */
- if ((filter->status & 0xff00) != 0) {
- (*filter->output_function)('\033', filter->data);
- (*filter->output_function)('(', filter->data);
- (*filter->output_function)('B', filter->data);
- }
- filter->status &= 0xff;
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_ucs_jis_dtor(struct mbfl_output_filter* filter)
-{
- (void)filt_ucs_jis_flush(filter);
-}
-
-/*
- * EUC-JP => UCS
- */
-static int
-filt_euc_ucs(struct mbfl_output_filter* filter, int c)
-{
- int s;
- switch (filter->status) {
- case 0: /* roman */
- if (c == 0x8e) { /* kana first char */
- filter->status = 1;
- } else if (c >= 0x80) { /* kanji first char */
- filter->status = 2;
- filter->cache = c;
- } else {
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- case 1: /* got 0x8e */
- filter->status = 0;
- if(c >= 0xa1 && c <= 0xdf){
- CK((*filter->output_function)(0xfec0 + c, filter->data));
- } else if(c < 0x80) {
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- case 2: /* got first half */
- filter->status = 0;
- if(c == '\0'){
- CK((*filter->output_function)(c, filter->data));
- } else {
- s = (filter->cache - 0xa1)*94 + c - 0xa1;
- if(s >= 0 && s < j2utable_size)
- s = j2utable[s];
- else
- s = 0;
- if(s == 0)
- s = UNDEFCHAR_UNICODE;
- CK((*filter->output_function)(s, filter->data));
- }
- break;
- }
-
- return c;
-}
-
-/*
- * UCS => EUC-JP
- */
-static int
-filt_ucs_euc(struct mbfl_output_filter* filter, int c)
-{
- int s = 0;
- if(c > 0 && c < u2jtable_size)
- s = u2jtable[c];
- if(s == 0 && c != 0)
- s = UNDEFCHAR_JIS;
-
- if(s < 0x80) { /* roman */
- CK((*filter->output_function)(s, filter->data));
- } else if(s < 0x100) { /* kana */
- CK((*filter->output_function)(0x8e, filter->data));
- CK((*filter->output_function)(s, filter->data));
- } else { /* kanji */
- CK((*filter->output_function)(((s >> 8) & 0xff) | 0x80, filter->data));
- CK((*filter->output_function)((s & 0xff) | 0x80, filter->data));
- }
-
- return c;
-}
-
-/*
- * EUC-JP => wchar
- */
-static int
-filt_euc_wchar(struct mbfl_output_filter* filter, int c)
-{
- switch (filter->status) {
- case 0: /* roman */
- if (c == 0x8e) { /* kana first char */
- filter->status = 1;
- } else if (c >= 0x80) { /* kanji first char */
- filter->status = 2;
- filter->cache = c;
- } else {
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- case 1: /* got 0x8e */
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- break;
- case 2: /* got first half */
- filter->status = 0;
- if(c == '\0'){
- CK((*filter->output_function)(c, filter->data));
- } else {
- CK((*filter->output_function)((filter->cache << 8) + c, filter->data));
- }
- break;
- }
-
- return c;
-}
-
-/*
- * wchar => EUC-JP
- */
-static int
-filt_wchar_euc(struct mbfl_output_filter* filter, int c)
-{
- if(c < 0x80) { /* roman */
- CK((*filter->output_function)(c, filter->data));
- } else if(c < 0x100) { /* kana */
- CK((*filter->output_function)(0x8e, filter->data));
- CK((*filter->output_function)(c, filter->data));
- } else { /* kanji */
- CK((*filter->output_function)((c >> 8) & 0xff, filter->data));
- CK((*filter->output_function)(c & 0xff, filter->data));
- }
-
- return c;
-}
-
-/*
- * SJIS => UCS
- */
-static int
-filt_sjis_ucs(struct mbfl_output_filter* filter, int c)
-{
- int s;
- if (filter->status == 1) { /* kanji second char */
- filter->status = 0;
- if(c == '\0'){
- CK((*filter->output_function)(c, filter->data));
- } else {
- s = filter->cache;
- if(s < 0xa0)
- s -= 0x81;
- else
- s -= 0xc1;
- s *= 188;
- if(c < 0x7f)
- s += c - 0x40;
- else
- s += c - 0x41;
- if(s >= 0 && s < j2utable_size)
- s = j2utable[s];
- else
- s = 0;
- if(s == 0)
- s = UNDEFCHAR_UNICODE;
- CK((*filter->output_function)(s, filter->data));
- }
- } else if (c >= 0xa1 && c <= 0xdf) { /* kana */
- filter->status = 0;
- CK((*filter->output_function)(0xfec0 + c, filter->data));
- } else if (c >= 0x80) { /* kanji first char */
- filter->status = 1;
- filter->cache = c;
- } else { /* roman */
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- }
-
- return c;
-}
-
-/*
- * UCS => SJIS
- */
-static int
-filt_ucs_sjis(struct mbfl_output_filter* filter, int c)
-{
- int s1 = 0;
- int c1,c2,s2;
- if(c > 0 && c < u2jtable_size)
- s1 = u2jtable[c];
- if(s1 == 0 && c != 0)
- s1 = UNDEFCHAR_JIS;
-
- if(s1 < 0x100) { /* roman or kana */
- CK((*filter->output_function)(s1, filter->data));
- } else { /* kanji */
- c1 = (s1 >> 8) & 0xff;
- c2 = s1 & 0xff;
- s1 = ((c1 + 1) >> 1) + (c1 < 0x5f ? 0x70 : 0xb0);
- s2 = c2 + (c1 & 1 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e);
- CK((*filter->output_function)(s1, filter->data));
- CK((*filter->output_function)(s2, filter->data));
- }
-
- return c;
-}
-
-/*
- * SJIS => wchar
- */
-static int
-filt_sjis_wchar(struct mbfl_output_filter* filter, int c)
-{
- if (filter->status == 1) { /* kanji second char */
- filter->status = 0;
- if(c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else {
- CK((*filter->output_function)((filter->cache << 8) + c, filter->data));
- }
- } else if (c >= 0xa1 && c <= 0xdf) { /* kana */
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- } else if (c >= 0x80) { /* kanji first char */
- filter->status = 1;
- filter->cache = c;
- } else { /* roman */
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- }
-
- return c;
-}
-
-/*
- * wchar => SJIS
- */
-static int
-filt_wchar_sjis(struct mbfl_output_filter* filter, int c)
-{
-
- if(c < 0x100) { /* roman or kana */
- CK((*filter->output_function)(c, filter->data));
- } else { /* kanji */
- CK((*filter->output_function)((c >> 8) & 0xff, filter->data));
- CK((*filter->output_function)(c & 0xff, filter->data));
- }
-
- return c;
-}
-
-/*
- * JIS => UCS
- */
-static int
-filt_jis_ucs(struct mbfl_output_filter* filter, int c)
-{
- int s;
-retry:
- switch (filter->status) {
- case 0: /* roman */
- case 10: /* kana */
- case 20: /* kanji */
- if (c == 0x1b) {
- filter->status++;
- } else if (c == 0x0e) { /* "kana in" */
- filter->status = 10;
- } else if (c == 0x0f) { /* "kana out" */
- filter->status = 0;
- } else if (c >= 0x21 && c <= 0x7e) {
- if (filter->status == 20) { /* kanji first char */
- filter->cache = c;
- filter->status = 25;
- } else if (filter->status == 10) { /* kana */
- CK((*filter->output_function)(0xff40 + c, filter->data));
- } else {
- CK((*filter->output_function)(c, filter->data));
- }
- } else if (c >= 0xa1 && c <= 0xdf) { /* GR kana */
- CK((*filter->output_function)(0xfec0 + c, filter->data));
- } else {
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- case 25: /* kanji second char */
- filter->status = 20;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else if (c == 0x1b) {
- goto retry;
- } else {
- s = (filter->cache - 0x21)*94 + c - 0x21;
- if(s >= 0 && s < j2utable_size)
- s = j2utable[s];
- else
- s = 0;
- if(s == 0)
- s = UNDEFCHAR_UNICODE;
- CK((*filter->output_function)(s, filter->data));
- }
- break;
- case 1: /* ESC */
- case 11: /* ESC */
- case 21: /* ESC */
- if (c == 0x24) {
- filter->status++;
- } else if (c == 0x28) {
- filter->status += 3;
- } else {
- filter->status--;
- CK((*filter->output_function)(0x1b, filter->data));
- goto retry;
- }
- break;
- case 2: /* ESC 0x24 */
- case 12: /* ESC 0x24 */
- case 22: /* ESC 0x24 */
- if (c == 0x40 || c == 0x42) {
- filter->status = 20;
- } else if (c == 0x28) {
- filter->status++;
- }else {
- filter->status -= 2;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- goto retry;
- }
- break;
- case 3: /* ESC 0x24 0x28 */
- case 13: /* ESC 0x24 0x28 */
- case 23: /* ESC 0x24 0x28 */
- if (c == 0x44) {
- filter->status = 20;
- } else {
- filter->status -= 3;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
- case 4: /* ESC 0x28 */
- case 14: /* ESC 0x28 */
- case 24: /* ESC 0x28 */
- switch (c) {
- case 0x42:
- case 0x48:
- case 0x4a:
- filter->status = 0;
- break;
- case 0x49:
- filter->status = 10;
- break;
- default:
- filter->status -= 4;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
- }
-
- return c;
-}
-
-/*
- * UCS => JIS
- */
-static int
-filt_ucs_jis(struct mbfl_output_filter* filter, int c)
-{
- int s = 0;
-
- if(c > 0 && c < u2jtable_size)
- s = u2jtable[c];
- if(s == 0 && c != 0)
- s = UNDEFCHAR_JIS;
-
- if(s < 0x80) { /* roman */
- if((filter->status & 0xff00) != 0){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
- filter->status = 0;
- CK((*filter->output_function)(s, filter->data));
- } else if(s < 0x100) { /* kana */
- if((filter->status & 0xff00) != 0x100){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('I', filter->data));
- }
- filter->status = 0x30100;
- CK((*filter->output_function)(s & 0x7f, filter->data));
- } else { /* kanji */
- if((filter->status & 0xff00) != 0x200){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('$', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
- filter->status = 0x30200;
- CK((*filter->output_function)((s >> 8) & 0x7f, filter->data));
- CK((*filter->output_function)(s & 0x7f, filter->data));
- }
-
- return c;
-}
-
-/*
- * JIS => wchar
- */
-static int
-filt_jis_wchar(struct mbfl_output_filter* filter, int c)
-{
-retry:
- switch (filter->status) {
- case 0: /* roman */
- case 10: /* kana */
- case 20: /* kanji */
- if (c == 0x1b) {
- filter->status++;
- } else if (c == 0x0e) { /* "kana in" */
- filter->status = 10;
- } else if (c == 0x0f) { /* "kana out" */
- filter->status = 0;
- } else if (c >= 0x21 && c <= 0x7e) {
- if (filter->status == 20) { /* kanji first char */
- filter->cache = c;
- filter->status = 25;
- } else if (filter->status == 10) { /* kana */
- CK((*filter->output_function)(c | 0x80, filter->data));
- } else {
- CK((*filter->output_function)(c, filter->data));
- }
- } else { /* CR, LF, CTLs, or maybe GR kana */
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- case 25: /* kanji second char */
- filter->status = 20;
- if (c == '\0') {
- CK((*filter->output_function)(c, filter->data));
- } else if (c == 0x1b) {
- goto retry;
- } else {
- CK((*filter->output_function)((filter->cache << 8) + c, filter->data));
- }
- break;
- case 1: /* ESC */
- case 11: /* ESC */
- case 21: /* ESC */
- if (c == 0x24) {
- filter->status++;
- } else if (c == 0x28) {
- filter->status += 3;
- } else {
- CK((*filter->output_function)(0x1b, filter->data));
- filter->status--;
- goto retry;
- }
- break;
- case 2: /* ESC 0x24 */
- case 12: /* ESC 0x24 */
- case 22: /* ESC 0x24 */
- if (c == 0x40 || c == 0x42) {
- filter->status = 20;
- } else if (c == 0x28) {
- filter->status++;
- } else {
- filter->status -= 2;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- goto retry;
- }
- break;
- case 3: /* ESC 0x24 0x28 */
- case 13: /* ESC 0x24 0x28 */
- case 23: /* ESC 0x24 0x28 */
- if (c == 0x44) {
- filter->status = 20;
- } else {
- filter->status -= 3;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x24, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
- case 4: /* ESC 0x28 */
- case 14: /* ESC 0x28 */
- case 24: /* ESC 0x28 */
- switch (c) {
- case 0x42:
- case 0x48:
- case 0x4a:
- filter->status = 0;
- break;
- case 0x49:
- filter->status = 10;
- break;
- default:
- filter->status -= 4;
- CK((*filter->output_function)(0x1b, filter->data));
- CK((*filter->output_function)(0x28, filter->data));
- goto retry;
- }
- break;
- }
-
- return c;
-}
-
-/*
- * wchar => JIS
- */
-static int
-filt_wchar_jis(struct mbfl_output_filter* filter, int c)
-{
- if(c < 0x80) { /* roman */
- if((filter->status & 0xff00) != 0){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
- filter->status = 0;
- CK((*filter->output_function)(c, filter->data));
- } else if(c < 0x100) { /* kana */
- if((filter->status & 0xff00) != 0x100){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('(', filter->data));
- CK((*filter->output_function)('I', filter->data));
- }
- filter->status = 0x30100;
- CK((*filter->output_function)(c & 0x7f, filter->data));
- } else { /* kanji */
- if((filter->status & 0xff00) != 0x200){
- CK((*filter->output_function)('\033', filter->data));
- CK((*filter->output_function)('$', filter->data));
- CK((*filter->output_function)('B', filter->data));
- }
- filter->status = 0x30200;
- CK((*filter->output_function)((c >> 8) & 0x7f, filter->data));
- CK((*filter->output_function)(c & 0x7f, filter->data));
- }
-
- return c;
-}
-
-/*
- * UNKNOWN->(UTF-8|EUC-JP|SJIS|JIS)
- */
-struct unknown_data {
- enum mbfl_no_encoding to;
- /* 変換後のコード */
-
- void* data;
- /* 本来のvoid* data */
-
- struct memory_device device;
- /* 推定作業中にはここに出力しておく。*/
-
- enum mbfl_no_encoding from_default;
- /* 不定の場合のコード */
-};
-
-static void
-filt_unknown_ja_jp_ctor(
- struct mbfl_output_filter* filter,
- enum mbfl_no_encoding from, /* ignored */
- enum mbfl_no_encoding to,
- int (*output_function)(int, void*),
- int (*flush_function)(void*),
- void* data)
-{
- struct unknown_data* u = (struct unknown_data*)malloc(sizeof (struct unknown_data));
- u->to = to;
- u->from_default = mbfl_no_encoding_pass;
- u->data = data;
- u->device.buffer = (char*)0;
- u->device.length = 0;
- u->device.pos = 0;
-
- filter->output_function = output_function;
- filter->flush_function = flush_function;
- filter->data = (void*)u;
- filter->status = 0;
- filter->cache = 0;
- filter->from = from;
- filter->to = to;
-}
-
-/* forward */
-static int filt_unknown_ja_jp_identify(struct mbfl_output_filter* filter);
-
-static int
-filt_unknown_ja_jp(struct mbfl_output_filter* filter, int c)
-{
- int bad;
- struct memory_device* dev = &((struct unknown_data*)filter->data)->device;
-
- /* filter->cache holds "bad" scores for UTF-8 EUC-JP, SJIS, JIS */
- /* filter->status holds status for UTF-8 EUC-JP, SJIS, JIS */
- /* 0xWWXXYYZZ - WW for UTF-8, XX for EUC-JP, YY for SJIS, ZZ for JIS */
-#define S_UTF8(x) ((x) << 24)
-#define S_EUCJP(x) ((x) << 16)
-#define S_SJIS(x) ((x) << 8)
-#define S_JIS(x) ((x))
-#define M_UTF8 0xff000000
-#define M_EUCJP 0x00ff0000
-#define M_SJIS 0x0000ff00
-#define M_JIS 0x000000ff
-
- if (dev->pos == 0 && ((c >= 0x20 && c <= 0x7e) || c == '\t' || c == '\n' || c == '\r' || c == '\0')) {
- /* 先頭の連続するASCIIはそのまま出力する。*/
- return (*filter->output_function)(c, ((struct unknown_data*)filter->data)->data);
- }
-
- /*
- * UTF-8だとした場合。
- */
- if ((filter->cache & M_UTF8) == 0) {
- if (c < 0x80) {
- if (filter->status & M_UTF8) {
- filter->cache |= S_UTF8(1); /* bad */
- } else if (c == 0x1b || c == 0x0e || c == 0x0f) {
- filter->cache |= S_UTF8(1); /* bad */
- }
- filter->status &= ~M_UTF8;
- } else if (c < 0xc0) {
- switch(filter->status & M_UTF8) {
- case S_UTF8(0x20): /* 3 byte code 2nd char */
- case S_UTF8(0x30): /* 4 byte code 2nd char */
- case S_UTF8(0x31): /* 4 byte code 3rd char */
- case S_UTF8(0x40): /* 5 byte code 2nd char */
- case S_UTF8(0x41): /* 5 byte code 3rd char */
- case S_UTF8(0x42): /* 5 byte code 4th char */
- case S_UTF8(0x50): /* 6 byte code 2nd char */
- case S_UTF8(0x51): /* 6 byte code 3rd char */
- case S_UTF8(0x52): /* 6 byte code 4th char */
- case S_UTF8(0x53): /* 6 byte code 5th char */
- filter->status += S_UTF8(1);
- break;
- case S_UTF8(0x10): /* 2 byte code 2nd char */
- case S_UTF8(0x21): /* 3 byte code 3rd char */
- case S_UTF8(0x32): /* 4 byte code 4th char */
- case S_UTF8(0x43): /* 5 byte code 5th char */
- case S_UTF8(0x54): /* 6 byte code 6th char */
- filter->status &= ~M_UTF8;
- break;
- default:
- filter->cache |= S_UTF8(1); /* bad */
- filter->status &= ~M_UTF8;
- break;
- }
- } else {
- if (filter->status & M_UTF8) {
- filter->cache |= S_UTF8(1); /* bad */
- }
- filter->status &= ~M_UTF8;
- if (c < 0xe0) { /* 2 byte code first char */
- filter->status |= S_UTF8(0x10);
- } else if (c < 0xf0) { /* 3 byte code 1st char */
- filter->status |= S_UTF8(0x20);
- } else if (c < 0xf8) { /* 4 byte code 1st char */
- filter->status |= S_UTF8(0x30);
- } else if (c < 0xfc) { /* 5 byte code 1st char */
- filter->status |= S_UTF8(0x40);
- } else { /* 6 byte code 1st char */
- filter->status |= S_UTF8(0x50);
- }
- }
- }
-
- /*
- * EUC-JPだとした場合。
- */
- if ((filter->cache & M_EUCJP) == 0) {
- switch ((filter->status & M_EUCJP)) {
- case S_EUCJP(0): /* roman */
- if (c == 0x1b || c == 0x0e || c == 0x0f) { /* bad */
- filter->cache |= S_EUCJP(1);
- } else if (c >= 0 && c <= 0x7e) { /* ok */
- ;
- } else if (c == 0x8e) { /* kana first char */
- filter->status += S_EUCJP(1);
- } else if (c >= 0xa1 && c <= 0xfe) { /* kanji first char */
- filter->status += S_EUCJP(2);
- } else { /* bad */
- filter->cache |= S_EUCJP(1);
- }
- break;
-
- case S_EUCJP(1): /* got 0x8e */
- if (c < 0xa1 || c > 0xdf) { /* bad */
- filter->cache |= S_EUCJP(1);
- }
- filter->status -= S_EUCJP(1);
- break;
-
- case S_EUCJP(2): /* got first half */
- if (c < 0xa1 || c > 0xfe) { /* bad */
- filter->cache |= S_EUCJP(1);
- }
- filter->status -= S_EUCJP(2);
- break;
- }
- }
-
- /*
- * SJISだとした場合。
- */
- if ((filter->cache & M_SJIS) == 0) {
- if ((filter->status & M_SJIS)) { /* kanji second char */
- if (c < 0x40 || c > 0xfc || c == 0x7f) { /* bad */
- filter->cache |= S_SJIS(1);
- }
- filter->status &= ~M_SJIS; /* 0にもどす。*/
- } else if (c == 0x1b || c == 0x0e || c == 0x0f) { /* bad */
- filter->cache |= S_SJIS(1);
- } else if (c >= 0 && c <= 0x7e) { /* roman ok */
- ;
- } else if (c >= 0xa1 && c <= 0xdf) { /* kana ok */
- ;
- } else if (c >= 0x81 && c <= 0xef) { /* kanji first char */
- filter->status += S_SJIS(1);
- } else { /* bad */
- filter->cache |= S_SJIS(1);
- }
- }
-
- /*
- * JISだとした場合。
- */
- if ((filter->cache & M_JIS) == 0) {
-retry:
- switch ((filter->status & M_JIS)) {
- case S_JIS(0): /* roman */
- case S_JIS(10): /* kana */
- case S_JIS(20): /* kanji */
- if (c == 0x1b) {
- filter->status += S_JIS(1);
- } else if (c == 0x0e) { /* "kana in" */
- filter->status = (filter->status & ~M_JIS) + 10;
- } else if (c == 0x0f) { /* "kana out" */
- filter->status &= ~M_JIS;
- } else if (c >= 0 && c <= 0x20) { /* CTLs ok */
- ;
- } else if (c >= 0x21 && c <= 0x7e) {
- if ((filter->status & M_JIS) == 20) { /* kanji first char */
- filter->status += S_JIS(5);
- }
- } else {
- filter->cache |= S_JIS(1); /* bad */
- }
- break;
-
- case S_JIS(25): /* kanji second char */
- filter->status -= S_JIS(5);
- if (c < 0x21 || c > 0x7e) { /* bad */
- filter->cache |= S_JIS(1);
- }
- if (c == 0x1b) {
- goto retry;
- }
- break;
-
- case S_JIS(1): /* ESC */
- case S_JIS(11): /* ESC */
- case S_JIS(21): /* ESC */
- if (c == 0x24) {
- filter->status += S_JIS(1);
- } else if (c == 0x28) {
- filter->status += S_JIS(3);
- } else {
- filter->cache |= S_JIS(1); /* bad */
- filter->status -= S_JIS(1);
- goto retry;
- }
- break;
-
- case S_JIS(2): /* ESC 0x24 */
- case S_JIS(12): /* ESC 0x24 */
- case S_JIS(22): /* ESC 0x24 */
- if (c == 0x40 || c == 0x42) {
- filter->status = (filter->status & ~M_JIS) + 20;
- } else if (c == 0x28) {
- filter->status += S_JIS(1);
- } else {
- filter->cache |= S_JIS(1); /* bad */
- filter->status -= S_JIS(2);
- goto retry;
- }
- break;
-
- case S_JIS(3): /* ESC 0x24 0x28 */
- case S_JIS(13): /* ESC 0x24 0x28 */
- case S_JIS(23): /* ESC 0x24 0x28 */
- if (c == 0x44) {
- filter->status = (filter->status & ~M_JIS) + 20;
- } else {
- filter->cache |= S_JIS(1); /* bad */
- filter->status -= S_JIS(3);
- goto retry;
- }
- break;
-
- case S_JIS(4): /* ESC 0x28 */
- case S_JIS(14): /* ESC 0x28 */
- case S_JIS(24): /* ESC 0x28 */
- switch (c) {
- case 0x42:
- case 0x48:
- case 0x4a:
- filter->status &= ~M_JIS;
- break;
-
- case 0x49:
- filter->status = (filter->status & ~M_JIS) + 10;
- break;
-
- default:
- filter->cache |= S_JIS(1); /* bad */
- filter->status -= S_JIS(4);
- goto retry;
- break;
- }
- break;
- }
- }
-
- /*
- * おしまい。
- */
- (void)memory_device_output(c, dev); /* 覚えておく */
-
- bad = 0;
- if (filter->cache & M_UTF8) {
- bad++;
- }
- if (filter->cache & M_EUCJP) {
- bad++;
- }
- if (filter->cache & M_SJIS) {
- bad++;
- }
- if (filter->cache & M_JIS) {
- bad++;
- }
- if (bad >= 3 /* 3つ以上のエンコーディングでない (一つ以下に確定) */
- || dev->pos >= 8192) { /* もう8192文字溜まっている */
- if (filt_unknown_ja_jp_identify(filter) < 0) { /* 漢字コードの判定を行う */
- c = -1;
- }
- }
-
- return c;
-}
-
-/*
- * 漢字コードを判定し、vptrを切りかえ、溜まっているデータを出力する。
- */
-
-/* forward */
-static struct filter_vtbl*
-select_vtbl(enum mbfl_no_encoding from, enum mbfl_no_encoding to);
-
-static int
-filt_unknown_ja_jp_identify(struct mbfl_output_filter* filter)
-{
- int n;
- char *p;
- struct unknown_data* u;
- enum mbfl_no_encoding code = mbfl_no_encoding_pass;
-
- /* saved data */
- u = (struct unknown_data*)filter->data;
-
- /* 判定 */
- n = 0;
- if ((filter->cache & M_UTF8) == 0) {
- n++;
- code = mbfl_no_encoding_utf8;
- }
- if ((filter->cache & M_EUCJP) == 0) {
- n++;
- code = mbfl_no_encoding_ja_jp_euc;
- }
- if ((filter->cache & M_SJIS) == 0) {
- n++;
- code = mbfl_no_encoding_ja_jp_sjis;
- }
- if ((filter->cache & M_JIS) == 0) {
- n++;
- code = mbfl_no_encoding_ja_jp_jis;
- }
- if (n != 1) {
- code = u->from_default;
- }
-
- /* 漢字らしきものが見つからなかった、
- そして、たぶんデストラクタが呼ばれた。*/
- if (u->device.pos == 0) {
- code = mbfl_no_encoding_en_us_ascii;
- }
-
- /* select the vtbl */
- filter->vptr = select_vtbl(code, u->to);
-
- /* constructor */
- (*filter->vptr->filter_ctor)(filter, code, u->to,
- filter->output_function, filter->flush_function, u->data);
-
- /* 溜まっているデータを吐き出す */
- for (p = u->device.buffer, n = u->device.pos; n > 0; n--) {
- if ((*filter->vptr->filter_function)(filter, *p++ & 0xff) < 0) {
- n = -1;
- break;
- }
- }
- /* 正常に終わった場合はnは0であるはず。*/
-
- /* free */
- if (u->device.buffer) {
- free((void*)u->device.buffer);
- }
- free((void*)u);
-
- return n; /* 正常ならば0、エラーならば-1 */
-}
-
-static int
-filt_unknown_ja_jp_flush(struct mbfl_output_filter* filter)
-{
- if (filt_unknown_ja_jp_identify(filter) < 0)
- return -1;
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_unknown_ja_jp_dtor(struct mbfl_output_filter* filter)
-{
- /* flush */
- (void)filt_unknown_ja_jp_flush(filter);
-
- /* destruct */
- (*filter->vptr->filter_dtor)(filter);
-}
-
-
-/*
- * UTF8 => wchar
- */
-static int
-filt_utf8_wchar(struct mbfl_output_filter* filter, int c)
-{
- int s;
- if(c < 0x80) {
- CK((*filter->output_function)(c, filter->data));
- filter->status = 0;
- } else if(c < 0xc0) {
- switch (filter->status & 0xff) {
- case 0x10: /* 2byte code 2nd char */
- case 0x21: /* 3byte code 3rd char */
- case 0x32: /* 4byte code 4th char */
- case 0x43: /* 5byte code 5th char */
- case 0x54: /* 6byte code 6th char */
- filter->status = 0;
- s = filter->cache + (c & 0x3f);
- if(s == 0) {
- s = UNDEFCHAR_UNICODE;
- }
- CK((*filter->output_function)(s, filter->data));
- break;
- case 0x20: /* 3byte code 2nd char */
- case 0x31: /* 4byte code 3rd char */
- case 0x42: /* 5byte code 4th char */
- case 0x53: /* 6byte code 5th char */
- filter->cache += ((c & 0x3f) << 6);
- filter->status++;
- break;
- case 0x30: /* 4byte code 2nd char */
- case 0x41: /* 5byte code 3rd char */
- case 0x52: /* 6byte code 4th char */
- filter->cache += ((c & 0x3f) << 12);
- filter->status++;
- break;
- case 0x40: /* 5byte code 2nd char */
- case 0x51: /* 6byte code 3rd char */
- filter->cache += ((c & 0x3f) << 18);
- filter->status++;
- break;
- case 0x50: /* 6byte code 2nd char */
- filter->cache += ((c & 0x3f) << 24);
- filter->status++;
- break;
- default:
- filter->status = 0;
- break;
- }
- } else if(c < 0xe0) { /* 2byte code first char */
- filter->status = 0x10;
- filter->cache = (c & 0x1f) << 6;
- } else if(c < 0xf0) { /* 3byte code first char */
- filter->status = 0x20;
- filter->cache = (c & 0xf) << 12;
- } else if(c < 0xf8) { /* 4byte code first char */
- filter->status = 0x30;
- filter->cache = (c & 0x7) << 18;
- } else if(c < 0xfc) { /* 5byte code first char */
- filter->status = 0x40;
- filter->cache = (c & 0x3) << 24;
- } else { /* 6 byte code first char */
- filter->status = 0x50;
- filter->cache = (c & 0x1) << 30;
- }
-
- return c;
-}
-
-/*
- * wchar => UTF-8
- */
-static int
-filt_wchar_utf8(struct mbfl_output_filter* filter, int c)
-{
- if(c < 0x80){
- CK((*filter->output_function)(c, filter->data));
- } else if(c < 0x800) {
- CK((*filter->output_function)(((c >> 6) & 0x1f) | 0xc0, filter->data));
- CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data));
- } else if(c < 0x10000) {
- CK((*filter->output_function)(((c >> 12) & 0x0f) | 0xe0, filter->data));
- CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data));
- } else if(c < 0x200000) {
- CK((*filter->output_function)(((c >> 18) & 0x07) | 0xf0, filter->data));
- CK((*filter->output_function)(((c >> 12) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data));
- } else if(c < 0x4000000) {
- CK((*filter->output_function)(((c >> 24) & 0x03) | 0xf8, filter->data));
- CK((*filter->output_function)(((c >> 18) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)(((c >> 12) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data));
- } else {
- CK((*filter->output_function)(((c >> 30) & 0x01) | 0xfc, filter->data));
- CK((*filter->output_function)(((c >> 24) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)(((c >> 18) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)(((c >> 12) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data));
- CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data));
- }
-
- return c;
-}
-
-/*
- * any => BASE64
- */
-static const char mbfl_b64_table[] =
-{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
-};
-
-static int
-filt_b64enc(struct mbfl_output_filter* filter, int c)
-{
- if (filter->status == 0) {
- filter->cache = (c & 0xff) << 16;
- filter->status++;
- } else if (filter->status == 1) {
- filter->cache |= (c & 0xff) << 8;
- filter->status++;
- } else {
- int s = filter->cache | (c & 0xff);
- filter->cache = 0;
- filter->status = 0;
- CK((*filter->output_function)(mbfl_b64_table[(s >> 18) & 0x3f], filter->data));
- CK((*filter->output_function)(mbfl_b64_table[(s >> 12) & 0x3f], filter->data));
- CK((*filter->output_function)(mbfl_b64_table[(s >> 6) & 0x3f], filter->data));
- CK((*filter->output_function)(mbfl_b64_table[s & 0x3f], filter->data));
- }
-
- return c;
-}
-
-static int
-filt_b64enc_flush(struct mbfl_output_filter* filter)
-{
- /* flush fragments */
- if (filter->status >= 1) {
- CK((*filter->output_function)(mbfl_b64_table[(filter->cache >> 18) & 0x3f], filter->data));
- CK((*filter->output_function)(mbfl_b64_table[(filter->cache >> 12) & 0x3f], filter->data));
- if (filter->status == 1) {
- CK((*filter->output_function)('=', filter->data));
- CK((*filter->output_function)('=', filter->data));
- } else {
- CK((*filter->output_function)(mbfl_b64_table[(filter->cache >> 6) & 0x3f], filter->data));
- CK((*filter->output_function)('=', filter->data));
- }
- }
- filter->status = 0;
- filter->cache = 0;
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_b64enc_dtor(struct mbfl_output_filter* filter)
-{
- (void)filt_b64enc_flush(filter);
-}
-
-/*
- * BASE64 => any
- */
-static int
-filt_b64dec(struct mbfl_output_filter* filter, int c)
-{
- int n = 0;
- char a;
-
- if(c == '=')
- return -1;
-
- if(c == '\r' || c == '\n' || c == ' ' || c == '\t')
- return c;
-
- while((a = mbfl_b64_table[n]) != '\0') {
- if(a == (char)c)
- break;
- n++;
- }
- n &= 0x3f;
-
- switch(filter->status) {
- case 0:
- filter->cache = n << 18;
- filter->status++;
- break;
- case 1:
- filter->cache |= n << 12;
- filter->status++;
- break;
- case 2:
- filter->cache |= n << 6;
- filter->status++;
- break;
- default:
- n |= filter->cache;
- filter->cache = 0;
- filter->status = 0;
- CK((*filter->output_function)((n >> 16) & 0xff, filter->data));
- CK((*filter->output_function)((n >> 8) & 0xff, filter->data));
- CK((*filter->output_function)(n & 0xff, filter->data));
- break;
- }
-
- return c;
-}
-
-static int
-filt_b64dec_flush(struct mbfl_output_filter* filter)
-{
- /* flush fragments */
- if (filter->status >= 2) {
- CK((*filter->output_function)((filter->cache >> 16) & 0xff, filter->data));
- if (filter->status == 3) {
- CK((*filter->output_function)((filter->cache >> 8) & 0xff, filter->data));
- }
- }
- filter->status = 0;
- filter->cache = 0;
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_b64dec_dtor(struct mbfl_output_filter* filter)
-{
- (void)filt_b64dec_flush(filter);
-}
-
-/*
- * any => Quoted-Printable
- */
-static int
-filt_qprintenc(struct mbfl_output_filter* filter, int c)
-{
- int s, n, m;
-
- switch(filter->status & 0xff) {
- case 0:
- filter->cache = c;
- filter->status &= ~0xffffff;
- filter->status |= 1;
- break;
- default:
- s = filter->cache;
- filter->cache = c;
- n = (filter->status & 0xffffff) >> 8;
- if (s == '=' ||s >= 0x80) {
- if(n >= 73)
- m = 2;
- else
- m = 3;
- } else if (filter->status & 0x1000000 &&
- (s == ' ' || s == '\t' || s == '?' || s == '_' || s == '(' || s == ')' || s == '\"')) {
- if(n >= 73)
- m = 2;
- else
- m = 3;
- } else if ((s == ' ' || s == '\t') && (c == '\r' || c == '\n')) {
- m = 3;
- } else if ((s == ' ' || s == '\t') && n >= 72) {
- m = 4;
- } else if (s == '\r' || s == '\n') {
- m = 5;
- } else if(n >= 75) {
- m = 1;
- } else {
- m = 0;
- }
-
- if (m == 1 || m == 2) {
- CK((*filter->output_function)('=', filter->data));
- }
- if (m == 1 || m == 2 || m == 5) {
- CK((*filter->output_function)('\r', filter->data));
- CK((*filter->output_function)('\n', filter->data));
- if((m == 5) && (c == '\r' || c == '\n')) {
- filter->status &= ~0xffffff;
- } else {
- filter->status &= ~0xffffff;
- filter->status |= 1;
- }
- }
- if(m <= 1) {
- CK((*filter->output_function)(s, filter->data));
- filter->status += 0x100;
- } else if(m == 2 || m == 3 || m == 4) {
- CK((*filter->output_function)('=', filter->data));
- n = (s >> 4) & 0xf;
- if(n < 10)
- n += '0';
- else
- n += 'A' - 10;
- CK((*filter->output_function)(n, filter->data));
- n = s & 0xf;
- if(n < 10)
- n += '0';
- else
- n += 'A' - 10;
- CK((*filter->output_function)(n, filter->data));
- filter->status += 0x300;
- }
- if(m == 4) {
- CK((*filter->output_function)('=', filter->data));
- CK((*filter->output_function)('\r', filter->data));
- CK((*filter->output_function)('\n', filter->data));
- filter->status = 1;
- }
- break;
- }
-
- return c;
-}
-
-static int
-filt_qprintenc_flush(struct mbfl_output_filter* filter)
-{
- /* flush filter cache */
- (*filter->vptr->filter_function)(filter, '\r');
- filter->status = 0;
- filter->cache = 0;
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_qprintenc_dtor(struct mbfl_output_filter* filter)
-{
- (void)filt_qprintenc_flush(filter);
-}
-
-/*
- * Quoted-Printable => any
- */
-static int
-filt_qprintdec(struct mbfl_output_filter* filter, int c)
-{
- int n;
- switch(filter->status) {
- case 1:
- if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
- filter->cache = c;
- filter->status = 2;
- } else if(c == '\r' || c == '\n') {
- filter->status = 3;
- } else {
- CK((*filter->output_function)('=', filter->data));
- CK((*filter->output_function)(c, filter->data));
- filter->status = 0;
- }
- break;
- case 2:
- n = filter->cache;
- if(n >= '0' && n <= '9') {
- n -= '0';
- } else {
- n -= ('A' + 10);
- }
- n <<= 4;
- if(c >= '0' && c <= '9') {
- n += (c - '0');
- } else if(c >= 'A' && c <= 'F') {
- n += (c - 'A') + 10;
- } else {
- CK((*filter->output_function)('=', filter->data));
- CK((*filter->output_function)(filter->cache, filter->data));
- n = c;
- }
- CK((*filter->output_function)(n, filter->data));
- filter->status = 0;
- break;
- case 3:
- if(c != '\n' && c != '\r') {
- CK((*filter->output_function)(c, filter->data));
- }
- filter->status = 0;
- break;
- default:
- if(c == '=') {
- filter->status = 1;
- } else {
- CK((*filter->output_function)(c, filter->data));
- }
- break;
- }
-
- return c;
-}
-
-static int
-filt_qprintdec_flush(struct mbfl_output_filter* filter)
-{
- /* flush fragments */
- if (filter->status == 1) {
- CK((*filter->output_function)('=', filter->data));
- } else if (filter->status == 2) {
- CK((*filter->output_function)('=', filter->data));
- CK((*filter->output_function)(filter->cache, filter->data));
- }
- filter->status = 0;
- filter->cache = 0;
-
- /* flush */
- return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0);
-}
-
-static void
-filt_qprintdec_dtor(struct mbfl_output_filter* filter)
-{
- (void)filt_qprintdec_flush(filter);
-}
-
-
-/*
- *
- * kanji code filter for output stream
- *
- */
-static struct filter_vtbl vtbl_pass = {
- filt_common_ctor,
- filt_common_dtor,
- filt_pass,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_eucjp_jis = {
- filt_common_ctor,
- filt_eucjp_jis_dtor,
- filt_eucjp_jis,
- filt_eucjp_jis_flush };
-
-static struct filter_vtbl vtbl_eucjp_sjis = {
- filt_common_ctor,
- filt_common_dtor,
- filt_eucjp_sjis,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_sjis_jis = {
- filt_common_ctor,
- filt_sjis_jis_dtor,
- filt_sjis_jis,
- filt_sjis_jis_flush };
-
-static struct filter_vtbl vtbl_sjis_eucjp = {
- filt_common_ctor,
- filt_common_dtor,
- filt_sjis_eucjp,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_jis_eucjp = {
- filt_common_ctor,
- filt_common_dtor,
- filt_jis_eucjp,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_jis_sjis = {
- filt_common_ctor,
- filt_common_dtor,
- filt_jis_sjis,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_eucjp_utf8 = {
- filt_common_ctor,
- filt_common_dtor,
- filt_eucjp_utf8,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_sjis_utf8 = {
- filt_common_ctor,
- filt_common_dtor,
- filt_sjis_utf8,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_jis_utf8 = {
- filt_common_ctor,
- filt_common_dtor,
- filt_jis_utf8,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_utf8_euc = {
- filt_common_ctor,
- filt_common_dtor,
- filt_utf8_euc,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_utf8_sjis = {
- filt_common_ctor,
- filt_common_dtor,
- filt_utf8_sjis,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_utf8_jis = {
- filt_common_ctor,
- filt_ucs_jis_dtor,
- filt_utf8_jis,
- filt_ucs_jis_flush };
-
-static struct filter_vtbl vtbl_euc_ucs = {
- filt_common_ctor,
- filt_common_dtor,
- filt_euc_ucs,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_ucs_euc = {
- filt_common_ctor,
- filt_common_dtor,
- filt_ucs_euc,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_euc_wchar = {
- filt_common_ctor,
- filt_common_dtor,
- filt_euc_wchar,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_wchar_euc = {
- filt_common_ctor,
- filt_common_dtor,
- filt_wchar_euc,
- filt_common_flush };
-
-static struct filter_vtbl vtbl_sjis_ucs = {
- filt_common_ctor,
- filt_common_dtor,