📄 mbfilter.c
字号:
} pc.from = from; pc.width = width - mkwidth; pc.outwidth = 0; pc.outchar = 0; pc.status = 0; pc.endpos = 0; /* feed data */ p = string->val; n = string->len; if (p != NULL) { while (n > 0) { n--; if ((*encoder->filter_function)(*p++, encoder) < 0) { break; } } mbfl_convert_filter_flush(encoder); if (pc.status != 0 && mkwidth > 0) { pc.width += mkwidth; while (n > 0) { if ((*encoder->filter_function)(*p++, encoder) < 0) { break; } n--; } mbfl_convert_filter_flush(encoder); if (pc.status != 1) { pc.status = 10; pc.device.pos = pc.endpos; mbfl_convert_filter_copy(pc.decoder_backup, pc.decoder); mbfl_convert_filter_reset(encoder, marker->no_encoding, mbfl_no_encoding_wchar); p = marker->val; n = marker->len; while (n > 0) { if ((*encoder->filter_function)(*p++, encoder) < 0) { break; } n--; } mbfl_convert_filter_flush(encoder); } } else if (pc.status != 0) { pc.device.pos = pc.endpos; mbfl_convert_filter_copy(pc.decoder_backup, pc.decoder); } mbfl_convert_filter_flush(pc.decoder); } result = mbfl_memory_device_result(&pc.device, result); mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(pc.decoder); mbfl_convert_filter_delete(pc.decoder_backup); return result;}/* * convert Hankaku and Zenkaku */struct collector_hantozen_data { mbfl_convert_filter *next_filter; int mode; int status; int cache;};static const unsigned char hankana2zenkata_table[64] = { 0x00,0x02,0x0C,0x0D,0x01,0xFB,0xF2,0xA1,0xA3,0xA5, 0xA7,0xA9,0xE3,0xE5,0xE7,0xC3,0xFC,0xA2,0xA4,0xA6, 0xA8,0xAA,0xAB,0xAD,0xAF,0xB1,0xB3,0xB5,0xB7,0xB9, 0xBB,0xBD,0xBF,0xC1,0xC4,0xC6,0xC8,0xCA,0xCB,0xCC, 0xCD,0xCE,0xCF,0xD2,0xD5,0xD8,0xDB,0xDE,0xDF,0xE0, 0xE1,0xE2,0xE4,0xE6,0xE8,0xE9,0xEA,0xEB,0xEC,0xED, 0xEF,0xF3,0x9B,0x9C};static const unsigned char hankana2zenhira_table[64] = { 0x00,0x02,0x0C,0x0D,0x01,0xFB,0x92,0x41,0x43,0x45, 0x47,0x49,0x83,0x85,0x87,0x63,0xFC,0x42,0x44,0x46, 0x48,0x4A,0x4B,0x4D,0x4F,0x51,0x53,0x55,0x57,0x59, 0x5B,0x5D,0x5F,0x61,0x64,0x66,0x68,0x6A,0x6B,0x6C, 0x6D,0x6E,0x6F,0x72,0x75,0x78,0x7B,0x7E,0x7F,0x80, 0x81,0x82,0x84,0x86,0x88,0x89,0x8A,0x8B,0x8C,0x8D, 0x8F,0x93,0x9B,0x9C};static const unsigned char zenkana2hankana_table[84][2] = { {0x67,0x00},{0x71,0x00},{0x68,0x00},{0x72,0x00},{0x69,0x00}, {0x73,0x00},{0x6A,0x00},{0x74,0x00},{0x6B,0x00},{0x75,0x00}, {0x76,0x00},{0x76,0x9E},{0x77,0x00},{0x77,0x9E},{0x78,0x00}, {0x78,0x9E},{0x79,0x00},{0x79,0x9E},{0x7A,0x00},{0x7A,0x9E}, {0x7B,0x00},{0x7B,0x9E},{0x7C,0x00},{0x7C,0x9E},{0x7D,0x00}, {0x7D,0x9E},{0x7E,0x00},{0x7E,0x9E},{0x7F,0x00},{0x7F,0x9E}, {0x80,0x00},{0x80,0x9E},{0x81,0x00},{0x81,0x9E},{0x6F,0x00}, {0x82,0x00},{0x82,0x9E},{0x83,0x00},{0x83,0x9E},{0x84,0x00}, {0x84,0x9E},{0x85,0x00},{0x86,0x00},{0x87,0x00},{0x88,0x00}, {0x89,0x00},{0x8A,0x00},{0x8A,0x9E},{0x8A,0x9F},{0x8B,0x00}, {0x8B,0x9E},{0x8B,0x9F},{0x8C,0x00},{0x8C,0x9E},{0x8C,0x9F}, {0x8D,0x00},{0x8D,0x9E},{0x8D,0x9F},{0x8E,0x00},{0x8E,0x9E}, {0x8E,0x9F},{0x8F,0x00},{0x90,0x00},{0x91,0x00},{0x92,0x00}, {0x93,0x00},{0x6C,0x00},{0x94,0x00},{0x6D,0x00},{0x95,0x00}, {0x6E,0x00},{0x96,0x00},{0x97,0x00},{0x98,0x00},{0x99,0x00}, {0x9A,0x00},{0x9B,0x00},{0x9C,0x00},{0x9C,0x00},{0x72,0x00}, {0x74,0x00},{0x66,0x00},{0x9D,0x00},{0x73,0x9E}};static intcollector_hantozen(int c, void* data){ int s, mode, n; struct collector_hantozen_data *pc = (struct collector_hantozen_data*)data; s = c; mode = pc->mode; if (mode & 0xf) { /* hankaku to zenkaku */ if ((mode & 0x1) && c >= 0x21 && c <= 0x7d && c != 0x22 && c != 0x27 && c != 0x5c) { /* all except <"> <'> <\> <~> */ s = c + 0xfee0; } else if ((mode & 0x2) && ((c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a))) { /* alpha */ s = c + 0xfee0; } else if ((mode & 0x4) && c >= 0x30 && c <= 0x39) { /* num */ s = c + 0xfee0; } else if ((mode & 0x8) && c == 0x20) { /* spase */ s = 0x3000; } } if (mode & 0xf0) { /* zenkaku to hankaku */ if ((mode & 0x10) && c >= 0xff01 && c <= 0xff5d && c != 0xff02 && c != 0xff07 && c!= 0xff3c) { /* all except <"> <'> <\> <~> */ s = c - 0xfee0; } else if ((mode & 0x20) && ((c >= 0xff21 && c <= 0xff3a) || (c >= 0xff41 && c <= 0xff5a))) { /* alpha */ s = c - 0xfee0; } else if ((mode & 0x40) && (c >= 0xff10 && c <= 0xff19)) { /* num */ s = c - 0xfee0; } else if ((mode & 0x80) && (c == 0x3000)) { /* spase */ s = 0x20; } else if ((mode & 0x10) && (c == 0x2212)) { /* MINUS SIGN */ s = 0x2d; } } if (mode & 0x300) { /* hankaku kana to zenkaku kana */ if ((mode & 0x100) && (mode & 0x800)) { /* hankaku kana to zenkaku katakana and glue voiced sound mark */ if (c >= 0xff61 && c <= 0xff9f) { if (pc->status) { n = (pc->cache - 0xff60) & 0x3f; if (c == 0xff9e && ((n >= 22 && n <= 36) || (n >= 42 && n <= 46))) { pc->status = 0; s = 0x3001 + hankana2zenkata_table[n]; } else if (c == 0xff9e && n == 19) { pc->status = 0; s = 0x30f4; } else if (c == 0xff9f && (n >= 42 && n <= 46)) { pc->status = 0; s = 0x3002 + hankana2zenkata_table[n]; } else { pc->status = 1; pc->cache = c; s = 0x3000 + hankana2zenkata_table[n]; } } else { pc->status = 1; pc->cache = c; return c; } } else { if (pc->status) { n = (pc->cache - 0xff60) & 0x3f; pc->status = 0; (*pc->next_filter->filter_function)(0x3000 + hankana2zenkata_table[n], pc->next_filter); } } } else if ((mode & 0x200) && (mode & 0x800)) { /* hankaku kana to zenkaku hirangana and glue voiced sound mark */ if (c >= 0xff61 && c <= 0xff9f) { if (pc->status) { n = (pc->cache - 0xff60) & 0x3f; if (c == 0xff9e && ((n >= 22 && n <= 36) || (n >= 42 && n <= 46))) { pc->status = 0; s = 0x3001 + hankana2zenhira_table[n]; } else if (c == 0xff9f && (n >= 42 && n <= 46)) { pc->status = 0; s = 0x3002 + hankana2zenhira_table[n]; } else { pc->status = 1; pc->cache = c; s = 0x3000 + hankana2zenhira_table[n]; } } else { pc->status = 1; pc->cache = c; return c; } } else { if (pc->status) { n = (pc->cache - 0xff60) & 0x3f; pc->status = 0; (*pc->next_filter->filter_function)(0x3000 + hankana2zenhira_table[n], pc->next_filter); } } } else if ((mode & 0x100) && c >= 0xff61 && c <= 0xff9f) { /* hankaku kana to zenkaku katakana */ s = 0x3000 + hankana2zenkata_table[c - 0xff60]; } else if ((mode & 0x200) && c >= 0xff61 && c <= 0xff9f) { /* hankaku kana to zenkaku hirangana */ s = 0x3000 + hankana2zenhira_table[c - 0xff60]; } } if (mode & 0x3000) { /* Zenkaku kana to hankaku kana */ if ((mode & 0x1000) && c >= 0x30a1 && c <= 0x30f4) { /* Zenkaku katakana to hankaku kana */ n = c - 0x30a1; if (zenkana2hankana_table[n][1] != 0) { (*pc->next_filter->filter_function)(0xff00 + zenkana2hankana_table[n][0], pc->next_filter); s = 0xff00 + zenkana2hankana_table[n][1]; } else { s = 0xff00 + zenkana2hankana_table[n][0]; } } else if ((mode & 0x2000) && c >= 0x3041 && c <= 0x3093) { /* Zenkaku hirangana to hankaku kana */ n = c - 0x3041; if (zenkana2hankana_table[n][1] != 0) { (*pc->next_filter->filter_function)(0xff00 + zenkana2hankana_table[n][0], pc->next_filter); s = 0xff00 + zenkana2hankana_table[n][1]; } else { s = 0xff00 + zenkana2hankana_table[n][0]; } } else if (c == 0x3001) { s = 0xff64; /* HALFWIDTH IDEOGRAPHIC COMMA */ } else if (c == 0x3002) { s = 0xff61; /* HALFWIDTH IDEOGRAPHIC FULL STOP */ } else if (c == 0x300c) { s = 0xff62; /* HALFWIDTH LEFT CORNER BRACKET */ } else if (c == 0x300d) { s = 0xff63; /* HALFWIDTH RIGHT CORNER BRACKET */ } else if (c == 0x309b) { s = 0xff9e; /* HALFWIDTH KATAKANA VOICED SOUND MARK */ } else if (c == 0x309c) { s = 0xff9f; /* HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK */ } else if (c == 0x30fc) { s = 0xff70; /* HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK */ } else if (c == 0x30fb) { s = 0xff65; /* HALFWIDTH KATAKANA MIDDLE DOT */ } } else if (mode & 0x30000) { if ((mode & 0x10000) && c >= 0x3041 && c <= 0x3093) { /* Zenkaku hirangana to Zenkaku katakana */ s = c + 0x60; } else if ((mode & 0x20000) && c >= 0x30a1 && c <= 0x30f3) { /* Zenkaku katakana to Zenkaku hirangana */ s = c - 0x60; } } if (mode & 0x100000) { /* special ascii to symbol */ if (c == 0x5c) { s = 0xffe5; /* FULLWIDTH YEN SIGN */ } else if (c == 0xa5) { /* YEN SIGN */ s = 0xffe5; /* FULLWIDTH YEN SIGN */ } else if (c == 0x7e) { s = 0xffe3; /* FULLWIDTH MACRON */ } else if (c == 0x203e) { /* OVERLINE */ s = 0xffe3; /* FULLWIDTH MACRON */ } else if (c == 0x27) { s = 0x2019; /* RIGHT SINGLE QUOTATION MARK */ } else if (c == 0x22) { s = 0x201d; /* RIGHT DOUBLE QUOTATION MARK */ } } else if (mode & 0x200000) { /* special symbol to ascii */ if (c == 0xffe5) { /* FULLWIDTH YEN SIGN */ s = 0x5c; } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ s = 0x5c; } else if (c == 0xffe3) { /* FULLWIDTH MACRON */ s = 0x7e; } else if (c == 0x203e) { /* OVERLINE */ s = 0x7e; } else if (c == 0x2018) { /* LEFT SINGLE QUOTATION MARK*/ s = 0x27; } else if (c == 0x2019) { /* RIGHT SINGLE QUOTATION MARK */ s = 0x27; } else if (c == 0x201c) { /* LEFT DOUBLE QUOTATION MARK */ s = 0x22; } else if (c == 0x201d) { /* RIGHT DOUBLE QUOTATION MARK */ s = 0x22; } } if (mode & 0x400000) { /* special ascii to symbol */ if (c == 0x5c) { s = 0xff3c; /* FULLWIDTH REVERSE SOLIDUS */ } else if (c == 0x7e) { s = 0xff5e; /* FULLWIDTH TILDE */ } else if (c == 0x27) { s = 0xff07; /* FULLWIDTH APOSTROPHE */ } else if (c == 0x22) { s = 0xff02; /* FULLWIDTH QUOTATION MARK */ } } else if (mode & 0x800000) { /* special symbol to ascii */ if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ s = 0x5c; } else if (c == 0xff5e) { /* FULLWIDTH TILDE */ s = 0x7e; } else if (c == 0xff07) { /* FULLWIDTH APOSTROPHE */ s = 0x27; } else if (c == 0xff02) { /* FULLWIDTH QUOTATION MARK */ s = 0x22; } } return (*pc->next_filter->filter_function)(s, pc->next_filter);}static intcollector_hantozen_flush(struct collector_hantozen_data *pc){ int ret, n; ret = 0; if (pc->status) { n = (pc->cache - 0xff60) & 0x3f; if (pc->mode & 0x100) { /* hankaku kana to zenkaku katakana */ ret = (*pc->next_filter->filter_function)(0x3000 + hankana2zenkata_table[n], pc->next_filter); } else if (pc->mode & 0x200) { /* hankaku kana to zenkaku hirangana */ ret = (*pc->next_filter->filter_function)(0x3000 + hankana2zenhira_table[n], pc->next_filter); } pc->status = 0; } return ret;}mbfl_string *mbfl_ja_jp_hantozen( mbfl_string *string, mbfl_string *result, int mode){ int n; unsigned char *p; const mbfl_encoding *encoding; mbfl_memory_device device; struct collector_hantozen_data pc; mbfl_convert_filter *decoder; mbfl_convert_filter *encoder; /* initialize */ if (string == NULL || result == NULL) { return NULL; } encoding = mbfl_no2encoding(string->no_encoding); if (encoding == NULL) { return NULL; } mbfl_memory_device_init(&device, string->len, 0); mbfl_string_init(result); result->no_language = string->no_language; result->no_encoding = string->no_encoding; decoder = mbfl_convert_filter_new( mbfl_no_encoding_wchar, string->no_encoding, mbfl_memory_device_output, 0, &device); encoder = mbfl_convert_filter_new( string->no_encoding, mbfl_no_encoding_wchar, collector_hantozen, 0, &pc); if (decoder == NULL || encoder == NULL) { mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(decoder); return NULL; } pc.next_filter = decoder; pc.mode = mode; pc.status = 0; pc.cache = 0; /* feed data */ p = string->val; n = string->len; if (p != NULL) { while (n > 0) { if ((*encoder->filter_function)(*p++, encoder) < 0) { break; } n--; } } mbfl_convert_filter_flush(encoder); collector_hantozen_flush(&pc); mbfl_convert_filter_flush(decoder); result = mbfl_memory_device_result(&device, result); mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(decoder); return result;}/* * MIME header encode */struct mime_header_encoder_data { mbfl_convert_filter *conv1_filter; mbfl_convert_filter *block_filter; mbfl_convert_filter *conv2_filter; mbfl_convert_filter *conv2_filter_backup; mbfl_convert_filter *encod_filter; mbfl_convert_filter *encod_filter_backup; mbfl_memory_device outdev; mbfl_memory_device tmpdev; int status1; int status2; int prevpos; int linehead; int firstindent; int encnamelen; int lwsplen; char encname[128]; char lwsp[16];};static intmime_header_encoder_block_collector(int c, void *data){ int n; struct mime_header_encoder_data *pe = (struct mime_header_encoder_data *)data; switch (pe->status2) { case 1: /* encoded word */ pe->prevpos = pe->outdev.pos; mbfl_convert_filter_copy(pe->conv2_filter, pe->conv2_filter_backup); mbfl_convert_filter_copy(pe->encod_filter, pe->encod_filter_backup); (*pe->conv2_filter->filter_function)(c, pe->conv2_filter); (*pe->conv2_filter->filter_flush)(pe->conv2_filter); (*pe->encod_filter->filter_flush)(pe->encod_filter); n = pe->outdev.pos - pe->linehead + pe->firstindent; pe->outdev.pos = pe->prevpos; mbfl_convert_filter_copy(pe->conv2_filter_backup, pe->conv2_filter); mbfl_convert_filter_copy(pe->encod_filter_backup, pe->encod_filter); if (n >= 74) { (*pe->conv2_filter->filter_flush)(pe->conv2_filter); (*pe->encod_filter->filter_flush)(pe->encod_filter); mbfl_memory_device_strncat(&pe->outdev, "\x3f\x3d", 2); /* ?= */ mbfl_memory_device_strncat(&pe->outdev, pe->lwsp, pe->lwsplen); pe->linehead = pe->outdev.pos; pe->firstindent = 0; mbfl_memory_device_strncat(&pe->outdev, pe->encname, pe->encnamelen); c = (*pe->conv2_filter->filter_function)(c, pe->conv2_filter); } else { c = (*pe->conv2_filter->filter_function)(c, pe->conv2_filter); } break; default: mbfl_memory_device_strncat(&pe->outdev, pe->encname, pe->encnamelen); c = (*pe->conv2_filter->filter_function)(c, pe->conv2_filter); pe->status2 = 1; break; } return c;}static intmime_header_encoder_collector(int c, void *data){ static int qp_table[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */ 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 1, 0, 1, /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xA0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xB0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xC0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xD0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xE0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0xF0 */ }; int n; struct mime_header_encoder_data *pe = (struct mime_header_encoder_data *)data; switch (pe->status1) { case 11: /* encoded word */ (*pe->block_filter->filter_function)(c, pe->block_filter); break; default: /* ASCII */ if (c <= 0x00ff && !qp_table[(c & 0xff)]) { /* ordinary characters */ mbfl_memory_device_output(c, &pe->tmpdev); pe->status1 = 1; } else if (pe->status1 == 0 && c == 0x20) { /* repeat SPACE */ mbfl_memory_device_output(c, &pe->tmpdev); } else { if (pe->tmpdev.pos < 74 && c == 0x20) { n = pe->outdev.pos - pe->linehead + pe->tmpdev.pos + pe->firstindent; if (n > 74) { mbfl_memory_device_strncat(&pe->outdev, pe->lwsp, pe->lwsplen); /* LWSP */ pe->linehead = pe->outdev.pos; pe->firstindent = 0; } else if (pe->outdev.pos > 0) { mbfl_memory_device_output(0x20, &pe->outdev); } mbfl_memory_device_devcat(&pe->outdev, &pe->tmpdev); mbfl_memory_device_reset(&pe->tmpdev); pe->status1 = 0; } else { n = pe->outdev.pos - pe->linehead + pe->encnamelen + pe->firstindent; if (n > 60) { mbfl_memory_device_strncat(&pe->outdev, pe->lwsp, pe->lwsplen); /* LWSP */ pe->linehead = pe->outdev.pos; pe->firstindent = 0; } else if (pe->outdev.pos > 0) { mbfl_memory_device_output(0x20, &pe->outdev); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -