13e12c5d1SDavid du Colombier /* 2*219b2ee8SDavid du Colombier following astonishing goo courtesy of kogure. 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier /* 53e12c5d1SDavid du Colombier * MicroSoft Kanji Encoding (SJIS) Transformation 63e12c5d1SDavid du Colombier */ 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier /* 93e12c5d1SDavid du Colombier * void 103e12c5d1SDavid du Colombier * J2S(unsigned char *_h, unsigned char *_l) 11*219b2ee8SDavid du Colombier * JIS X 208 to MS kanji transformation. 123e12c5d1SDavid du Colombier * 133e12c5d1SDavid du Colombier * Calling/Exit State: 143e12c5d1SDavid du Colombier * _h and _l should be in their valid range. 153e12c5d1SDavid du Colombier * No return value. 163e12c5d1SDavid du Colombier */ 173e12c5d1SDavid du Colombier #define J2S(_h, _l) { \ 183e12c5d1SDavid du Colombier /* lower: 21-7e >> 40-9d,9e-fb >> 40-7e,(skip 7f),80-fc */ \ 193e12c5d1SDavid du Colombier if (((_l) += (((_h)-- % 2) ? 0x1f : 0x7d)) > 0x7e) (_l)++; \ 203e12c5d1SDavid du Colombier /* upper: 21-7e >> 81-af >> 81-9f,(skip a0-df),e0-ef */ \ 213e12c5d1SDavid du Colombier if (((_h) = ((_h) / 2 + 0x71)) > 0x9f) (_h) += 0x40; \ 223e12c5d1SDavid du Colombier } 233e12c5d1SDavid du Colombier 243e12c5d1SDavid du Colombier /* 253e12c5d1SDavid du Colombier * void 263e12c5d1SDavid du Colombier * S2J(unsigned char *_h, unsigned char *_l) 27*219b2ee8SDavid du Colombier * MS kanji to JIS X 208 transformation. 283e12c5d1SDavid du Colombier * 293e12c5d1SDavid du Colombier * Calling/Exit State: 303e12c5d1SDavid du Colombier * _h and _l should be in valid range. 313e12c5d1SDavid du Colombier * No return value. 323e12c5d1SDavid du Colombier */ 333e12c5d1SDavid du Colombier #define S2J(_h, _l) { \ 343e12c5d1SDavid du Colombier /* lower: 40-7e,80-fc >> 21-5f,61-dd >> 21-7e,7f-dc */ \ 353e12c5d1SDavid du Colombier if (((_l) -= 0x1f) > 0x60) (_l)--; \ 363e12c5d1SDavid du Colombier /* upper: 81-9f,e0-ef >> 00-1e,5f-6e >> 00-2e >> 21-7d */ \ 373e12c5d1SDavid du Colombier if (((_h) -= 0x81) > 0x5e) (_h) -= 0x40; (_h) *= 2, (_h) += 0x21; \ 383e12c5d1SDavid du Colombier /* upper: ,21-7d >> ,22-7e ; lower: ,7f-dc >> ,21-7e */ \ 393e12c5d1SDavid du Colombier if ((_l) > 0x7e) (_h)++, (_l) -= 0x5e; \ 403e12c5d1SDavid du Colombier } 413e12c5d1SDavid du Colombier 423e12c5d1SDavid du Colombier /* 433e12c5d1SDavid du Colombier * int 443e12c5d1SDavid du Colombier * ISJKANA(const unsigned char *_b) 453e12c5d1SDavid du Colombier * Tests given byte is in the range of JIS X 0201 katakana. 463e12c5d1SDavid du Colombier * 473e12c5d1SDavid du Colombier * Calling/Exit State: 483e12c5d1SDavid du Colombier * Returns 1 if it is, or 0 otherwise. 493e12c5d1SDavid du Colombier */ 503e12c5d1SDavid du Colombier #define ISJKANA(_b) (0xa0 <= (_b) && (_b) < 0xe0) 513e12c5d1SDavid du Colombier 523e12c5d1SDavid du Colombier /* 533e12c5d1SDavid du Colombier * int 543e12c5d1SDavid du Colombier * CANS2JH(const unsigned char *_h) 553e12c5d1SDavid du Colombier * Tests given byte is in the range of valid first byte of MS 563e12c5d1SDavid du Colombier * kanji code; either acts as a subroutine of CANS2J() macro 573e12c5d1SDavid du Colombier * or can be used to parse MS kanji encoded strings. 583e12c5d1SDavid du Colombier * 593e12c5d1SDavid du Colombier * Calling/Exit State: 603e12c5d1SDavid du Colombier * Returns 1 if it is, or 0 otherwise. 613e12c5d1SDavid du Colombier */ 623e12c5d1SDavid du Colombier #define CANS2JH(_h) ((0x81 <= (_h) && (_h) < 0xf0) && !ISJKANA(_h)) 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier /* 653e12c5d1SDavid du Colombier * int 663e12c5d1SDavid du Colombier * CANS2JL(const unsigned char *_l) 673e12c5d1SDavid du Colombier * Tests given byte is in the range of valid second byte of MS 683e12c5d1SDavid du Colombier * kanji code; acts as a subroutine of CANS2J() macro. 693e12c5d1SDavid du Colombier * 703e12c5d1SDavid du Colombier * Calling/Exit State: 713e12c5d1SDavid du Colombier * Returns 1 if it is, or 0 otherwise. 723e12c5d1SDavid du Colombier */ 733e12c5d1SDavid du Colombier #define CANS2JL(_l) (0x40 <= (_l) && (_l) < 0xfd && (_l) != 0x7f) 743e12c5d1SDavid du Colombier 753e12c5d1SDavid du Colombier /* 763e12c5d1SDavid du Colombier * int 773e12c5d1SDavid du Colombier * CANS2J(const unsigned char *_h, const unsinged char *_l) 783e12c5d1SDavid du Colombier * Tests given bytes form a MS kanji code point which can be 79*219b2ee8SDavid du Colombier * transformed to a valid JIS X 208 code point. 803e12c5d1SDavid du Colombier * 813e12c5d1SDavid du Colombier * Calling/Exit State: 823e12c5d1SDavid du Colombier * Returns 1 if they are, or 0 otherwise. 833e12c5d1SDavid du Colombier */ 843e12c5d1SDavid du Colombier #define CANS2J(_h, _l) (CANS2JH(_h) && CANS2JL(_l)) 853e12c5d1SDavid du Colombier 863e12c5d1SDavid du Colombier /* 873e12c5d1SDavid du Colombier * int 883e12c5d1SDavid du Colombier * CANJ2SB(const unsigned char *_b) 893e12c5d1SDavid du Colombier * Tests given bytes is in the range of valid 94 graphic 903e12c5d1SDavid du Colombier * character set; acts as a subroutine of CANJ2S() macro. 913e12c5d1SDavid du Colombier * 923e12c5d1SDavid du Colombier * Calling/Exit State: 933e12c5d1SDavid du Colombier * Returns 1 if it is, or 0 otherwise. 943e12c5d1SDavid du Colombier */ 953e12c5d1SDavid du Colombier #define CANJ2SB(_b) (0x21 <= (_b) && (_b) < 0x7f) 963e12c5d1SDavid du Colombier 973e12c5d1SDavid du Colombier /* 983e12c5d1SDavid du Colombier * int 993e12c5d1SDavid du Colombier * CANJ2S(const unsigned char *_h, const unsigned char *_l) 100*219b2ee8SDavid du Colombier * Tests given bytes form valid JIS X 208 code points 1013e12c5d1SDavid du Colombier * (which can be transformed to MS kanji). 1023e12c5d1SDavid du Colombier * 1033e12c5d1SDavid du Colombier * Calling/Exit State: 1043e12c5d1SDavid du Colombier * Returns 1 if they are, or 0 otherwise. 1053e12c5d1SDavid du Colombier */ 1063e12c5d1SDavid du Colombier #define CANJ2S(_h, _l) (CANJ2SB(_h) && CANJ2SB(_l)) 1073e12c5d1SDavid du Colombier 108