1/* Copyright 1992 NEC Corporation, Tokyo, Japan. 2 * 3 * Permission to use, copy, modify, distribute and sell this software 4 * and its documentation for any purpose is hereby granted without 5 * fee, provided that the above copyright notice appear in all copies 6 * and that both that copyright notice and this permission notice 7 * appear in supporting documentation, and that the name of NEC 8 * Corporation not be used in advertising or publicity pertaining to 9 * distribution of the software without specific, written prior 10 * permission. NEC Corporation makes no representations about the 11 * suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 16 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#if !defined(lint) && !defined(__CODECENTER__) 24static char rcsid[]="@(#) 102.1 $Id: RKkana.c 14875 2005-11-12 21:25:31Z bonefish $"; 25#endif 26 27/* LINTLIBRARY */ 28#include "canna.h" 29#include "RKintern.h" 30 31 32/* RkCvtZen 33 * hankaku moji wo zenkaku moji ni suru 34 */ 35static 36unsigned short 37hiragana[] = 38{ 39/* 0x00 */ 40 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 41 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 42/* 0x10 */ 43 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 44 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 45/* 0x20 */ 46 0xa1a1, 0xa1aa, 0xa1ed, 0xa1f4, 0xa1f0, 0xa1f3, 0xa1f5, 0xa1c7, 47 0xa1ca, 0xa1cb, 0xa1f6, 0xa1dc, 0xa1a4, 0xa1dd, 0xa1a5, 0xa1bf, 48/* 0x30 */ 49 0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7, 50 0xa3b8, 0xa3b9, 0xa1a7, 0xa1a8, 0xa1e3, 0xa1e1, 0xa1e4, 0xa1a9, 51/* 0x40 */ 52 0xa1f7, 0xa3c1, 0xa3c2, 0xa3c3, 0xa3c4, 0xa3c5, 0xa3c6, 0xa3c7, 53 0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb, 0xa3cc, 0xa3cd, 0xa3ce, 0xa3cf, 54/* 0x50 */ 55 0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3, 0xa3d4, 0xa3d5, 0xa3d6, 0xa3d7, 56 0xa3d8, 0xa3d9, 0xa3da, 0xa1ce, 0xa1ef, 0xa1cf, 0xa1b0, 0xa1b2, 57/* 0x60 */ 58 0xa1c6, 0xa3e1, 0xa3e2, 0xa3e3, 0xa3e4, 0xa3e5, 0xa3e6, 0xa3e7, 59 0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb, 0xa3ec, 0xa3ed, 0xa3ee, 0xa3ef, 60/* 0x70 */ 61 0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3, 0xa3f4, 0xa3f5, 0xa3f6, 0xa3f7, 62 0xa3f8, 0xa3f9, 0xa3fa, 0xa1d0, 0xa1c3, 0xa1d1, 0xa1c1, 0xa2a2, 63/*0x80 */ 64 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 65 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 66/*0x90 */ 67 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 68 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 69/*0xa0 */ 70 0xa1a1, 0xa1a3, 0xa1d6, 0xa1d7, 0xa1a2, 0xa1a6, 0xa4f2, 0xa4a1, 71 0xa4a3, 0xa4a5, 0xa4a7, 0xa4a9, 0xa4e3, 0xa4e5, 0xa4e7, 0xa4c3, 72/*0xb0 */ 73 0xa1bc, 0xa4a2, 0xa4a4, 0xa4a6, 0xa4a8, 0xa4aa, 0xa4ab, 0xa4ad, 74 0xa4af, 0xa4b1, 0xa4b3, 0xa4b5, 0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd, 75/*0xc0 */ 76 0xa4bf, 0xa4c1, 0xa4c4, 0xa4c6, 0xa4c8, 0xa4ca, 0xa4cb, 0xa4cc, 77 0xa4cd, 0xa4ce, 0xa4cf, 0xa4d2, 0xa4d5, 0xa4d8, 0xa4db, 0xa4de, 78/*0xd0 */ 79 0xa4df, 0xa4e0, 0xa4e1, 0xa4e2, 0xa4e4, 0xa4e6, 0xa4e8, 0xa4e9, 80 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ed, 0xa4ef, 0xa4f3, 0xa1ab, 0xa1ac, 81/* 0xe0 */ 82 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 83 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 84/* 0xf0 */ 85 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 86 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87}; 88static 89unsigned short 90hankaku[] = { 91/*0x00*/ 92 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 93 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 94/*0x10*/ 95 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 96 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 97/*0x20*/ 98 0x0000, ' ', 0x8ea4, 0x8ea1, ',', '.', 0x8ea5, ':', 99 ';', '?', '!', 0x8ede, 0x8edf, 0x0000, 0x0000, 0x0000, 100/*0x30*/ 101 '^', 0x0000, '_', 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 102 0x0000, 0x0000, 0x0000, 0x0000, 0x8eb0, 0x0000, 0x0000, '/', 103/*0x40*/ 104 0x0000, '~', 0x0000, '|', 0x0000, 0x0000, '\'', '\'', 105 '"', '"', '(', ')', '[', ']', '[', ']', 106/*0x50*/ 107 '{', '}', 0x0000, 0x0000, 0x0000, 0x0000, 0x8ea2, 0x8ea3, 108 0x0000, 0x0000, 0x0000, 0x0000, '+', '-', 0x0000, 0x0000, 109/*0x60*/ 110 0x0000, '=', 0x0000, '<', '>', 0x0000, 0x0000, 0x0000, 111 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, '\\', 112/*0x70*/ 113 '$',0x0000, 0x0000, '%', '#', '&', '*', '@', 114 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 115/*0x80*/ 116 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 117 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 118/*0x90*/ 119 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 120 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 121/*0xa0*/ 122 0x0020, 0x00a7, 0x00b1, 0x00a8, 0x00b2, 0x00a9, 0x00b3, 0x00aa, 123 0x00b4, 0x00ab, 0x00b5, 0x00b6, 0xb6de, 0x00b7, 0xb7de, 0x00b8, 124/*0xb0*/ 125 0xb8de, 0x00b9, 0xb9de, 0x00ba, 0xbade, 0x00bb, 0xbbde, 0x00bc, 126 0xbcde, 0x00bd, 0xbdde, 0x00be, 0xbede, 0x00bf, 0xbfde, 0x00c0, 127/*0xc0*/ 128 0xc0de, 0x00c1, 0xc1de, 0x00af, 0x00c2, 0xc2de, 0x00c3, 0xc3de, 129 0x00c4, 0xc4de, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 130/*0xd0*/ 131 0xcade, 0xcadf, 0x00cb, 0xcbde, 0xcbdf, 0x00cc, 0xccde, 0xccdf, 132 0x00cd, 0xcdde, 0xcddf, 0x00ce, 0xcede, 0xcedf, 0x00cf, 0x00d0, 133/*0xe0*/ 134 0x00d1, 0x00d2, 0x00d3, 0x00ac, 0x00d4, 0x00ad, 0x00d5, 0x00ae, 135 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dc, 136/*0xf0*/ 137 0x00b2, 0x00b4, 0x00a6, 0x00dd, 0xb3de, 0x00b6, 0x00b9, 0x0000, 138 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 139}; 140 141#ifdef OBSOLETE_RKKANA 142 143#define ADDCODE(dst, maxdst, count, code, length) {\ 144 if ( (unsigned long)(length) <= (unsigned long)(maxdst) ) {\ 145 (maxdst) -= (length); (count) += (length);\ 146 if ( (dst) ) {\ 147 (dst) += (length);\ 148 switch((length)) {\ 149 case 4: *--(dst) = (code)&255; (code) >>= 8;\ 150 case 3: *--(dst) = (code)&255; (code) >>= 8;\ 151 case 2: *--(dst) = (code)&255; (code) >>= 8;\ 152 case 1: *--(dst) = (code)&255; (code) >>= 8;\ 153 };\ 154 (dst) += (length);\ 155 };\ 156 };\ 157} 158 159#else /* !OBSOLETE_RKKANA */ 160 161static int _ADDCODE(unsigned char *dst, int maxdst, int count, unsigned long code, int length); 162 163static int 164_ADDCODE(unsigned char *dst, int maxdst, int count, unsigned long code, int length) 165{ 166 if ((unsigned long)length <= (unsigned long)maxdst) { 167 maxdst -= length; 168 count += length; 169 if (dst) { 170 dst += length; 171 switch (length) { 172 case 4: *--dst = (unsigned char)code; code >>= 8; 173 case 3: *--dst = (unsigned char)code; code >>= 8; 174 case 2: *--dst = (unsigned char)code; code >>= 8; 175 case 1: *--dst = (unsigned char)code; code >>= 8; 176 } 177 } 178 return length; 179 } 180 return 0; 181} 182 183#define ADDCODE(dst, maxdst, count, code, length) \ 184{ int llen = _ADDCODE(dst, maxdst, count, (unsigned long)code, length); \ 185 if (llen > 0 && (dst)) { (dst) += llen; (maxdst) -= llen; (count) += llen; }} 186 187#define ADDWCODE(dst, maxdst, count, code) {\ 188 if ( (maxdst) > 0 ) {\ 189 (maxdst)-- ; (count)++ ;\ 190 if ( (dst) ) {\ 191 *(dst)++ = (code);\ 192 }\ 193 }\ 194} 195 196#endif /* !OBSOLETE_RKKANA */ 197 198/* RkCvtZen 199 * hankaku moji(ASCII+katakana) wo taiou suru zenkaku moji ni suru 200 * dakuten,handakuten shori mo okonau. 201 */ 202int 203RkCvtZen(unsigned char *zen, int maxzen, unsigned char *han, int maxhan) 204{ 205 unsigned char *z = zen; 206 unsigned char *h = han; 207 unsigned char *H = han + maxhan; 208 unsigned short hi, lo; 209 unsigned byte; 210 int count = 0; 211 unsigned long code; 212 213 if ( --maxzen <= 0 ) 214 return count; 215 while ( h < H ) { 216 hi = *h++; 217 byte = 2; 218 if ( hi == 0x8e ) { /* hankaku katakana */ 219 if ( !(code = hiragana[lo = *h++]) ) 220 code = (hi<<8)|lo; 221 byte = (code>>8) ? 2 : 1; 222 if ( (code>>8) == 0xa4 ) { 223 code |= 0x100; 224 /* dakuten/handakuten ga tuku baai */ 225 if ( h + 1 < H && h[0] == 0x8e ) { 226 lo = h[1]; 227 switch(code&255) { 228 /* u */ case 0xa6: 229 if ( lo == 0xde ) code = 0xa5f4, h += 2; 230 break; 231 /* ha */case 0xcf: case 0xd2: case 0xd5: case 0xd8: case 0xdb: 232 if ( lo == 0xdf ) { 233 code += 2, h += 2; 234 break; 235 }; 236 /* ka */case 0xab: case 0xad: case 0xaf: case 0xb1: case 0xb3: 237 /* sa */case 0xb5: case 0xb7: case 0xb9: case 0xbb: case 0xbd: 238 /* ta */case 0xbf: case 0xc1: case 0xc4: case 0xc6: case 0xc8: 239 if ( lo == 0xde ) { 240 code += 1, h += 2; 241 break; 242 }; 243 }; 244 }; 245 }; 246 } 247 else if (hi == 0x8f) { 248 ADDCODE(z, maxzen, count, hi, 1); 249 code = (((unsigned long)h[0]) << 8) 250 | ((unsigned long)h[1]); h += 2; 251 byte = 2; 252 } 253 else if ( hi & 0x80 ) 254 code = (hi<<8)|*h++; 255 else { 256 if ( !(code = hiragana[hi]) ) 257 code = hi; 258 byte = (code>>8) ? 2 : 1; 259 } 260 ADDCODE(z, maxzen, count, code, byte); 261 }; 262 if ( z ) 263 *z = 0; 264 return count; 265} 266/* RkCvtHan 267 * zenkaku kana moji wo hankaku moji ni suru 268 */ 269int 270RkCvtHan(unsigned char *han, int maxhan, unsigned char *zen, int maxzen) 271{ 272 unsigned char *h = han; 273 unsigned char *z = zen; 274 unsigned char *Z = zen + maxzen; 275 unsigned short hi, lo; 276 unsigned short byte; 277 int count = 0; 278 unsigned long code; 279 280 if ( --maxhan <= 0 ) 281 return 0; 282 while ( z < Z ) { 283 hi = *z++; 284 byte = 1; 285 switch(hi) { 286 case 0xa1: /* kigou */ 287 lo = *z++; 288 if ( !(code = hankaku[lo&0x7f]) ) 289 code = (hi<<8)|lo; 290 byte = (code>>8) ? 2 : 1; 291 break; 292 case 0xa3: /* eisuuji */ 293 lo = *z++; 294 if ( 0xb0 <= lo && lo <= 0xb9 ) code = (lo - 0xb0) + '0'; 295 else 296 if ( 0xc1 <= lo && lo <= 0xda ) code = (lo - 0xc1) + 'A'; 297 else 298 if ( 0xe1 <= lo && lo <= 0xfa ) code = (lo - 0xe1) + 'a'; 299 else 300 code = (hi<<8)|lo, byte = 2; 301 break; 302 case 0xa4: /* hiragana */ 303 case 0xa5: /* katakana */ 304 lo = *z++; 305 if ( (code = hankaku[lo]) && 306 (lo <= (unsigned short)(hi==0xa4 ? 0xf3: 0xf6)) ) { 307 if ( code>>8 ) { 308 code = 0x8e000000|((code>>8)<<16)|0x00008e00|(code&255); 309 byte = 4; 310 } 311 else { 312 code = 0x00008e00|(code&255); 313 byte = 2; 314 }; 315 } 316 else 317 code = (hi<<8)|lo, byte = 2; 318 break; 319 default: 320 if (hi == 0x8f) { 321 ADDCODE(h, maxhan, count, hi, 1); 322 code = (((unsigned long)z[0]) << 8) 323 | ((unsigned long)z[1]); z += 2; 324 byte = 2; 325 } 326 else if ( hi & 0x80 ) { /* kanji */ 327 code = (hi<<8)|(*z++); 328 byte = 2; 329 } 330 else 331 switch(hi) { 332 /* 333 case ',': code = 0x8ea4; byte = 2; break; 334 case '-': code = 0x8eb0; byte = 2; break; 335 case '.': code = 0x8ea1; byte = 2; break; 336 */ 337 default: code = hi; break; 338 }; 339 break; 340 }; 341 ADDCODE(h, maxhan, count, code, byte); 342 }; 343 if ( h ) 344 *h = 0; 345 return count; 346} 347/* RkCvtKana/RkCvtHira 348 * zenkaku hiragana wo katakana ni suru 349 */ 350int 351RkCvtKana(unsigned char *kana, int maxkana, unsigned char *hira, int maxhira) 352{ 353 register unsigned char *k = kana; 354 register unsigned char *h = hira; 355 register unsigned char *H = hira + maxhira; 356 unsigned short hi; 357 unsigned short byte; 358 int count = 0; 359 unsigned long code; 360 361 if ( --maxkana <= 0 ) 362 return 0; 363 while ( h < H ) { 364 hi = *h++; 365 if (hi == 0x8f) { 366 ADDCODE(k, maxkana, count, hi, 1); 367 code = (((unsigned long)h[0]) << 8) 368 | ((unsigned long)h[1]); h += 2; 369 byte = 2; 370 } 371 else if ( hi & 0x80 ) { 372 int dakuon; 373 374 code = (hi == 0xa4) ? (0xa500|(*h++)) : ((hi<<8)|(*h++)); 375 byte = 2; 376 /* hiragana U + " */ 377 dakuon = ( h + 1 < H && 378 ((((unsigned long)h[0])<<8)|((unsigned long)h[1])) == 0xa1ab ); 379 if ( hi == 0xa4 && code == 0xa5a6 && dakuon ) { 380 code = 0xa5f4; 381 h += 2; 382 }; 383 } 384 else 385 code = hi, byte = 1; 386 ADDCODE(k, maxkana, count, code, byte); 387 }; 388 if ( k ) 389 *k = 0; 390 return count; 391} 392int 393RkCvtHira(unsigned char *hira, int maxhira, unsigned char *kana, int maxkana) 394{ 395 register unsigned char *h = hira; 396 register unsigned char *k = kana; 397 register unsigned char *K = kana + maxkana; 398 unsigned short hi; 399 unsigned short byte; 400 int count = 0; 401 unsigned long code; 402 403 if ( --maxhira <= 0 ) 404 return 0; 405 while ( k < K ) { 406 hi = *k++; 407 if (hi == 0x8f) { 408 ADDCODE(h, maxhira, count, hi, 1); 409 code = (((unsigned long)k[0]) << 8) 410 | ((unsigned long)k[1]); k += 2; 411 byte = 2; 412 } 413 else if ( hi & 0x80 ) { 414 code = (hi == 0xa5) ? (0xa400|(*k++)) : ((hi<<8)|(*k++)); 415 byte = 2; 416 /* katakana U + " */ 417 if ( code == 0xa4f4 ) { /* u no dakuon */ 418 code = 0xa4a6a1ab; 419 byte = 4; 420 } 421 else 422 if ( code == 0xa4f5 ) 423 code = 0xa4ab; 424 else 425 if ( code == 0xa4f6 ) 426 code = 0xa4b1; 427 } 428 else 429 code = hi, byte = 1; 430 ADDCODE(h, maxhira, count, code, byte); 431 }; 432 if ( h ) 433 *h = 0; 434 return count; 435} 436int 437RkCvtNone(unsigned char *dst, int maxdst, unsigned char *src, int maxsrc) 438{ 439 register unsigned char *d = dst; 440 register unsigned char *s = src; 441 register unsigned char *S = src + maxsrc; 442 unsigned short byte; 443 int count = 0; 444 unsigned long code; 445 446 if ( --maxdst <= 0 ) 447 return 0; 448 while ( s < S ) { 449 code = *s++; 450 byte = 1; 451 if (code == 0x8f) { 452 ADDCODE(d, maxdst, count, code, 1); 453 code = (((unsigned long)s[0]) << 8) 454 | ((unsigned long)s[1]); s += 2; 455 byte = 2; 456 } 457 else if ( code & 0x80 ) 458 code = (code<<8)|(*s++), byte = 2; 459 ADDCODE(d, maxdst, count, code, byte); 460 }; 461 if ( d ) 462 *d = 0; 463 return count; 464} 465 466/* RkEuc 467 * shift jis --> euc 468 */ 469int 470RkCvtEuc(unsigned char *euc, int maxeuc, unsigned char *sj, int maxsj) 471{ 472 unsigned char *e = euc; 473 unsigned char *s = sj; 474 unsigned char *S = sj + maxsj; 475 unsigned short hi, lo; 476 unsigned short byte; 477 int count = 0; 478 unsigned long code; 479 480 if ( --maxeuc <= 0 ) 481 return 0; 482 483 while ( s < S ) { 484 hi = *s++; 485 if ( hi <= 0x7f ) /* ascii */ 486 code = hi, byte = 1; 487 else 488 if ( 0xa0 <= hi && hi <= 0xdf ) /* hankaku katakana */ 489 code = 0x8e00|hi, byte = 2; 490 else 491 if (0xf0 <= hi && hi <= 0xfc) { /* gaiji */ 492 hi -= 0xf0; 493 hi = 2*hi + 0x21; 494 if ((lo = *s++) <= 0x9e) { 495 if (lo < 0x80) 496 lo++; 497 lo -= 0x20; 498 } 499 else { 500 hi++; 501 lo -= 0x7e; 502 } 503 code = 0x8f8080 | (hi<<8) | lo, byte = 3; 504 } 505 else { 506 hi -= (hi <= 0x9f) ? 0x80 : 0xc0; 507 hi = 2*hi + 0x20; 508 if ( (lo = *s++) <= 0x9e ) { /* kisuu ku */ 509 hi--; 510 if ( 0x80 <= lo ) lo--; 511 lo -= (0x40 - 0x21); 512 } 513 else /* guusuu ku */ 514 lo -= (0x9f - 0x21); 515 code = 0x8080|(hi<<8)|lo, byte = 2; 516 }; 517 ADDCODE(e, maxeuc, count, code, byte); 518 }; 519 if ( e ) 520 *e = 0; 521 return count; 522} 523/* RkCvtSuuji 524 * arabia suuji wo kansuuji ni kaeru 525 */ 526static unsigned suujinew[] = { 527 0xa1bb, 0xb0ec, 0xc6f3, 0xbbb0, 0xbbcd, 528 0xb8de, 0xcfbb, 0xbcb7, 0xc8ac, 0xb6e5, 529}; 530static unsigned suujiold[] = { 531 0xa1bb, 0xb0ed, 0xc6f5, 0xbbb2, 0xbbcd, 532 0xb8e0, 0xcfbb, 0xbcb7, 0xc8ac, 0xb6e5, 533}; 534static unsigned kurai4[] = { 535 0, 0xcbfc, 0xb2af, 0xc3fb, 0xb5fe, 0, 536}; 537 538static unsigned kurai3new[] = { 0, 0xbdbd, 0xc9b4, 0xc0e9, }; 539static unsigned kurai3old[] = { 0, 0xbdbd, 0xc9b4, 0xc0e9, }; 540 541int 542RkCvtSuuji(unsigned char *dst, int maxdst, unsigned char *src, int maxsrc, int format) 543{ 544 int count; 545 int i, j, k; 546 int digit[4], pend; 547 unsigned code, tmp; 548 unsigned char *d = dst; 549 unsigned char *s = src + maxsrc - 1; 550 551 if ( --maxdst <= 0 ) 552 return 0; 553/* yuukou keta suu wo kazoeru */ 554 pend = 0; 555 for ( count = k = 0; s >= src; k++ ) { 556 int dec; 557 558 if ( *s & 0x80 ) { 559 if ( !(0xb0 <= *s && *s <= 0xb9) ) 560 break; 561 dec = *s - 0xb0; 562 if ( --s < src || *s != 0xa3 ) 563 break; 564 s--; 565 } 566 else { 567 if ( !('0' <= *s && *s <= '9') ) 568 break; 569 dec = *s-- - '0'; 570 }; 571 572 switch(format) { 573 /* simple */ 574 case 0: /* sanyou suuji */ 575 code = hiragana[dec + '0']; 576 ADDCODE(d, maxdst, count, code, 2); 577 break; 578 case 1: /* kanji suuji */ 579 code = suujinew[dec]; 580 ADDCODE(d, maxdst, count, code, 2); 581 break; 582 /* kanji kurai dori */ 583 case 2: 584 case 3: 585 case 4: /* 12 O 3456 M 7890 */ 586 digit[pend++] = dec; 587 if ( pend == 4 ) { 588 while ( pend > 0 && digit[pend - 1] == 0 ) 589 pend--; 590 if ( pend ) { 591 /* kurai wo shuturyoku */ 592 code = kurai4[k/4]; 593 if (code) 594 ADDCODE(d, maxdst, count, code, 2) 595 else 596 if ( k >= 4 ) 597 return 0; 598 599 for ( i = 0; i < pend; i++ ) 600 switch(format) { 601 case 2: 602 if ( digit[i] ) { 603 code = kurai3new[i]; 604 if (code) 605 ADDCODE(d, maxdst, count, code, 2); 606 if ( i == 0 || (digit[i] > 1) ) { 607 code = suujinew[digit[i]]; 608 ADDCODE(d, maxdst, count, code, 2); 609 }; 610 }; 611 break; 612 case 3: 613 if ( digit[i] ) { 614 code = kurai3old[i]; 615 if (code) 616 ADDCODE(d, maxdst, count, code, 2); 617 code = suujiold[digit[i]]; 618 ADDCODE(d, maxdst, count, code, 2); 619 }; 620 break; 621 case 4: 622 code = hiragana[digit[i]+'0']; 623 ADDCODE(d, maxdst, count, code, 2); 624 break; 625 }; 626 }; 627 pend = 0; 628 }; 629 break; 630 case 5: /* 1,234,567,890 */ 631 if ( k && k%3 == 0 ) { 632 code = hiragana[',']; 633 ADDCODE(d, maxdst, count, code, 2); 634 }; 635 code = hiragana[dec + '0']; 636 ADDCODE(d, maxdst, count, code, 2); 637 break; 638 default: 639 return 0; 640 }; 641 }; 642 643 if ( format == 2 || format == 3 || format == 4 ) { 644 while ( pend > 0 && digit[pend - 1] == 0 ) 645 pend--; 646 if ( pend ) { 647 code = kurai4[k/4]; 648 if (code) 649 ADDCODE(d, maxdst, count, code, 2) 650 else 651 if ( k >= 4 ) 652 return 0; 653 for ( i = 0; i < pend; i++ ) 654 switch(format) { 655 case 2: 656 if ( digit[i] ) { 657 code = kurai3new[i]; 658 if (code) 659 ADDCODE(d, maxdst, count, code, 2); 660 if ( i == 0 || (digit[i] > 1) ) { 661 code = suujinew[digit[i]]; 662 ADDCODE(d, maxdst, count, code, 2); 663 }; 664 }; 665 break; 666 case 3: 667 if ( digit[i] ) { 668 code = kurai3old[i]; 669 if (code) 670 ADDCODE(d, maxdst, count, code, 2); 671 code = suujiold[digit[i]]; 672 ADDCODE(d, maxdst, count, code, 2); 673 }; 674 break; 675 case 4: 676 code = hiragana[digit[i]+'0']; 677 ADDCODE(d, maxdst, count, code, 2); 678 break; 679 }; 680 }; 681 }; 682 683 if ( dst ) { 684 *d = 0; 685 for ( i = 0, j = count - 1; i < j; i++, j-- ) { 686 tmp = dst[i]; dst[i] = dst[j]; dst[j] = tmp; 687 }; 688 for ( i = count - 1; i > 0; i-- ) 689 if ( dst[i] & 0x80 ) { 690 tmp = dst[i+0]; dst[i+0] = dst[i-1]; dst[i-1] = tmp; 691 i--; 692 }; 693 }; 694 return count; 695} 696 697/* ¥ï¥¤¥É¥¥ã¥é¥¯¥¿ */ 698 699#define CBUFSIZE 512 700 701int 702RkwCvtHan(WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen) 703{ 704 int len = 0; 705#ifndef WIN 706 char cbuf[CBUFSIZE], cbuf2[CBUFSIZE]; 707#else 708 char *cbuf, *cbuf2; 709 710 cbuf = malloc(CBUFSIZE); 711 cbuf2 = malloc(CBUFSIZE); 712 if (!cbuf || !cbuf2) { 713 if (cbuf) { 714 free(cbuf); 715 } 716 if (cbuf2) { 717 free(cbuf2); 718 } 719 return len; 720 } 721#endif 722 723 len = CNvW2E(src, srclen, cbuf, CBUFSIZE); 724 len = RkCvtHan((unsigned char *)cbuf2, CBUFSIZE, (unsigned char *)cbuf, len); 725 if (len > 0) { 726 cbuf2[len] = '\0'; 727 len = MBstowcs(dst, cbuf2, maxdst); 728 } 729#ifdef WIN 730 free(cbuf2); 731 free(cbuf); 732#endif 733 return len; 734} 735 736int 737RkwCvtHira(WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen) 738{ 739 int len = 0; 740#ifndef WIN 741 char cbuf[CBUFSIZE], cbuf2[CBUFSIZE]; 742#else 743 char *cbuf, *cbuf2; 744 745 cbuf = malloc(CBUFSIZE); 746 cbuf2 = malloc(CBUFSIZE); 747 if (!cbuf || !cbuf2) { 748 if (cbuf) { 749 free(cbuf); 750 } 751 if (cbuf2) { 752 free(cbuf2); 753 } 754 return len; 755 } 756#endif 757 758 len = CNvW2E(src, srclen, cbuf, CBUFSIZE); 759 len = RkCvtHira((unsigned char *)cbuf2, CBUFSIZE, 760 (unsigned char *)cbuf, len); 761 if (len > 0) { 762 cbuf2[len] = (unsigned char)0; 763 len = MBstowcs(dst, cbuf2, maxdst); 764 } 765#ifdef WIN 766 free(cbuf2); 767 free(cbuf); 768#endif 769 return len; 770} 771 772int 773RkwCvtKana(WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen) 774{ 775 int len = 0; 776#ifndef WIN 777 char cbuf[CBUFSIZE], cbuf2[CBUFSIZE]; 778#else 779 char *cbuf, *cbuf2; 780 781 cbuf = malloc(CBUFSIZE); 782 cbuf2 = malloc(CBUFSIZE); 783 if (!cbuf || !cbuf2) { 784 if (cbuf) { 785 free(cbuf); 786 } 787 if (cbuf2) { 788 free(cbuf2); 789 } 790 return len; 791 } 792#endif 793 794 len = CNvW2E(src, srclen, cbuf, CBUFSIZE); 795 len = RkCvtKana((unsigned char *)cbuf2, CBUFSIZE, 796 (unsigned char *)cbuf, len); 797 if (len > 0) { 798 cbuf2[len] = '\0'; 799 len = MBstowcs(dst, cbuf2, maxdst); 800 } 801#ifdef WIN 802 free(cbuf2); 803 free(cbuf); 804#endif 805 return len; 806} 807 808int 809RkwCvtZen(WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen) 810{ 811 int len = 0; 812#ifndef WIN 813 char cbuf[CBUFSIZE], cbuf2[CBUFSIZE]; 814#else 815 char *cbuf, *cbuf2; 816 817 cbuf = malloc(CBUFSIZE); 818 cbuf2 = malloc(CBUFSIZE); 819 if (!cbuf || !cbuf2) { 820 if (cbuf) { 821 free(cbuf); 822 } 823 if (cbuf2) { 824 free(cbuf2); 825 } 826 return len; 827 } 828#endif 829 830 len = CNvW2E(src, srclen, cbuf, CBUFSIZE); 831 len = RkCvtZen((unsigned char *)cbuf2, CBUFSIZE, 832 (unsigned char *)cbuf, len); 833 if (len > 0) { 834 cbuf2[len] = '\0'; 835 len = MBstowcs(dst, cbuf2, maxdst); 836 } 837#ifdef WIN 838 free(cbuf2); 839 free(cbuf); 840#endif 841 return len; 842} 843 844int 845RkwCvtNone(WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen) 846{ 847 int i; 848 849 if(!dst || !src) return 0; 850 851 int len = (maxdst < srclen) ? maxdst : srclen; 852 for (int i = 0 ; i < len ; i++) { 853 *dst++ = *src++; 854 } 855/* *dst = *src; ¤Ê¤ó¤Ç¤³¤ì¤¬É¬ÍפʤΡ© */ 856 return len; 857} 858 859int 860RkwMapRoma(struct RkRxDic *romaji, WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen, int flags, int *status) 861{ 862 int len = 0, ret; 863 char cbuf1[CBUFSIZE], cbuf2[CBUFSIZE]; 864 865 len = CNvW2E(src, srclen, cbuf1, CBUFSIZE); 866 len = RkMapRoma(romaji, (unsigned char *)cbuf2, CBUFSIZE, 867 (unsigned char *)cbuf1, len, flags, status); 868 cbuf2[(*status > 0) ? *status : -*status] = (unsigned char)0; 869 ret = MBstowcs(dst, cbuf2, maxdst); 870 if (*status > 0) { 871 *status = ret; 872 } 873 else { 874 *status = -ret; 875 } 876 877 return len; 878} 879 880int 881RkwMapPhonogram(struct RkRxDic *romaji, WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen, WCHAR_T key, int flags, int *ulen, int *dlen, int *tlen, int *rule) 882{ 883 int status = 0; 884 char tmpch; 885 int len, ret, fdlen, fulen, ftlen; 886 char cbuf1[CBUFSIZE], cbuf2[CBUFSIZE]; 887 WCHAR_T wbuf[CBUFSIZE]; 888 889 len = CNvW2E(src, srclen, cbuf1, CBUFSIZE); 890 status = RkMapPhonogram(romaji, (unsigned char *)cbuf2, CBUFSIZE, 891 (unsigned char *)cbuf1, len, 892 (unsigned) key, flags, 893 &fulen, &fdlen, &ftlen, rule); 894 tmpch = cbuf2[fdlen]; 895 cbuf2[fdlen] = '\0'; 896 ret = MBstowcs(dst, cbuf2, maxdst); 897 cbuf2[fdlen] = tmpch; 898 if (dlen) { 899 *dlen = ret; 900 } 901 cbuf2[fdlen + ftlen] = (unsigned char)0; 902 ret = MBstowcs(dst + ret, cbuf2 + fdlen, maxdst - ret); 903 if (tlen) { 904 *tlen = ret; 905 } 906 if (ulen) { 907 cbuf1[fulen] = '\0'; 908 *ulen = MBstowcs(wbuf, cbuf1, CBUFSIZE); 909 } 910 911 return status; 912} 913 914int 915RkwCvtRoma(struct RkRxDic *romaji, WCHAR_T *dst, int maxdst, WCHAR_T *src, int srclen, int flags) 916{ 917 int ret = 0, len; 918 char cbuf1[CBUFSIZE], cbuf2[CBUFSIZE]; 919 920 if (srclen) { 921 len = CNvW2E(src, srclen, cbuf1, CBUFSIZE); 922 len = RkCvtRoma(romaji, (unsigned char *)cbuf2, CBUFSIZE, 923 (unsigned char *)cbuf1, len, flags); 924 cbuf2[len] = (unsigned char)0; 925 ret = MBstowcs(dst, cbuf2, maxdst); 926 dst[ret] = (WCHAR_T)0; 927 } else { 928 ret = 0; 929 *dst = (WCHAR_T)0; 930 } 931 932 return ret; 933} 934 935#define SUUJI_THROUGH 0 936#define SUUJI_HANKAKU 1 937#define SUUJI_ZENKAKU 2 938#define SUUJI_SIMPLEKANJI 3 939#define SUUJI_FULLKANJI 4 940#define SUUJI_FULLKANJITRAD 5 941#define SUUJI_WITHKANJIUNIT 6 942#define SUUJI_WITHCOMMA 7 943 944/* RkCvtSuuji 945 * arabia suuji wo kansuuji ni kaeru 946 */ 947int 948RkwCvtSuuji(WCHAR_T *dst, int maxdst, WCHAR_T *src, int maxsrc, int format) 949{ 950 int count; 951 int i, j, k; 952 int digit[4], pend; 953 WCHAR_T code, tmp; 954 WCHAR_T *d = dst; 955 WCHAR_T *s = src + maxsrc - 1; 956 957 if ( --maxdst <= 0 ) 958 return 0; 959 /* ͸ú¤Ê·å¿ô¤ò¿ô¤¨¤ë */ 960 pend = 0; 961 for ( count = k = 0; s >= src; k++ ) { 962 int dec, thru = *s; 963 964 if ( thru & 0x8080 ) { 965 if ( !((WCHAR_T)0xa3b0 <= *s && *s <= (WCHAR_T)0xa3b9) ) 966 break; 967 dec = *s-- - 0xa3b0; 968 } 969 else { 970 if ( !((WCHAR_T)'0' <= *s && *s <= (WCHAR_T)'9') ) 971 break; 972 dec = *s-- - '0'; 973 } 974 975 switch(format) { 976 /* simple */ 977 case SUUJI_THROUGH: /* sanyou suuji */ 978 code = thru; 979 ADDWCODE(d, maxdst, count, code); 980 break; 981 case SUUJI_HANKAKU: /* sanyou suuji */ 982 code = dec + '0'; 983 if (code == thru) { 984 return 0; 985 } 986 ADDWCODE(d, maxdst, count, code); 987 break; 988 case SUUJI_ZENKAKU: /* sanyou suuji */ 989 code = hiragana[dec + '0']; 990 if (code == thru) { 991 return 0; 992 } 993 ADDWCODE(d, maxdst, count, code); 994 break; 995 /* kanji kurai dori */ 996 case SUUJI_SIMPLEKANJI: /* kanji suuji */ 997 code = suujinew[dec]; 998 ADDWCODE(d, maxdst, count, code); 999 break; 1000 case SUUJI_FULLKANJI: 1001 case SUUJI_FULLKANJITRAD: 1002 case SUUJI_WITHKANJIUNIT: /* 12 O 3456 M 7890 */ 1003 digit[pend++] = dec; 1004 if ( pend == 4 ) { 1005 while ( pend > 0 && digit[pend - 1] == 0 ) 1006 pend--; 1007 if ( pend ) { 1008 /* kurai wo shuturyoku */ 1009 code = kurai4[k/4]; 1010 if (code) 1011 ADDWCODE(d, maxdst, count, code) 1012 else 1013 if ( k >= 4 ) 1014 return 0; 1015 1016 for ( i = 0; i < pend; i++ ) 1017 switch(format) { 1018 case SUUJI_FULLKANJI: 1019 if ( digit[i] ) { 1020 code = kurai3new[i]; 1021 if (code) 1022 ADDWCODE(d, maxdst, count, code); 1023 if ( i == 0 || (digit[i] > 1) ) { 1024 code = suujinew[digit[i]]; 1025 ADDWCODE(d, maxdst, count, code); 1026 } 1027 } 1028 break; 1029 case SUUJI_FULLKANJITRAD: 1030 if ( digit[i] ) { 1031 code = kurai3old[i]; 1032 if (code) 1033 ADDWCODE(d, maxdst, count, code); 1034 code = suujiold[digit[i]]; 1035 ADDWCODE(d, maxdst, count, code); 1036 }; 1037 break; 1038 case SUUJI_WITHKANJIUNIT: 1039 code = hiragana[digit[i]+'0']; 1040 ADDWCODE(d, maxdst, count, code); 1041 break; 1042 } 1043 } 1044 pend = 0; 1045 } 1046 break; 1047 case SUUJI_WITHCOMMA: /* 1,234,567,890 */ 1048 if ( k && k%3 == 0 ) { 1049 code = hiragana[',']; 1050 ADDWCODE(d, maxdst, count, code); 1051 } 1052 code = hiragana[dec + '0']; 1053 ADDWCODE(d, maxdst, count, code); 1054 break; 1055 default: 1056 return 0; 1057 }; 1058 }; 1059 1060 if (format == SUUJI_FULLKANJI || format == SUUJI_FULLKANJITRAD || 1061 format == SUUJI_WITHKANJIUNIT) { 1062 while ( pend > 0 && digit[pend - 1] == 0 ) 1063 pend--; 1064 if ( pend ) { 1065 code = kurai4[k/4]; 1066 if (code) 1067 ADDWCODE(d, maxdst, count, code) 1068 else 1069 if ( k >= 4 ) 1070 return 0; 1071 for ( i = 0; i < pend; i++ ) 1072 switch(format) { 1073 case SUUJI_FULLKANJI: 1074 if ( digit[i] ) { 1075 code = kurai3new[i]; 1076 if (code) 1077 ADDWCODE(d, maxdst, count, code); 1078 if ( i == 0 || (digit[i] > 1) ) { 1079 code = suujinew[digit[i]]; 1080 ADDWCODE(d, maxdst, count, code); 1081 }; 1082 }; 1083 break; 1084 case SUUJI_FULLKANJITRAD: 1085 if ( digit[i] ) { 1086 code = kurai3old[i]; 1087 if (code) 1088 ADDWCODE(d, maxdst, count, code); 1089 code = suujiold[digit[i]]; 1090 ADDWCODE(d, maxdst, count, code); 1091 }; 1092 break; 1093 case SUUJI_WITHKANJIUNIT: 1094 code = hiragana[digit[i]+'0']; 1095 ADDWCODE(d, maxdst, count, code); 1096 break; 1097 } 1098 } 1099 } 1100 1101 if ( dst ) { 1102 *d = 0; 1103 for ( i = 0, j = count - 1; i < j; i++, j-- ) { 1104 tmp = dst[i]; dst[i] = dst[j]; dst[j] = tmp; 1105 } 1106 } 1107 return count; 1108} 1109/* RkCvtNarrow 1110 * 1111 */ 1112int 1113RkCvtNarrow(char *dst, int maxdst, WCHAR_T *src, int maxsrc) 1114{ 1115#ifdef USE_SJIS_TEXT_DIC 1116 return Wcstosjis(dst, maxdst, src, maxsrc); 1117#else /* !USE_SJIS_TEXT_DIC */ 1118 unsigned char *d = (unsigned char *)dst; 1119 WCHAR_T *s = src; 1120 WCHAR_T *S = src + maxsrc; 1121 int count = 0; 1122 long code; 1123 int byte; 1124 1125 if ( --maxdst <= 0 ) 1126 return count; 1127 while ( s < S ) 1128 { 1129 code = *s++; 1130 switch(code&0x8080) 1131 { 1132 case 0x0000: 1133 code &= 0xff; 1134 byte = 1; 1135 break; 1136 case 0x0080: 1137 code &= 0xff; 1138 code |= 0x8e00; 1139 byte = 2; 1140 break; 1141 case 0x8000: 1142 code &= 0xffff; 1143 code |= 0x8f8080; 1144 byte = 3; 1145 break; 1146 case 0x8080: 1147 code &= 0xffff; 1148 byte = 2; 1149 break; 1150 }; 1151 ADDCODE(d, maxdst, count, code, byte); 1152 }; 1153 if ( d ) 1154 *d = 0; 1155 return count; 1156#endif /* !USE_SJIS_TEXT_DIC */ 1157} 1158 1159/* RkCvtWide 1160 * 1161 */ 1162int 1163RkCvtWide(WCHAR_T *dst, int maxdst, char *src, int maxsrc) 1164{ 1165#ifdef USE_SJIS_TEXT_DIC 1166 return SJistowcs(dst, maxdst, src, maxsrc); 1167#else /* !USE_SJIS_TEXT_DIC, that is, EUC */ 1168 WCHAR_T *d = dst; 1169 unsigned char *s = (unsigned char *)src; 1170 unsigned char *S = (unsigned char *)src + maxsrc; 1171 int count = 0; 1172 unsigned long code; 1173 1174 if ( --maxdst <= 0 ) 1175 return count; 1176 while ( s < S ) 1177 { 1178 code = *s++; 1179 if ( code & 0x80 ) 1180 { 1181 switch(code) 1182 { 1183 case RK_SS2: /* hankaku katakana */ 1184 code = 0x0080|(s[0]&0x7f); 1185 s++; 1186 break; 1187 case RK_SS3: /* gaiji */ 1188 code = 0x8000|(((s[0]<<8)|s[1])&0x7f7f); 1189 s += 2; 1190 break; 1191 default: 1192 code = 0x8080|(((s[-1]<<8)|s[0])&0x7f7f); 1193 s += 1; 1194 }; 1195 }; 1196 ADDWCODE(d, maxdst, count, (WCHAR_T)code); 1197 }; 1198 if ( d ) 1199 *d = 0; 1200 return count; 1201#endif /* !USE_SJIS_TEXT_DIC */ 1202} 1203 1204