diff options
Diffstat (limited to 'ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c')
-rw-r--r-- | ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c | 1034 |
1 files changed, 474 insertions, 560 deletions
diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c index 68084a0e0a..34acccbc2d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c @@ -36,120 +36,103 @@ #include "emoji2uni.h" extern int mbfl_bisec_srch2(int w, const unsigned short tbl[], int n); -extern int mbfl_filt_ident_sjis(int c, mbfl_identify_filter *filter); extern const unsigned char mblen_table_sjis[]; +static int mbfl_filt_conv_sjis_wchar_flush(mbfl_convert_filter *filter); + static const char *mbfl_encoding_sjis_docomo_aliases[] = {"SJIS-DOCOMO", "shift_jis-imode", "x-sjis-emoji-docomo", NULL}; static const char *mbfl_encoding_sjis_kddi_aliases[] = {"SJIS-KDDI", "shift_jis-kddi", "x-sjis-emoji-kddi", NULL}; static const char *mbfl_encoding_sjis_sb_aliases[] = {"SJIS-SOFTBANK", "shift_jis-softbank", "x-sjis-emoji-softbank", NULL}; const mbfl_encoding mbfl_encoding_sjis_docomo = { - mbfl_no_encoding_sjis_docomo, - "SJIS-Mobile#DOCOMO", - "Shift_JIS", - (const char *(*)[])&mbfl_encoding_sjis_docomo_aliases, + mbfl_no_encoding_sjis_docomo, + "SJIS-Mobile#DOCOMO", + "Shift_JIS", + mbfl_encoding_sjis_docomo_aliases, mblen_table_sjis, - MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE, + MBFL_ENCTYPE_GL_UNSAFE, &vtbl_sjis_docomo_wchar, &vtbl_wchar_sjis_docomo }; const mbfl_encoding mbfl_encoding_sjis_kddi = { - mbfl_no_encoding_sjis_kddi, - "SJIS-Mobile#KDDI", - "Shift_JIS", - (const char *(*)[])&mbfl_encoding_sjis_kddi_aliases, + mbfl_no_encoding_sjis_kddi, + "SJIS-Mobile#KDDI", + "Shift_JIS", + mbfl_encoding_sjis_kddi_aliases, mblen_table_sjis, - MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE, + MBFL_ENCTYPE_GL_UNSAFE, &vtbl_sjis_kddi_wchar, &vtbl_wchar_sjis_kddi }; const mbfl_encoding mbfl_encoding_sjis_sb = { - mbfl_no_encoding_sjis_sb, - "SJIS-Mobile#SOFTBANK", - "Shift_JIS", - (const char *(*)[])&mbfl_encoding_sjis_sb_aliases, + mbfl_no_encoding_sjis_sb, + "SJIS-Mobile#SOFTBANK", + "Shift_JIS", + mbfl_encoding_sjis_sb_aliases, mblen_table_sjis, - MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE, + MBFL_ENCTYPE_GL_UNSAFE, &vtbl_sjis_sb_wchar, &vtbl_wchar_sjis_sb }; -const struct mbfl_identify_vtbl vtbl_identify_sjis_docomo = { - mbfl_no_encoding_sjis_docomo, - mbfl_filt_ident_common_ctor, - mbfl_filt_ident_sjis -}; - -const struct mbfl_identify_vtbl vtbl_identify_sjis_kddi = { - mbfl_no_encoding_sjis_kddi, - mbfl_filt_ident_common_ctor, - mbfl_filt_ident_sjis -}; - -const struct mbfl_identify_vtbl vtbl_identify_sjis_sb = { - mbfl_no_encoding_sjis_sb, - mbfl_filt_ident_common_ctor, - mbfl_filt_ident_sjis -}; - const struct mbfl_convert_vtbl vtbl_sjis_docomo_wchar = { - mbfl_no_encoding_sjis_docomo, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, + mbfl_no_encoding_sjis_docomo, + mbfl_no_encoding_wchar, + mbfl_filt_conv_common_ctor, + NULL, + mbfl_filt_conv_sjis_mobile_wchar, + mbfl_filt_conv_sjis_wchar_flush, NULL, - mbfl_filt_conv_sjis_mobile_wchar, - mbfl_filt_conv_common_flush, - NULL, }; const struct mbfl_convert_vtbl vtbl_wchar_sjis_docomo = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis_docomo, - mbfl_filt_conv_common_ctor, + mbfl_no_encoding_wchar, + mbfl_no_encoding_sjis_docomo, + mbfl_filt_conv_common_ctor, + NULL, + mbfl_filt_conv_wchar_sjis_mobile, + mbfl_filt_conv_sjis_mobile_flush, NULL, - mbfl_filt_conv_wchar_sjis_mobile, - mbfl_filt_conv_sjis_mobile_flush, - NULL, }; const struct mbfl_convert_vtbl vtbl_sjis_kddi_wchar = { - mbfl_no_encoding_sjis_kddi, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, + mbfl_no_encoding_sjis_kddi, + mbfl_no_encoding_wchar, + mbfl_filt_conv_common_ctor, + NULL, + mbfl_filt_conv_sjis_mobile_wchar, + mbfl_filt_conv_sjis_wchar_flush, NULL, - mbfl_filt_conv_sjis_mobile_wchar, - mbfl_filt_conv_common_flush, - NULL, }; const struct mbfl_convert_vtbl vtbl_wchar_sjis_kddi = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis_kddi, - mbfl_filt_conv_common_ctor, + mbfl_no_encoding_wchar, + mbfl_no_encoding_sjis_kddi, + mbfl_filt_conv_common_ctor, NULL, - mbfl_filt_conv_wchar_sjis_mobile, + mbfl_filt_conv_wchar_sjis_mobile, mbfl_filt_conv_sjis_mobile_flush, NULL, }; const struct mbfl_convert_vtbl vtbl_sjis_sb_wchar = { - mbfl_no_encoding_sjis_sb, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, + mbfl_no_encoding_sjis_sb, + mbfl_no_encoding_wchar, + mbfl_filt_conv_common_ctor, + NULL, + mbfl_filt_conv_sjis_mobile_wchar, + mbfl_filt_conv_sjis_wchar_flush, NULL, - mbfl_filt_conv_sjis_mobile_wchar, - mbfl_filt_conv_common_flush, - NULL, }; const struct mbfl_convert_vtbl vtbl_wchar_sjis_sb = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis_sb, - mbfl_filt_conv_common_ctor, + mbfl_no_encoding_wchar, + mbfl_no_encoding_sjis_sb, + mbfl_filt_conv_common_ctor, NULL, - mbfl_filt_conv_wchar_sjis_mobile, + mbfl_filt_conv_wchar_sjis_mobile, mbfl_filt_conv_sjis_mobile_flush, NULL, }; @@ -195,467 +178,431 @@ const unsigned short mbfl_kddi2uni_pua_b[8][3] = { {0x27e7, 0x2863, 0xf080}, }; +/* Regional Indicator Unicode codepoints are from 0x1F1E6-0x1F1FF + * These correspond to the letters A-Z + * To display the flag emoji for a country, two unicode codepoints are combined, + * which correspond to the two-letter code for that country + * This macro converts uppercase ASCII values to Regional Indicator codepoints */ #define NFLAGS(c) (0x1F1A5+(int)(c)) #define CK(statement) do { if ((statement) < 0) return (-1); } while (0) -#define SJIS_ENCODE(c1,c2,s1,s2) \ - do { \ - s1 = c1; \ - s1--; \ - s1 >>= 1; \ - if ((c1) < 0x5f) { \ - s1 += 0x71; \ - } else { \ - s1 += 0xb1; \ - } \ - s2 = c2; \ - if ((c1) & 1) { \ - if ((c2) < 0x60) { \ - s2--; \ - } \ - s2 += 0x20; \ - } else { \ - s2 += 0x7e; \ - } \ +#define SJIS_ENCODE(c1,c2,s1,s2) \ + do { \ + s1 = ((c1 - 1) >> 1) + ((c1) < 0x5F ? 0x71 : 0xB1); \ + s2 = c2; \ + if ((c1) & 1) { \ + if ((c2) < 0x60) { \ + s2--; \ + } \ + s2 += 0x20; \ + } else { \ + s2 += 0x7e; \ + } \ } while (0) -#define SJIS_DECODE(c1,c2,s1,s2) \ - do { \ - s1 = c1; \ - if (s1 < 0xa0) { \ - s1 -= 0x81; \ - } else { \ - s1 -= 0xc1; \ - } \ - s1 <<= 1; \ - s1 += 0x21; \ - s2 = c2; \ - if (s2 < 0x9f) { \ - if (s2 < 0x7f) { \ - s2++; \ - } \ - s2 -= 0x20; \ - } else { \ - s1++; \ - s2 -= 0x7e; \ - } \ +#define SJIS_DECODE(c1,c2,s1,s2) \ + do { \ + if (c1 < 0xa0) { \ + s1 = ((c1 - 0x81) << 1) + 0x21; \ + } else { \ + s1 = ((c1 - 0xc1) << 1) + 0x21; \ + } \ + s2 = c2; \ + if (c2 < 0x9f) { \ + if (c2 < 0x7f) { \ + s2++; \ + } \ + s2 -= 0x20; \ + } else { \ + s1++; \ + s2 -= 0x7e; \ + } \ } while (0) -#define CODE2JIS(c1,c2,s1,s2) \ - c1 = (s1)/94+0x21; \ - c2 = (s1)-94*((c1)-0x21)+0x21; \ - s1 = ((c1) << 8) | (c2); \ +/* (ku*94)+ten value -> Shift-JIS byte sequence */ +#define CODE2JIS(c1,c2,s1,s2) \ + c1 = (s1)/94+0x21; \ + c2 = (s1)-94*((c1)-0x21)+0x21; \ + s1 = ((c1) << 8) | (c2); \ s2 = 1 -int -mbfilter_conv_map_tbl(int c, int *w, const unsigned short map[][3], int n) +int mbfilter_conv_map_tbl(int c, int *w, const unsigned short map[][3], int n) { - int i, match = 0; - - for (i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { if (map[i][0] <= c && c <= map[i][1]) { *w = c - map[i][0] + map[i][2]; - match = 1; - break; + return 1; } } - return match; + return 0; } -int -mbfilter_conv_r_map_tbl(int c, int *w, const unsigned short map[][3], int n) +int mbfilter_conv_r_map_tbl(int c, int *w, const unsigned short map[][3], int n) { - int i, match = 0; - - for (i = 0; i < n; i++) { + /* Convert in reverse direction */ + for (int i = 0; i < n; i++) { if (map[i][2] <= c && c <= map[i][2] - map[i][0] + map[i][1]) { *w = c + map[i][0] - map[i][2]; - match = 1; - break; + return 1; } } - return match; + return 0; } -int -mbfilter_sjis_emoji_docomo2unicode(int s, int *snd) +/* number -> (ku*94)+ten value for telephone keypad character */ +#define DOCOMO_KEYPAD(n) ((n) == 0 ? 0x296F : (0x2965 + (n))) +#define DOCOMO_KEYPAD_HASH 0x2964 + +#define EMIT_KEYPAD_EMOJI(c) do { *snd = (c); return 0x20E3; } while(0) + +/* Unicode codepoints for emoji are above 0x1F000, but we only store 16-bits + * in our tables. Therefore, add 0x10000 to recover the true values. + * + * Again, for some emoji which are not supported by Unicode, we use codepoints + * in the Private Use Area above 0xFE000. Again, add 0xF0000 to recover the + * true value. */ +static inline int convert_emoji_cp(int cp) { - int w = s; + if (cp > 0xF000) + return cp + 0x10000; + else if (cp > 0xE000) + return cp + 0xF0000; + return cp; +} + +int mbfilter_sjis_emoji_docomo2unicode(int s, int *snd) +{ + /* All three mobile vendors had emoji for numbers on a telephone keypad + * Unicode doesn't have those, but it has a combining character which puts + * a 'keypad button' around the following character, making it look like + * a key on a telephone or keyboard. That combining char is codepoint 0x20E3. */ if (s >= mb_tbl_code2uni_docomo1_min && s <= mb_tbl_code2uni_docomo1_max) { - if (s >= mb_tbl_code2uni_docomo1_min + 0x00a2 && - s <= mb_tbl_code2uni_docomo1_min + 0x00ad && - s != mb_tbl_code2uni_docomo1_min + 0x00a3) { - w = 0x20E3; - *snd = mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min]; - if (*snd > 0xf000) { - *snd += 0x10000; - } + if ((s >= DOCOMO_KEYPAD(1) && s <= DOCOMO_KEYPAD(9)) || s == DOCOMO_KEYPAD(0) || s == DOCOMO_KEYPAD_HASH) { + EMIT_KEYPAD_EMOJI(convert_emoji_cp(mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min])); } else { - w = mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min]; - if (w > 0xf000) { - w += 0x10000; - } else if (w > 0xe000) { /* unsupported by Unicode 6.0 */ - w += 0xf0000; - } *snd = 0; - if (!w) { - w = s; - } + return convert_emoji_cp(mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min]); } } - - return w; + return 0; } -int -mbfilter_sjis_emoji_kddi2unicode(int s, int *snd) -{ - int w = s, si, c; - const int nflags_order_kddi[] = {3, 1, 5, 4, 0, 7}; +#define EMIT_FLAG_EMOJI(country) do { *snd = NFLAGS((country)[0]); return NFLAGS((country)[1]); } while(0) + +static const char nflags_kddi[6][2] = {"FR", "DE", "IT", "GB", "CN", "KR"}; - *snd = 0; +int mbfilter_sjis_emoji_kddi2unicode(int s, int *snd) +{ if (s >= mb_tbl_code2uni_kddi1_min && s <= mb_tbl_code2uni_kddi1_max) { - si = s - mb_tbl_code2uni_kddi1_min; - if (si == 0x0008) { /* ES */ - *snd = NFLAGS(nflags_s[2][0]); w = NFLAGS(nflags_s[2][1]); - } else if (si == 0x0009) { /* RU */ - *snd = NFLAGS(nflags_s[8][0]); w = NFLAGS(nflags_s[8][1]); - } else if (si >= 0x008d && si <= 0x0092) { - c = nflags_order_kddi[si-0x008d]; - *snd = NFLAGS(nflags_s[c][0]); w = NFLAGS(nflags_s[c][1]); - } else if (si == 0x0104) { - *snd = 0x0023; w = 0x20E3; + if (s == 0x24C0) { /* Spain */ + EMIT_FLAG_EMOJI("ES"); + } else if (s == 0x24C1) { /* Russia */ + EMIT_FLAG_EMOJI("RU"); + } else if (s >= 0x2545 && s <= 0x254A) { + EMIT_FLAG_EMOJI(nflags_kddi[s - 0x2545]); + } else if (s == 0x25BC) { + EMIT_KEYPAD_EMOJI('#'); } else { - w = mb_tbl_code2uni_kddi1[si]; - if (w > 0xf000) { - w += 0x10000; - } else if (w > 0xe000) { /* unsupported by Unicode 6.0 */ - w += 0xf0000; - } + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_kddi1[s - mb_tbl_code2uni_kddi1_min]); } } else if (s >= mb_tbl_code2uni_kddi2_min && s <= mb_tbl_code2uni_kddi2_max) { - si = s - mb_tbl_code2uni_kddi2_min; - if (si == 100) { /* JP */ - *snd = NFLAGS(nflags_s[6][0]); w = NFLAGS(nflags_s[6][1]); - } else if (si >= 0x00ba && si <= 0x00c2) { - *snd = si-0x00ba+0x0031; w = 0x20E3; - } else if (si == 0x010b) { /* US */ - *snd = NFLAGS(nflags_s[9][0]); w = NFLAGS(nflags_s[9][1]); - } else if (si == 0x0144) { - *snd = 0x0030; w = 0x20E3; + if (s == 0x2750) { /* Japan */ + EMIT_FLAG_EMOJI("JP"); + } else if (s >= 0x27A6 && s <= 0x27AE) { + EMIT_KEYPAD_EMOJI(s - 0x27A6 + '1'); + } else if (s == 0x27F7) { /* United States */ + EMIT_FLAG_EMOJI("US"); + } else if (s == 0x2830) { + EMIT_KEYPAD_EMOJI('0'); } else { - w = mb_tbl_code2uni_kddi2[si]; - if (w > 0xf000) { - w += 0x10000; - } else if (w > 0xe000) { /* unsupported by Unicode 6.0 */ - w += 0xf0000; - } + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_kddi2[s - mb_tbl_code2uni_kddi2_min]); } } - return w; + return 0; } -int -mbfilter_sjis_emoji_sb2unicode(int s, int *snd) +static const char nflags_sb[10][2] = {"JP", "US", "FR", "DE", "IT", "GB", "ES", "RU", "CN", "KR"}; + +int mbfilter_sjis_emoji_sb2unicode(int s, int *snd) { - int w = s, si, c; - const int nflags_order_sb[10] = {6, 9, 3, 1, 5, 4, 2, 8, 0, 7}; - - *snd = 0; - if (s >= mb_tbl_code2uni_sb1_min && s <= mb_tbl_code2uni_sb1_max) { - si = s - mb_tbl_code2uni_sb1_min; - if (si == 0x006e || (si >= 0x007a && si <= 0x0083)) { - *snd = mb_tbl_code2uni_sb1[si]; - if (*snd > 0xf000) { - *snd += 0x10000; - } - w = 0x20E3; + if (s >= mb_tbl_code2uni_sb1_min && s <= mb_tbl_code2uni_sb1_max) { + if (s == 0x2817 || (s >= 0x2823 && s <= 0x282C)) { + EMIT_KEYPAD_EMOJI(mb_tbl_code2uni_sb1[s - mb_tbl_code2uni_sb1_min]); } else { - w = mb_tbl_code2uni_sb1[si]; - if (w > 0xf000) { - w += 0x10000; - } else if (w > 0xe000) { /* unsupported by Unicode 6.0 */ - w += 0xf0000; - } + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_sb1[s - mb_tbl_code2uni_sb1_min]); } } else if (s >= mb_tbl_code2uni_sb2_min && s <= mb_tbl_code2uni_sb2_max) { - si = s - mb_tbl_code2uni_sb2_min; - w = mb_tbl_code2uni_sb2[si]; - if (w > 0xf000) { - w += 0x10000; - } else if (w > 0xe000) { /* unsupported by Unicode 6.0 */ - w += 0xf0000; - } + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_sb2[s - mb_tbl_code2uni_sb2_min]); } else if (s >= mb_tbl_code2uni_sb3_min && s <= mb_tbl_code2uni_sb3_max) { - si = s - mb_tbl_code2uni_sb3_min; - if (si >= 0x0069 && si <= 0x0072) { - c = nflags_order_sb[si-0x0069]; - *snd = NFLAGS(nflags_s[c][0]); w = NFLAGS(nflags_s[c][1]); + if (s >= 0x2B02 && s <= 0x2B0B) { + EMIT_FLAG_EMOJI(nflags_sb[s - 0x2B02]); } else { - w = mb_tbl_code2uni_sb3[si]; - if (w > 0xf000) { - w += 0x10000; - } else if (w > 0xe000) { /* unsupported by Unicode 6.0 */ - w += 0xf0000; - } + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_sb3[s - mb_tbl_code2uni_sb3_min]); } } - return w; + return 0; } int mbfilter_unicode2sjis_emoji_docomo(int c, int *s1, mbfl_convert_filter *filter) { - int i, match = 0, c1s; - + /* When converting SJIS-Mobile to Unicode, we convert keypad symbol emoji + * to a sequence of 2 codepoints, one of which is a combining character which + * adds the 'key' image around the other + * + * In the other direction, look for such sequences and convert them to a + * single emoji */ if (filter->status == 1) { - c1s = filter->cache; - filter->cache = 0; - filter->status = 0; + int c1 = filter->cache; + filter->cache = filter->status = 0; if (c == 0x20E3) { - if (c1s == 0x0023) { + if (c1 == '#') { *s1 = 0x2964; - match = 1; - } else if (c1s == 0x0030) { - *s1 = 0x296f; - match = 1; - } else if (c1s >= 0x0031 && c1s <= 0x0039) { - *s1 = 0x2966 + (c1s - 0x0031); - match = 1; + } else if (c1 == '0') { + *s1 = 0x296F; + } else { /* Previous character was '1'-'9' */ + *s1 = 0x2966 + (c1 - '1'); } + return 1; } else { - CK((*filter->output_function)(c1s, filter->data)); - } - } else { - if (c == 0x0023 || (c >= 0x0030 && c<=0x0039)) { - filter->status = 1; - filter->cache = c; - *s1 = -1; - return match; - } - - if (c == 0x00A9) { - *s1 = 0x29b5; match = 1; - } else if (c == 0x00AE) { - *s1 = 0x29ba; match = 1; - } else if (c >= mb_tbl_uni_docomo2code2_min && c <= mb_tbl_uni_docomo2code2_max) { - i = mbfl_bisec_srch2(c, mb_tbl_uni_docomo2code2_key, mb_tbl_uni_docomo2code2_len); - if (i >= 0) { - *s1 = mb_tbl_uni_docomo2code2_value[i]; - match = 1; - } - } else if (c >= mb_tbl_uni_docomo2code3_min && c <= mb_tbl_uni_docomo2code3_max) { - i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_docomo2code3_key, mb_tbl_uni_docomo2code3_len); - if (i >= 0) { - *s1 = mb_tbl_uni_docomo2code3_value[i]; - match = 1; - } - } else if (c >= mb_tbl_uni_docomo2code5_min && c <= mb_tbl_uni_docomo2code5_max) { - i = mbfl_bisec_srch2(c - 0xf0000, mb_tbl_uni_docomo2code5_key, mb_tbl_uni_docomo2code5_len); - if (i >= 0) { - *s1 = mb_tbl_uni_docomo2code5_val[i]; - match = 1; - } + /* This character wasn't combining character to make keypad symbol, + * so pass the previous character through... and proceed to process the + * current character as usual + * (Single-byte ASCII characters are valid in Shift-JIS...) */ + CK((*filter->output_function)(c1, filter->data)); } } - return match; + if (c == '#' || (c >= '0' && c <= '9')) { + filter->status = 1; + filter->cache = c; + return 0; + } + + if (c == 0xA9) { /* Copyright sign */ + *s1 = 0x29B5; + return 1; + } else if (c == 0x00AE) { /* Registered sign */ + *s1 = 0x29BA; + return 1; + } else if (c >= mb_tbl_uni_docomo2code2_min && c <= mb_tbl_uni_docomo2code2_max) { + int i = mbfl_bisec_srch2(c, mb_tbl_uni_docomo2code2_key, mb_tbl_uni_docomo2code2_len); + if (i >= 0) { + *s1 = mb_tbl_uni_docomo2code2_value[i]; + return 1; + } + } else if (c >= mb_tbl_uni_docomo2code3_min && c <= mb_tbl_uni_docomo2code3_max) { + int i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_docomo2code3_key, mb_tbl_uni_docomo2code3_len); + if (i >= 0) { + *s1 = mb_tbl_uni_docomo2code3_value[i]; + return 1; + } + } else if (c >= mb_tbl_uni_docomo2code5_min && c <= mb_tbl_uni_docomo2code5_max) { + int i = mbfl_bisec_srch2(c - 0xF0000, mb_tbl_uni_docomo2code5_key, mb_tbl_uni_docomo2code5_len); + if (i >= 0) { + *s1 = mb_tbl_uni_docomo2code5_val[i]; + return 1; + } + } + return 0; } -int -mbfilter_unicode2sjis_emoji_kddi(int c, int *s1, mbfl_convert_filter *filter) +int mbfilter_unicode2sjis_emoji_kddi(int c, int *s1, mbfl_convert_filter *filter) { - int i, match = 0, c1s; - if (filter->status == 1) { - c1s = filter->cache; - filter->cache = 0; - filter->status = 0; + int c1 = filter->cache; + filter->cache = filter->status = 0; if (c == 0x20E3) { - if (c1s == 0x0023) { - *s1 = 0x25bc; - match = 1; - } else if (c1s == 0x0030) { + if (c1 == '#') { + *s1 = 0x25BC; + } else if (c1 == '0') { *s1 = 0x2830; - match = 1; - } else if (c1s >= 0x0031 && c1s <= 0x0039) { - *s1 = 0x27a6 + (c1s - 0x0031); - match = 1; - } - } else if ((c >= NFLAGS(0x41) && c <= NFLAGS(0x5A)) && (c1s >= NFLAGS(0x41) && c1s <= NFLAGS(0x5A))) { - for (i=0; i<10; i++) { - if (c1s == NFLAGS(nflags_s[i][0]) && c == NFLAGS(nflags_s[i][1])) { - *s1 = nflags_code_kddi[i]; - match = 1; - break; - } + } else { /* Previous character was '1'-'9' */ + *s1 = 0x27a6 + (c1 - '1'); } + return 1; } else { - if (c1s >= ucs_a1_jis_table_min && c1s < ucs_a1_jis_table_max) { - c1s = ucs_a1_jis_table[c1s - ucs_a1_jis_table_min]; - CK((*filter->output_function)(c1s, filter->data)); - } + CK((*filter->output_function)(c1, filter->data)); } - } else { - if (c == 0x0023 || ( c >= 0x0030 && c<=0x0039) || - (c >= NFLAGS(0x41) && c<= NFLAGS(0x5A))) { - filter->status = 1; - filter->cache = c; - *s1 = -1; - return match; - } - - if (c == 0x00A9) { - *s1 = 0x27dc; match = 1; - } else if (c == 0x00AE) { - *s1 = 0x27dd; match = 1; - } else if (c >= mb_tbl_uni_kddi2code2_min && c <= mb_tbl_uni_kddi2code2_max) { - i = mbfl_bisec_srch2(c, mb_tbl_uni_kddi2code2_key, mb_tbl_uni_kddi2code2_len); - if (i >= 0) { - *s1 = mb_tbl_uni_kddi2code2_value[i]; - match = 1; - } - } else if (c >= mb_tbl_uni_kddi2code3_min && c <= mb_tbl_uni_kddi2code3_max) { - i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_kddi2code3_key, mb_tbl_uni_kddi2code3_len); - if (i >= 0) { - *s1 = mb_tbl_uni_kddi2code3_value[i]; - match = 1; - } - } else if (c >= mb_tbl_uni_kddi2code5_min && c <= mb_tbl_uni_kddi2code5_max) { - i = mbfl_bisec_srch2(c - 0xf0000, mb_tbl_uni_kddi2code5_key, mb_tbl_uni_kddi2code5_len); - if (i >= 0) { - *s1 = mb_tbl_uni_kddi2code5_val[i]; - match = 1; + } else if (filter->status == 2) { + int c1 = filter->cache; + filter->cache = filter->status = 0; + if (c >= NFLAGS('B') && c <= NFLAGS('U')) { /* B for GB, U for RU */ + for (int i = 0; i < 10; i++) { + if (c1 == NFLAGS(nflags_s[i][0]) && c == NFLAGS(nflags_s[i][1])) { + *s1 = nflags_code_kddi[i]; + return 1; + } } } + + /* If none of the KDDI national flag emoji matched, then we have no way + * to convert the previous codepoint... */ + mbfl_filt_conv_illegal_output(c1, filter); + } + + if (c == '#' || (c >= '0' && c <= '9')) { + filter->status = 1; + filter->cache = c; + return 0; + } else if (c >= NFLAGS('C') && c <= NFLAGS('U')) { /* C for CN, U for US */ + filter->status = 2; + filter->cache = c; + return 0; } - return match; + if (c == 0xA9) { /* Copyright sign */ + *s1 = 0x27DC; + return 1; + } else if (c == 0xAE) { /* Registered sign */ + *s1 = 0x27DD; + return 1; + } else if (c >= mb_tbl_uni_kddi2code2_min && c <= mb_tbl_uni_kddi2code2_max) { + int i = mbfl_bisec_srch2(c, mb_tbl_uni_kddi2code2_key, mb_tbl_uni_kddi2code2_len); + if (i >= 0) { + *s1 = mb_tbl_uni_kddi2code2_value[i]; + return 1; + } + } else if (c >= mb_tbl_uni_kddi2code3_min && c <= mb_tbl_uni_kddi2code3_max) { + int i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_kddi2code3_key, mb_tbl_uni_kddi2code3_len); + if (i >= 0) { + *s1 = mb_tbl_uni_kddi2code3_value[i]; + return 1; + } + } else if (c >= mb_tbl_uni_kddi2code5_min && c <= mb_tbl_uni_kddi2code5_max) { + int i = mbfl_bisec_srch2(c - 0xF0000, mb_tbl_uni_kddi2code5_key, mb_tbl_uni_kddi2code5_len); + if (i >= 0) { + *s1 = mb_tbl_uni_kddi2code5_val[i]; + return 1; + } + } + return 0; } -int -mbfilter_unicode2sjis_emoji_sb(int c, int *s1, mbfl_convert_filter *filter) +int mbfilter_unicode2sjis_emoji_sb(int c, int *s1, mbfl_convert_filter *filter) { - int i, match = 0, c1s; - if (filter->status == 1) { - filter->status = 0; - c1s = filter->cache; - filter->cache = 0; + int c1 = filter->cache; + filter->cache = filter->status = 0; if (c == 0x20E3) { - if (c1s == 0x0023) { + if (c1 == '#') { *s1 = 0x2817; - match = 1; - } else if (c1s == 0x0030) { + } else if (c1 == '0') { *s1 = 0x282c; - match = 1; - } else if (c1s >= 0x0031 && c1s <= 0x0039) { - *s1 = 0x2823 + (c1s - 0x0031); - match = 1; + } else { /* Previous character was '1'-'9' */ + *s1 = 0x2823 + (c1 - '1'); } - } else if ((c >= NFLAGS(0x41) && c <= NFLAGS(0x5A)) && (c1s >= NFLAGS(0x41) && c1s <= NFLAGS(0x5A))) { - for (i=0; i<10; i++) { - if (c1s == NFLAGS(nflags_s[i][0]) && c == NFLAGS(nflags_s[i][1])) { + return 1; + } else { + (*filter->output_function)(c1, filter->data); + } + } else if (filter->status == 2) { + int c1 = filter->cache; + filter->cache = filter->status = 0; + if (c >= NFLAGS('B') && c <= NFLAGS('U')) { /* B for GB, U for RU */ + for (int i = 0; i < 10; i++) { + if (c1 == NFLAGS(nflags_s[i][0]) && c == NFLAGS(nflags_s[i][1])) { *s1 = nflags_code_sb[i]; - match = 1; - break; + return 1; } } - } else { - if (c1s >= ucs_a1_jis_table_min && c1s < ucs_a1_jis_table_max) { - c1s = ucs_a1_jis_table[c1s - ucs_a1_jis_table_min]; - CK((*filter->output_function)(c1s, filter->data)); - } } - } else { - if (c == 0x0023 || ( c >= 0x0030 && c<=0x0039) || (c >= NFLAGS(0x41) && c<= NFLAGS(0x5A))) { - filter->status = 1; - filter->cache = c; - *s1 = -1; - return match; - } - - if (c == 0x00A9) { - *s1 = 0x2855; match = 1; - } else if (c == 0x00AE) { - *s1 = 0x2856; match = 1; - } else if (c >= mb_tbl_uni_sb2code2_min && c <= mb_tbl_uni_sb2code2_max) { - i = mbfl_bisec_srch2(c, mb_tbl_uni_sb2code2_key, mb_tbl_uni_sb2code2_len); - if (i >= 0) { - *s1 = mb_tbl_uni_sb2code2_value[i]; - match = 1; - } - } else if (c >= mb_tbl_uni_sb2code3_min && c <= mb_tbl_uni_sb2code3_max) { - i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_sb2code3_key, mb_tbl_uni_sb2code3_len); - if (i >= 0) { - *s1 = mb_tbl_uni_sb2code3_value[i]; - match = 1; - } - } else if (c >= mb_tbl_uni_sb2code5_min && c <= mb_tbl_uni_sb2code5_max) { - i = mbfl_bisec_srch2(c - 0xf0000, mb_tbl_uni_sb2code5_key, mb_tbl_uni_sb2code5_len); - if (i >= 0) { - *s1 = mb_tbl_uni_sb2code5_val[i]; - match = 1; - } + + /* If none of the SoftBank national flag emoji matched, then we have no way + * to convert the previous codepoint... */ + mbfl_filt_conv_illegal_output(c1, filter); + } + + if (c == '#' || (c >= '0' && c <= '9')) { + filter->status = 1; + filter->cache = c; + return 0; + } else if (c >= NFLAGS('C') && c <= NFLAGS('U')) { /* C for CN, U for US */ + filter->status = 2; + filter->cache = c; + return 0; + } + + if (c == 0xA9) { /* Copyright sign */ + *s1 = 0x2855; + return 1; + } else if (c == 0xAE) { /* Registered sign */ + *s1 = 0x2856; + return 1; + } else if (c >= mb_tbl_uni_sb2code2_min && c <= mb_tbl_uni_sb2code2_max) { + int i = mbfl_bisec_srch2(c, mb_tbl_uni_sb2code2_key, mb_tbl_uni_sb2code2_len); + if (i >= 0) { + *s1 = mb_tbl_uni_sb2code2_value[i]; + return 1; + } + } else if (c >= mb_tbl_uni_sb2code3_min && c <= mb_tbl_uni_sb2code3_max) { + int i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_sb2code3_key, mb_tbl_uni_sb2code3_len); + if (i >= 0) { + *s1 = mb_tbl_uni_sb2code3_value[i]; + return 1; + } + } else if (c >= mb_tbl_uni_sb2code5_min && c <= mb_tbl_uni_sb2code5_max) { + int i = mbfl_bisec_srch2(c - 0xF0000, mb_tbl_uni_sb2code5_key, mb_tbl_uni_sb2code5_len); + if (i >= 0) { + *s1 = mb_tbl_uni_sb2code5_val[i]; + return 1; } } - return match; + return 0; } -/* - * SJIS-win => wchar - */ -int -mbfl_filt_conv_sjis_mobile_wchar(int c, mbfl_convert_filter *filter) +int mbfl_filt_conv_sjis_mobile_wchar(int c, mbfl_convert_filter *filter) { - int c1, s, s1 = 0, s2 = 0, w; - int snd = 0; + int c1, s, s1, s2, w, snd = 0; -retry: switch (filter->status) { case 0: - if (c >= 0 && c < 0x80) { /* latin */ - if (filter->from->no_encoding == mbfl_no_encoding_sjis_sb && c == 0x1b) { + if (c >= 0 && c < 0x80) { /* ASCII */ + if (filter->from == &mbfl_encoding_sjis_sb && c == 0x1B) { + /* ESC; escape sequences were used on older SoftBank phones for emoji */ filter->cache = c; filter->status = 2; } else { CK((*filter->output_function)(c, filter->data)); } - } else if (c > 0xa0 && c < 0xe0) { /* kana */ - CK((*filter->output_function)(0xfec0 + c, filter->data)); - } else if (c > 0x80 && c < 0xfd && c != 0xa0) { /* kanji first char */ + } else if (c > 0xA0 && c < 0xE0) { /* Kana */ + CK((*filter->output_function)(0xFEC0 + c, filter->data)); + } else if (c > 0x80 && c < 0xFD && c != 0xA0) { /* Kanji, first byte */ filter->status = 1; filter->cache = c; } else { - w = c & MBFL_WCSGROUP_MASK; - w |= MBFL_WCSGROUP_THROUGH; - CK((*filter->output_function)(w, filter->data)); + CK((*filter->output_function)(c | MBFL_WCSGROUP_THROUGH, filter->data)); } break; - case 1: /* kanji second char */ + case 1: /* Kanji, second byte */ filter->status = 0; c1 = filter->cache; - if (c >= 0x40 && c <= 0xfc && c != 0x7f) { + if (c >= 0x40 && c <= 0xFC && c != 0x7F) { w = 0; SJIS_DECODE(c1, c, s1, s2); - s = (s1 - 0x21)*94 + s2 - 0x21; + s = ((s1 - 0x21) * 94) + s2 - 0x21; if (s <= 137) { if (s == 31) { - w = 0xff3c; /* FULLWIDTH REVERSE SOLIDUS */ + w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ } else if (s == 32) { - w = 0xff5e; /* FULLWIDTH TILDE */ + w = 0xFF5E; /* FULLWIDTH TILDE */ } else if (s == 33) { - w = 0x2225; /* PARALLEL TO */ + w = 0x2225; /* PARALLEL TO */ } else if (s == 60) { - w = 0xff0d; /* FULLWIDTH HYPHEN-MINUS */ + w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ } else if (s == 80) { - w = 0xffe0; /* FULLWIDTH CENT SIGN */ + w = 0xFFE0; /* FULLWIDTH CENT SIGN */ } else if (s == 81) { - w = 0xffe1; /* FULLWIDTH POUND SIGN */ + w = 0xFFE1; /* FULLWIDTH POUND SIGN */ } else if (s == 137) { - w = 0xffe2; /* FULLWIDTH NOT SIGN */ + w = 0xFFE2; /* FULLWIDTH NOT SIGN */ } } if (w == 0) { @@ -665,134 +612,123 @@ retry: w = jisx0208_ucs_table[s]; } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { /* vendor ext2 (89ku - 92ku) */ w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; - } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { /* vendor ext3 (115ku - 119ku) */ - w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; - } else if (s >= (94*94) && s < (114*94)) { /* user (95ku - 114ku) */ - w = s - (94*94) + 0xe000; } - if (s >= (94*94) && s < 119*94) { - if (filter->from->no_encoding == mbfl_no_encoding_sjis_docomo) { - w = mbfilter_sjis_emoji_docomo2unicode(s, &snd); - } else if (filter->from->no_encoding == mbfl_no_encoding_sjis_kddi) { - w = mbfilter_sjis_emoji_kddi2unicode(s, &snd); - } else if (filter->from->no_encoding == mbfl_no_encoding_sjis_sb) { - w = mbfilter_sjis_emoji_sb2unicode(s, &snd); + /* Emoji */ + if (filter->from == &mbfl_encoding_sjis_docomo && s >= mb_tbl_code2uni_docomo1_min && s <= mb_tbl_code2uni_docomo1_max) { + w = mbfilter_sjis_emoji_docomo2unicode(s, &snd); + if (snd > 0) { + CK((*filter->output_function)(snd, filter->data)); } - - if (w > 0 && snd > 0) { + } else if (filter->from == &mbfl_encoding_sjis_kddi && s >= mb_tbl_code2uni_kddi1_min && s <= mb_tbl_code2uni_kddi2_max) { + w = mbfilter_sjis_emoji_kddi2unicode(s, &snd); + if (snd > 0) { + CK((*filter->output_function)(snd, filter->data)); + } + } else if (filter->from == &mbfl_encoding_sjis_sb && s >= mb_tbl_code2uni_sb1_min && s <= mb_tbl_code2uni_sb3_max) { + w = mbfilter_sjis_emoji_sb2unicode(s, &snd); + if (snd > 0) { CK((*filter->output_function)(snd, filter->data)); } } + + if (w == 0) { + if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { /* vendor ext3 (115ku - 119ku) */ + w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; + } else if (s >= (94*94) && s < (114*94)) { /* user (95ku - 114ku) */ + w = s - (94*94) + 0xe000; + } + } } if (w <= 0) { - w = (s1 << 8) | s2; - w &= MBFL_WCSPLANE_MASK; - w |= MBFL_WCSPLANE_WINCP932; + w = (s1 << 8) | s2 | MBFL_WCSPLANE_WINCP932; } CK((*filter->output_function)(w, filter->data)); - } else if ((c >= 0 && c < 0x21) || c == 0x7f) { /* CTLs */ - CK((*filter->output_function)(c, filter->data)); } else { - w = (c1 << 8) | c; - w &= MBFL_WCSGROUP_MASK; - w |= MBFL_WCSGROUP_THROUGH; - CK((*filter->output_function)(w, filter->data)); + CK((*filter->output_function)((c1 << 8) | c | MBFL_WCSGROUP_THROUGH, filter->data)); } break; - /* ESC : Softbank Emoji */ + + /* ESC: Softbank Emoji */ case 2: - if (filter->from->no_encoding == mbfl_no_encoding_sjis_sb && - c == 0x24) { - filter->cache = c; - filter->status++; + if (c == '$') { + filter->cache = c; + filter->status++; } else { - filter->cache = 0; - filter->status = 0; - CK((*filter->output_function)(0x1b, filter->data)); - goto retry; + CK((*filter->output_function)((filter->cache << 8) | c | MBFL_WCSGROUP_THROUGH, filter->data)); + filter->status = filter->cache = 0; } break; - /* ESC $ : Softbank Emoji */ + /* ESC $: Softbank Emoji */ case 3: - if (filter->from->no_encoding == mbfl_no_encoding_sjis_sb && - ((c >= 0x45 && c <= 0x47) || (c >= 0x4f && c <= 0x51))) { - filter->cache = c; - filter->status++; + if ((c >= 'E' && c <= 'G') || (c >= 'O' && c <= 'Q')) { + filter->cache = c; + filter->status++; } else { - filter->cache = 0; - filter->status = 0; - CK((*filter->output_function)(0x1b, filter->data)); - CK((*filter->output_function)(0x24, filter->data)); - goto retry; + CK((*filter->output_function)(0x1B2400 | c | MBFL_WCSGROUP_THROUGH, filter->data)); + filter->status = filter->cache = 0; } break; - /* ESC [GEFOPQ] : Softbank Emoji */ + /* ESC $ [GEFOPQ]: Softbank Emoji */ case 4: - w = 0; - if (filter->from->no_encoding == mbfl_no_encoding_sjis_sb) { - c1 = filter->cache; - - if (c == 0x0f) { - w = c; - filter->cache = 0; - filter->status = 0; + c1 = filter->cache; + if (c == 0xF) { /* Terminate sequence of emoji */ + filter->status = filter->cache = 0; + return c; + } else { + if (c1 == 'G' && c >= 0x21 && c <= 0x7a) { + s1 = (0x91 - 0x21) * 94; + } else if (c1 == 'E' && c >= 0x21 && c <= 0x7A) { + s1 = (0x8D - 0x21) * 94; + } else if (c1 == 'F' && c >= 0x21 && c <= 0x7A) { + s1 = (0x8E - 0x21) * 94; + } else if (c1 == 'O' && c >= 0x21 && c <= 0x6D) { + s1 = (0x92 - 0x21) * 94; + } else if (c1 == 'P' && c >= 0x21 && c <= 0x6C) { + s1 = (0x95 - 0x21) * 94; + } else if (c1 == 'Q' && c >= 0x21 && c <= 0x5E) { + s1 = (0x96 - 0x21) * 94; } else { - if (c1 == 0x47 && c >= 0x21 && c <= 0x7a) { - s1 = 0x91; s2 = c; - } else if (c1 == 0x45 && c >= 0x21 && c <= 0x7a) { - s1 = 0x8d; s2 = c; - } else if (c1 == 0x46 && c >= 0x21 && c <= 0x7a) { - s1 = 0x8e; s2 = c; - } else if (c1 == 0x4f && c >= 0x21 && c <= 0x6d) { - s1 = 0x92; s2 = c; - } else if (c1 == 0x50 && c >= 0x21 && c <= 0x6c) { - s1 = 0x95; s2 = c; - } else if (c1 == 0x51 && c >= 0x21 && c <= 0x5e) { - s1 = 0x96; s2 = c; - } - s = (s1 - 0x21)*94 + s2 - 0x21; - w = mbfilter_sjis_emoji_sb2unicode(s, &snd); - if (w > 0) { - if (snd > 0) { - CK((*filter->output_function)(snd, filter->data)); - } - CK((*filter->output_function)(w, filter->data)); + CK((*filter->output_function)((c1 << 8) | c | MBFL_WCSGROUP_THROUGH, filter->data)); + filter->status = filter->cache = 0; + return c; + } + + w = mbfilter_sjis_emoji_sb2unicode(s1 + c - 0x21, &snd); + if (w > 0) { + if (snd > 0) { + CK((*filter->output_function)(snd, filter->data)); } + CK((*filter->output_function)(w, filter->data)); + } else { + CK((*filter->output_function)((c1 << 8) | c | MBFL_WCSGROUP_THROUGH, filter->data)); + filter->status = filter->cache = 0; } } + } - if (w <= 0) { - c1 = filter->cache; - filter->cache = 0; - filter->status = 0; - CK((*filter->output_function)(0x1b, filter->data)); - CK((*filter->output_function)(0x24, filter->data)); - CK((*filter->output_function)(c1 & 0xff, filter->data)); - goto retry; - } - break; + return c; +} - default: - filter->status = 0; - break; +static int mbfl_filt_conv_sjis_wchar_flush(mbfl_convert_filter *filter) +{ + if (filter->status && filter->status != 4) { + mbfl_filt_conv_illegal_output(filter->cache, filter); } - return c; + if (filter->flush_function) { + (*filter->flush_function)(filter->data); + } + + return 0; } -/* - * wchar => SJIS-win - */ -int -mbfl_filt_conv_wchar_sjis_mobile(int c, mbfl_convert_filter *filter) +int mbfl_filt_conv_wchar_sjis_mobile(int c, mbfl_convert_filter *filter) { - int c1, c2, s1, s2; + int c1, c2, s1 = 0, s2 = 0; - s1 = 0; - s2 = 0; if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { @@ -801,102 +737,83 @@ mbfl_filt_conv_wchar_sjis_mobile(int c, mbfl_convert_filter *filter) s1 = ucs_i_jis_table[c - ucs_i_jis_table_min]; } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { s1 = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } else if (c >= 0xe000 && c < (0xe000 + 20*94)) { /* user (95ku - 114ku) */ - s1 = c - 0xe000; - c1 = s1/94 + 0x7f; - c2 = s1%94 + 0x21; + } else if (c >= 0xE000 && c < (0xE000 + 20*94)) { + /* Private User Area (95ku - 114ku) */ + s1 = c - 0xE000; + c1 = (s1 / 94) + 0x7F; + c2 = (s1 % 94) + 0x21; s1 = (c1 << 8) | c2; s2 = 1; } + if (s1 <= 0) { - c1 = c & ~MBFL_WCSPLANE_MASK; - if (c1 == MBFL_WCSPLANE_WINCP932) { - s1 = c & MBFL_WCSPLANE_MASK; - s2 = 1; - } else if (c1 == MBFL_WCSPLANE_JIS0208) { - s1 = c & MBFL_WCSPLANE_MASK; - } else if (c1 == MBFL_WCSPLANE_JIS0212) { - s1 = c & MBFL_WCSPLANE_MASK; - s1 |= 0x8080; - } else if (c == 0xa5) { /* YEN SIGN */ - s1 = 0x216f; /* FULLWIDTH YEN SIGN */ - } else if (c == 0x203e) { /* OVER LINE */ - s1 = 0x2131; /* FULLWIDTH MACRON */ - } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ + if (c == 0xA5) { /* YEN SIGN */ + s1 = 0x216F; /* FULLWIDTH YEN SIGN */ + } else if (c == 0xFF3c) { /* FULLWIDTH REVERSE SOLIDUS */ s1 = 0x2140; - } else if (c == 0xff5e) { /* FULLWIDTH TILDE */ - s1 = 0x2141; - } else if (c == 0x2225) { /* PARALLEL TO */ + } else if (c == 0x2225) { /* PARALLEL TO */ s1 = 0x2142; - } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ - s1 = 0x215d; - } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ + } else if (c == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ + s1 = 0x215D; + } else if (c == 0xFFE0) { /* FULLWIDTH CENT SIGN */ s1 = 0x2171; - } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ + } else if (c == 0xFFE1) { /* FULLWIDTH POUND SIGN */ s1 = 0x2172; - } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ - s1 = 0x224c; + } else if (c == 0xFFE2) { /* FULLWIDTH NOT SIGN */ + s1 = 0x224C; } } if ((s1 <= 0) || (s1 >= 0x8080 && s2 == 0)) { /* not found or X 0212 */ s1 = -1; - c1 = 0; - c2 = cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext1 (13ku) */ + + /* CP932 vendor ext1 (13ku) */ + for (c1 = 0; c1 < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; c1++) { if (c == cp932ext1_ucs_table[c1]) { - s1 = ((c1/94 + 0x2d) << 8) + (c1%94 + 0x21); + s1 = (((c1 / 94) + 0x2D) << 8) + (c1 % 94) + 0x21; break; } - c1++; } + if (s1 <= 0) { - c1 = 0; - c2 = cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext2 (115ku - 119ku) */ + /* CP932 vendor ext2 (115ku - 119ku) */ + for (c1 = 0; c1 < cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; c1++) { if (c == cp932ext2_ucs_table[c1]) { - s1 = ((c1/94 + 0x93) << 8) + (c1%94 + 0x21); + s1 = (((c1 / 94) + 0x79) << 8) + (c1 % 94) + 0x21; break; } - c1++; } } if (s1 <= 0) { - c1 = 0; - c2 = cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext3 (115ku - 119ku) */ + /* CP932 vendor ext3 (115ku - 119ku) */ + for (c1 = 0; c1 < cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; c1++) { if (c == cp932ext3_ucs_table[c1]) { - s1 = ((c1/94 + 0x93) << 8) + (c1%94 + 0x21); + s1 = (((c1 / 94) + 0x93) << 8) + (c1 % 94) + 0x21; break; } - c1++; } } + if (c == 0) { s1 = 0; - } else if (s1 <= 0) { - s1 = -1; } } - if ((filter->to->no_encoding == mbfl_no_encoding_sjis_docomo && - mbfilter_unicode2sjis_emoji_docomo(c, &s1, filter) > 0) || - (filter->to->no_encoding == mbfl_no_encoding_sjis_kddi && - mbfilter_unicode2sjis_emoji_kddi(c, &s1, filter) > 0) || - (filter->to->no_encoding == mbfl_no_encoding_sjis_sb && - mbfilter_unicode2sjis_emoji_sb(c, &s1, filter) > 0 )) { + if ((filter->to == &mbfl_encoding_sjis_docomo && mbfilter_unicode2sjis_emoji_docomo(c, &s1, filter)) || + (filter->to == &mbfl_encoding_sjis_kddi && mbfilter_unicode2sjis_emoji_kddi(c, &s1, filter)) || + (filter->to == &mbfl_encoding_sjis_sb && mbfilter_unicode2sjis_emoji_sb(c, &s1, filter))) { CODE2JIS(c1,c2,s1,s2); } - if (filter->status == 1 && filter->cache > 0) { + if (filter->status) { return c; } if (s1 >= 0) { - if (s1 < 0x100) { /* latin or kana */ + if (s1 < 0x100) { /* Latin/Kana */ CK((*filter->output_function)(s1, filter->data)); - } else { /* kanji */ + } else { /* Kanji */ c1 = (s1 >> 8) & 0xff; c2 = s1 & 0xff; SJIS_ENCODE(c1, c2, s1, s2); @@ -910,18 +827,15 @@ mbfl_filt_conv_wchar_sjis_mobile(int c, mbfl_convert_filter *filter) return c; } -int -mbfl_filt_conv_sjis_mobile_flush(mbfl_convert_filter *filter) +int mbfl_filt_conv_sjis_mobile_flush(mbfl_convert_filter *filter) { int c1 = filter->cache; - if (filter->status == 1 && (c1 == 0x0023 || (c1 >= 0x0030 && c1<=0x0039))) { + if (filter->status == 1 && (c1 == '#' || (c1 >= '0' && c1 <= '9'))) { CK((*filter->output_function)(c1, filter->data)); } - filter->status = 0; - filter->cache = 0; - if (filter->flush_function != NULL) { - return (*filter->flush_function)(filter->data); + if (filter->flush_function) { + (*filter->flush_function)(filter->data); } return 0; |