1 /* 2 following astonishing goo courtesy of kogure. 3 */ 4 /* 5 * MicroSoft Kanji Encoding (SJIS) Transformation 6 */ 7 8 /* 9 * void 10 * J2S(unsigned char *_h, unsigned char *_l) 11 * JIS X 208 to MS kanji transformation. 12 * 13 * Calling/Exit State: 14 * _h and _l should be in their valid range. 15 * No return value. 16 */ 17 #define J2S(_h, _l) { \ 18 /* lower: 21-7e >> 40-9d,9e-fb >> 40-7e,(skip 7f),80-fc */ \ 19 if (((_l) += (((_h)-- % 2) ? 0x1f : 0x7d)) > 0x7e) (_l)++; \ 20 /* upper: 21-7e >> 81-af >> 81-9f,(skip a0-df),e0-ef */ \ 21 if (((_h) = ((_h) / 2 + 0x71)) > 0x9f) (_h) += 0x40; \ 22 } 23 24 /* 25 * void 26 * S2J(unsigned char *_h, unsigned char *_l) 27 * MS kanji to JIS X 208 transformation. 28 * 29 * Calling/Exit State: 30 * _h and _l should be in valid range. 31 * No return value. 32 */ 33 #define S2J(_h, _l) { \ 34 /* lower: 40-7e,80-fc >> 21-5f,61-dd >> 21-7e,7f-dc */ \ 35 if (((_l) -= 0x1f) > 0x60) (_l)--; \ 36 /* upper: 81-9f,e0-ef >> 00-1e,5f-6e >> 00-2e >> 21-7d */ \ 37 if (((_h) -= 0x81) > 0x5e) (_h) -= 0x40; (_h) *= 2, (_h) += 0x21; \ 38 /* upper: ,21-7d >> ,22-7e ; lower: ,7f-dc >> ,21-7e */ \ 39 if ((_l) > 0x7e) (_h)++, (_l) -= 0x5e; \ 40 } 41 42 /* 43 * int 44 * ISJKANA(const unsigned char *_b) 45 * Tests given byte is in the range of JIS X 0201 katakana. 46 * 47 * Calling/Exit State: 48 * Returns 1 if it is, or 0 otherwise. 49 */ 50 #define ISJKANA(_b) (0xa0 <= (_b) && (_b) < 0xe0) 51 52 /* 53 * int 54 * CANS2JH(const unsigned char *_h) 55 * Tests given byte is in the range of valid first byte of MS 56 * kanji code; either acts as a subroutine of CANS2J() macro 57 * or can be used to parse MS kanji encoded strings. 58 * 59 * Calling/Exit State: 60 * Returns 1 if it is, or 0 otherwise. 61 */ 62 #define CANS2JH(_h) ((0x81 <= (_h) && (_h) < 0xf0) && !ISJKANA(_h)) 63 64 /* 65 * int 66 * CANS2JL(const unsigned char *_l) 67 * Tests given byte is in the range of valid second byte of MS 68 * kanji code; acts as a subroutine of CANS2J() macro. 69 * 70 * Calling/Exit State: 71 * Returns 1 if it is, or 0 otherwise. 72 */ 73 #define CANS2JL(_l) (0x40 <= (_l) && (_l) < 0xfd && (_l) != 0x7f) 74 75 /* 76 * int 77 * CANS2J(const unsigned char *_h, const unsinged char *_l) 78 * Tests given bytes form a MS kanji code point which can be 79 * transformed to a valid JIS X 208 code point. 80 * 81 * Calling/Exit State: 82 * Returns 1 if they are, or 0 otherwise. 83 */ 84 #define CANS2J(_h, _l) (CANS2JH(_h) && CANS2JL(_l)) 85 86 /* 87 * int 88 * CANJ2SB(const unsigned char *_b) 89 * Tests given bytes is in the range of valid 94 graphic 90 * character set; acts as a subroutine of CANJ2S() macro. 91 * 92 * Calling/Exit State: 93 * Returns 1 if it is, or 0 otherwise. 94 */ 95 #define CANJ2SB(_b) (0x21 <= (_b) && (_b) < 0x7f) 96 97 /* 98 * int 99 * CANJ2S(const unsigned char *_h, const unsigned char *_l) 100 * Tests given bytes form valid JIS X 208 code points 101 * (which can be transformed to MS kanji). 102 * 103 * Calling/Exit State: 104 * Returns 1 if they are, or 0 otherwise. 105 */ 106 #define CANJ2S(_h, _l) (CANJ2SB(_h) && CANJ2SB(_l)) 107 108 #define JIS208MAX 8407 109 #define GB2312MAX 8795 110 #define BIG5MAX 13973 111 112 extern Rune tabjis208[JIS208MAX]; /* runes indexed by kuten */ 113 extern Rune tabgb2312[GB2312MAX]; 114 extern Rune tabbig5[BIG5MAX]; 115