conv.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:21k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*
  2.  * conversion between client encoding and server internal encoding
  3.  * (currently mule internal code (mic) is used)
  4.  * Tatsuo Ishii
  5.  * WIN1250 client encoding support contributed by Pavel Behal
  6.  *
  7.  * $Id: conv.c,v 1.12 1999/07/11 22:47:20 ishii Exp $
  8.  *
  9.  *
  10.  */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "mb/pg_wchar.h"
  14. /*
  15.  * convert bogus chars that cannot be represented in the current
  16. encoding
  17.  * system.
  18.  */
  19. static void
  20. printBogusChar(unsigned char **mic, unsigned char **p)
  21. {
  22. char strbuf[16];
  23. int l = pg_mic_mblen(*mic);
  24. *(*p)++ = '(';
  25. while (l--)
  26. {
  27. sprintf(strbuf, "%02x", *(*mic)++);
  28. *(*p)++ = strbuf[0];
  29. *(*p)++ = strbuf[1];
  30. }
  31. *(*p)++ = ')';
  32. }
  33. /*
  34.  * SJIS ---> MIC
  35.  */
  36. static void
  37. sjis2mic(unsigned char *sjis, unsigned char *p, int len)
  38. {
  39. int c1,
  40. c2;
  41. while (len > 0 && (c1 = *sjis++))
  42. {
  43. if (c1 >= 0xa1 && c1 <= 0xdf)
  44. { /* 1 byte kana? */
  45. len--;
  46. *p++ = LC_JISX0201K;
  47. *p++ = c1;
  48. }
  49. else if (c1 > 0x7f)
  50. { /* kanji? */
  51. c2 = *sjis++;
  52. len -= 2;
  53. *p++ = LC_JISX0208;
  54. *p++ = ((c1 & 0x3f) << 1) + 0x9f + (c2 > 0x9e);
  55. *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
  56. }
  57. else
  58. { /* should be ASCII */
  59. len--;
  60. *p++ = c1;
  61. }
  62. }
  63. *p = '';
  64. }
  65. /*
  66.  * MIC ---> SJIS
  67.  */
  68. static void
  69. mic2sjis(unsigned char *mic, unsigned char *p, int len)
  70. {
  71. int c1,
  72. c2;
  73. while (len > 0 && (c1 = *mic))
  74. {
  75. len -= pg_mic_mblen(mic++);
  76. if (c1 == LC_JISX0201K)
  77. *p++ = *mic++;
  78. else if (c1 == LC_JISX0208)
  79. {
  80. c1 = *mic++;
  81. c2 = *mic++;
  82. *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1);
  83. *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
  84. }
  85. else if (c1 > 0x7f)
  86. { /* cannot convert to SJIS! */
  87. mic--;
  88. printBogusChar(&mic, &p);
  89. }
  90. else
  91. { /* should be ASCII */
  92. *p++ = c1;
  93. }
  94. }
  95. *p = '';
  96. }
  97. /*
  98.  * EUC_JP ---> MIC
  99.  */
  100. static void
  101. euc_jp2mic(unsigned char *euc, unsigned char *p, int len)
  102. {
  103. int c1;
  104. while (len > 0 && (c1 = *euc++))
  105. {
  106. if (c1 == SS2)
  107. { /* 1 byte kana? */
  108. len -= 2;
  109. *p++ = LC_JISX0201K;
  110. *p++ = *euc++;
  111. }
  112. else if (c1 == SS3)
  113. { /* JIS X0212 kanji? */
  114. len -= 3;
  115. *p++ = LC_JISX0212;
  116. *p++ = *euc++;
  117. *p++ = *euc++;
  118. }
  119. else if (c1 & 0x80)
  120. { /* kanji? */
  121. len -= 2;
  122. *p++ = LC_JISX0208;
  123. *p++ = c1;
  124. *p++ = *euc++;
  125. }
  126. else
  127. { /* should be ASCII */
  128. len--;
  129. *p++ = c1;
  130. }
  131. }
  132. *p = '';
  133. }
  134. /*
  135.  * MIC ---> EUC_JP
  136.  */
  137. static void
  138. mic2euc_jp(unsigned char *mic, unsigned char *p, int len)
  139. {
  140. int c1;
  141. while (len > 0 && (c1 = *mic))
  142. {
  143. len -= pg_mic_mblen(mic++);
  144. if (c1 == LC_JISX0201K)
  145. {
  146. *p++ = SS2;
  147. *p++ = *mic++;
  148. }
  149. else if (c1 == LC_JISX0212)
  150. {
  151. *p++ = SS3;
  152. *p++ = *mic++;
  153. *p++ = *mic++;
  154. }
  155. else if (c1 == LC_JISX0208)
  156. {
  157. *p++ = *mic++;
  158. *p++ = *mic++;
  159. }
  160. else if (c1 > 0x7f)
  161. { /* cannot convert to EUC_JP! */
  162. mic--;
  163. printBogusChar(&mic, &p);
  164. }
  165. else
  166. { /* should be ASCII */
  167. *p++ = c1;
  168. }
  169. }
  170. *p = '';
  171. }
  172. /*
  173.  * EUC_KR ---> MIC
  174.  */
  175. static void
  176. euc_kr2mic(unsigned char *euc, unsigned char *p, int len)
  177. {
  178. int c1;
  179. while (len > 0 && (c1 = *euc++))
  180. {
  181. if (c1 & 0x80)
  182. {
  183. len -= 2;
  184. *p++ = LC_KS5601;
  185. *p++ = c1;
  186. *p++ = *euc++;
  187. }
  188. else
  189. { /* should be ASCII */
  190. len--;
  191. *p++ = c1;
  192. }
  193. }
  194. *p = '';
  195. }
  196. /*
  197.  * MIC ---> EUC_KR
  198.  */
  199. static void
  200. mic2euc_kr(unsigned char *mic, unsigned char *p, int len)
  201. {
  202. int c1;
  203. while (len > 0 && (c1 = *mic))
  204. {
  205. len -= pg_mic_mblen(mic++);
  206. if (c1 == LC_KS5601)
  207. {
  208. *p++ = *mic++;
  209. *p++ = *mic++;
  210. }
  211. else if (c1 > 0x7f)
  212. { /* cannot convert to EUC_KR! */
  213. mic--;
  214. printBogusChar(&mic, &p);
  215. }
  216. else
  217. { /* should be ASCII */
  218. *p++ = c1;
  219. }
  220. }
  221. *p = '';
  222. }
  223. /*
  224.  * EUC_CN ---> MIC
  225.  */
  226. static void
  227. euc_cn2mic(unsigned char *euc, unsigned char *p, int len)
  228. {
  229. int c1;
  230. while (len > 0 && (c1 = *euc++))
  231. {
  232. if (c1 & 0x80)
  233. {
  234. len -= 2;
  235. *p++ = LC_GB2312_80;
  236. *p++ = c1;
  237. *p++ = *euc++;
  238. }
  239. else
  240. { /* should be ASCII */
  241. len--;
  242. *p++ = c1;
  243. }
  244. }
  245. *p = '';
  246. }
  247. /*
  248.  * MIC ---> EUC_CN
  249.  */
  250. static void
  251. mic2euc_cn(unsigned char *mic, unsigned char *p, int len)
  252. {
  253. int c1;
  254. while (len > 0 && (c1 = *mic))
  255. {
  256. len -= pg_mic_mblen(mic++);
  257. if (c1 == LC_GB2312_80)
  258. {
  259. *p++ = *mic++;
  260. *p++ = *mic++;
  261. }
  262. else if (c1 > 0x7f)
  263. { /* cannot convert to EUC_CN! */
  264. mic--;
  265. printBogusChar(&mic, &p);
  266. }
  267. else
  268. { /* should be ASCII */
  269. *p++ = c1;
  270. }
  271. }
  272. *p = '';
  273. }
  274. /*
  275.  * EUC_TW ---> MIC
  276.  */
  277. static void
  278. euc_tw2mic(unsigned char *euc, unsigned char *p, int len)
  279. {
  280. int c1;
  281. while (len > 0 && (c1 = *euc++))
  282. {
  283. if (c1 == SS2)
  284. {
  285. len -= 4;
  286. c1 = *euc++; /* plane No. */
  287. if (c1 == 0xa1)
  288. *p++ = LC_CNS11643_1;
  289. else if (c1 == 0xa2)
  290. *p++ = LC_CNS11643_2;
  291. else
  292. {
  293. *p++ = 0x9d; /* LCPRV2 */
  294. *p++ = 0xa3 - c1 + LC_CNS11643_3;
  295. }
  296. *p++ = *euc++;
  297. *p++ = *euc++;
  298. }
  299. else if (c1 & 0x80)
  300. { /* CNS11643-1 */
  301. len -= 2;
  302. *p++ = LC_CNS11643_1;
  303. *p++ = c1;
  304. *p++ = *euc++;
  305. }
  306. else
  307. { /* should be ASCII */
  308. len--;
  309. *p++ = c1;
  310. }
  311. }
  312. *p = '';
  313. }
  314. /*
  315.  * MIC ---> EUC_TW
  316.  */
  317. static void
  318. mic2euc_tw(unsigned char *mic, unsigned char *p, int len)
  319. {
  320. int c1;
  321. while (len > 0 && (c1 = *mic))
  322. {
  323. len -= pg_mic_mblen(mic++);
  324. if (c1 == LC_CNS11643_1 || c1 == LC_CNS11643_2)
  325. {
  326. *p++ = *mic++;
  327. *p++ = *mic++;
  328. }
  329. else if (c1 == 0x9d)
  330. { /* LCPRV2? */
  331. *p++ = SS2;
  332. *p++ = c1 - LC_CNS11643_3 + 0xa3;
  333. *p++ = *mic++;
  334. *p++ = *mic++;
  335. }
  336. else if (c1 > 0x7f)
  337. { /* cannot convert to EUC_TW! */
  338. mic--;
  339. printBogusChar(&mic, &p);
  340. }
  341. else
  342. { /* should be ASCII */
  343. *p++ = c1;
  344. }
  345. }
  346. *p = '';
  347. }
  348. /*
  349.  * Big5 ---> MIC
  350.  */
  351. static void
  352. big52mic(unsigned char *big5, unsigned char *p, int len)
  353. {
  354. unsigned short c1;
  355. unsigned short big5buf,
  356. cnsBuf;
  357. unsigned char lc;
  358. char bogusBuf[2];
  359. int i;
  360. while (len > 0 && (c1 = *big5++))
  361. {
  362. if (c1 <= 0x7fU)
  363. { /* ASCII */
  364. len--;
  365. *p++ = c1;
  366. }
  367. else
  368. {
  369. len -= 2;
  370. big5buf = c1 << 8;
  371. c1 = *big5++;
  372. big5buf |= c1;
  373. cnsBuf = BIG5toCNS(big5buf, &lc);
  374. if (lc != 0)
  375. {
  376. if (lc == LC_CNS11643_3 || lc == LC_CNS11643_4)
  377. {
  378. *p++ = 0x9d;/* LCPRV2 */
  379. }
  380. *p++ = lc; /* Plane No. */
  381. *p++ = (cnsBuf >> 8) & 0x00ff;
  382. *p++ = cnsBuf & 0x00ff;
  383. }
  384. else
  385. { /* cannot convert */
  386. big5 -= 2;
  387. *p++ = '(';
  388. for (i = 0; i < 2; i++)
  389. {
  390. sprintf(bogusBuf, "%02x", *big5++);
  391. *p++ = bogusBuf[0];
  392. *p++ = bogusBuf[1];
  393. }
  394. *p++ = ')';
  395. }
  396. }
  397. }
  398. *p = '';
  399. }
  400. /*
  401.  * MIC ---> Big5
  402.  */
  403. static void
  404. mic2big5(unsigned char *mic, unsigned char *p, int len)
  405. {
  406. int l;
  407. unsigned short c1;
  408. unsigned short big5buf,
  409. cnsBuf;
  410. while (len > 0 && (c1 = *mic))
  411. {
  412. l = pg_mic_mblen(mic++);
  413. len -= l;
  414. /* 0x9d means LCPRV2 */
  415. if (c1 == LC_CNS11643_1 || c1 == LC_CNS11643_2 || c1 == 0x9d)
  416. {
  417. if (c1 == 0x9d)
  418. {
  419. c1 = *mic++; /* get plane no. */
  420. }
  421. cnsBuf = (*mic++) << 8;
  422. cnsBuf |= (*mic++) & 0x00ff;
  423. big5buf = CNStoBIG5(cnsBuf, c1);
  424. if (big5buf == 0)
  425. { /* cannot convert to Big5! */
  426. mic -= l;
  427. printBogusChar(&mic, &p);
  428. }
  429. else
  430. {
  431. *p++ = (big5buf >> 8) & 0x00ff;
  432. *p++ = big5buf & 0x00ff;
  433. }
  434. }
  435. else if (c1 <= 0x7f) /* ASCII */
  436. *p++ = c1;
  437. else
  438. { /* cannot convert to Big5! */
  439. mic--;
  440. printBogusChar(&mic, &p);
  441. }
  442. }
  443. *p = '';
  444. }
  445. /*
  446.  * LATINn ---> MIC
  447.  */
  448. static void
  449. latin2mic(unsigned char *l, unsigned char *p, int len, int lc)
  450. {
  451. int c1;
  452. while (len-- > 0 && (c1 = *l++))
  453. {
  454. if (c1 > 0x7f)
  455. { /* Latin1? */
  456. *p++ = lc;
  457. }
  458. *p++ = c1;
  459. }
  460. *p = '';
  461. }
  462. /*
  463.  * MIC ---> LATINn
  464.  */
  465. static void
  466. mic2latin(unsigned char *mic, unsigned char *p, int len, int lc)
  467. {
  468. int c1;
  469. while (len > 0 && (c1 = *mic))
  470. {
  471. len -= pg_mic_mblen(mic++);
  472. if (c1 == lc)
  473. *p++ = *mic++;
  474. else if (c1 > 0x7f)
  475. {
  476. mic--;
  477. printBogusChar(&mic, &p);
  478. }
  479. else
  480. { /* should be ASCII */
  481. *p++ = c1;
  482. }
  483. }
  484. *p = '';
  485. }
  486. static void
  487. latin12mic(unsigned char *l, unsigned char *p, int len)
  488. {
  489. latin2mic(l, p, len, LC_ISO8859_1);
  490. }
  491. static void
  492. mic2latin1(unsigned char *mic, unsigned char *p, int len)
  493. {
  494. mic2latin(mic, p, len, LC_ISO8859_1);
  495. }
  496. static void
  497. latin22mic(unsigned char *l, unsigned char *p, int len)
  498. {
  499. latin2mic(l, p, len, LC_ISO8859_2);
  500. }
  501. static void
  502. mic2latin2(unsigned char *mic, unsigned char *p, int len)
  503. {
  504. mic2latin(mic, p, len, LC_ISO8859_2);
  505. }
  506. static void
  507. latin32mic(unsigned char *l, unsigned char *p, int len)
  508. {
  509. latin2mic(l, p, len, LC_ISO8859_3);
  510. }
  511. static void
  512. mic2latin3(unsigned char *mic, unsigned char *p, int len)
  513. {
  514. mic2latin(mic, p, len, LC_ISO8859_3);
  515. }
  516. static void
  517. latin42mic(unsigned char *l, unsigned char *p, int len)
  518. {
  519. latin2mic(l, p, len, LC_ISO8859_4);
  520. }
  521. static void
  522. mic2latin4(unsigned char *mic, unsigned char *p, int len)
  523. {
  524. mic2latin(mic, p, len, LC_ISO8859_4);
  525. }
  526. #ifdef NOT_USED
  527. static void
  528. latin52mic(unsigned char *l, unsigned char *p, int len)
  529. {
  530. latin2mic(l, p, len, LC_ISO8859_5);
  531. }
  532. static void
  533. mic2latin5(unsigned char *mic, unsigned char *p, int len)
  534. {
  535. mic2latin(mic, p, len, LC_ISO8859_5);
  536. }
  537. #endif
  538. /*
  539.  * ASCII ---> MIC
  540.  */
  541. static void
  542. ascii2mic(unsigned char *l, unsigned char *p, int len)
  543. {
  544. int c1;
  545. while (len-- > 0 && (c1 = *l++))
  546. *p++ = (c1 & 0x7f);
  547. *p = '';
  548. }
  549. /*
  550.  * MIC ---> ASCII
  551.  */
  552. static void
  553. mic2ascii(unsigned char *mic, unsigned char *p, int len)
  554. {
  555. int c1;
  556. while (len-- > 0 && (c1 = *mic))
  557. {
  558. if (c1 > 0x7f)
  559. printBogusChar(&mic, &p);
  560. else
  561. { /* should be ASCII */
  562. *p++ = c1;
  563. }
  564. mic++;
  565. }
  566. *p = '';
  567. }
  568. /*
  569.  * Cyrillic support
  570.  * currently supported Cyrillic encodings:
  571.  *
  572.  * KOI8-R (this is the charset for the mule internal code
  573.  * for Cyrillic)
  574.  * ISO-8859-5
  575.  * Microsoft's CP1251(windows-1251)
  576.  * Alternativny Variant (MS-DOS CP866)
  577.  */
  578. /* koi2mic: KOI8-R to Mule internal code */
  579. static void
  580. koi2mic(unsigned char *l, unsigned char *p, int len)
  581. {
  582. latin2mic(l, p, len, LC_KOI8_R);
  583. }
  584. /* mic2koi: Mule internal code to KOI8-R */
  585. static void
  586. mic2koi(unsigned char *mic, unsigned char *p, int len)
  587. {
  588. mic2latin(mic, p, len, LC_KOI8_R);
  589. }
  590. /*
  591.  * latin2mic_with_table: a generic single byte charset encoding
  592.  * conversion from a local charset to the mule internal code.
  593.  * with a encoding conversion table.
  594.  * the table is ordered according to the local charset,
  595.  * starting from 128 (0x80). each entry in the table
  596.  * holds the corresponding code point for the mule internal code.
  597.  */
  598. static void
  599. latin2mic_with_table(
  600.  unsigned char *l, /* local charset string (source) */
  601.  unsigned char *p, /* pointer to store mule internal
  602.  * code (destination) */
  603.  int len, /* length of l */
  604.  int lc, /* leading character of p */
  605.  unsigned char *tab /* code conversion table */
  606. )
  607. {
  608. unsigned char c1,
  609. c2;
  610. while (len-- > 0 && (c1 = *l++))
  611. {
  612. if (c1 < 128)
  613. *p++ = c1;
  614. else
  615. {
  616. c2 = tab[c1 - 128];
  617. if (c2)
  618. {
  619. *p++ = lc;
  620. *p++ = c2;
  621. }
  622. else
  623. {
  624. *p++ = ' '; /* cannot convert */
  625. }
  626. }
  627. }
  628. *p = '';
  629. }
  630. /*
  631.  * mic2latin_with_table: a generic single byte charset encoding
  632.  * conversion from the mule internal code to a local charset
  633.  * with a encoding conversion table.
  634.  * the table is ordered according to the second byte of the mule
  635.  * internal code starting from 128 (0x80).
  636.  * each entry in the table
  637.  * holds the corresponding code point for the local code.
  638.  */
  639. static void
  640. mic2latin_with_table(
  641.  unsigned char *mic, /* mule internal code
  642.  * (source) */
  643.  unsigned char *p, /* local code (destination) */
  644.  int len, /* length of p */
  645.  int lc, /* leading character */
  646.  unsigned char *tab /* code conversion table */
  647. )
  648. {
  649. unsigned char c1,
  650. c2;
  651. while (len-- > 0 && (c1 = *mic++))
  652. {
  653. if (c1 < 128)
  654. *p++ = c1;
  655. else if (c1 == lc)
  656. {
  657. c1 = *mic++;
  658. len--;
  659. c2 = tab[c1 - 128];
  660. if (c2)
  661. *p++ = c2;
  662. else
  663. {
  664. *p++ = ' '; /* cannot convert */
  665. }
  666. }
  667. else
  668. {
  669. *p++ = ' '; /* bogus character */
  670. }
  671. }
  672. *p = '';
  673. }
  674. /* iso2mic: ISO-8859-5 to Mule internal code */
  675. static void
  676. iso2mic(unsigned char *l, unsigned char *p, int len)
  677. {
  678. static unsigned char iso2koi[] = {
  679. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  680. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  681. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  682. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  683. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  684. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  685. 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
  686. 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
  687. 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
  688. 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
  689. 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
  690. 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
  691. 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
  692. 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
  693. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  694. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  695. };
  696. latin2mic_with_table(l, p, len, LC_KOI8_R, iso2koi);
  697. }
  698. /* mic2iso: Mule internal code to ISO8859-5 */
  699. static void
  700. mic2iso(unsigned char *mic, unsigned char *p, int len)
  701. {
  702. static unsigned char koi2iso[] = {
  703. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  704. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  705. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  706. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  707. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  708. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  709. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  710. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  711. 0xee, 0xd0, 0xd1, 0xe6, 0xd4, 0xd5, 0xe4, 0xd3,
  712. 0xe5, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
  713. 0xdf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xd6, 0xd2,
  714. 0xec, 0xeb, 0xd7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
  715. 0xce, 0xb0, 0xb1, 0xc6, 0xb4, 0xb5, 0xc4, 0xb3,
  716. 0xc5, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
  717. 0xbf, 0xcf, 0xc0, 0xc1, 0xc2, 0xc3, 0xb6, 0xb2,
  718. 0xcc, 0xcb, 0xb7, 0xc8, 0xcd, 0xc9, 0xc7, 0xca
  719. };
  720. mic2latin_with_table(mic, p, len, LC_KOI8_R, koi2iso);
  721. }
  722. /* win2mic: CP1251 to Mule internal code */
  723. static void
  724. win2mic(unsigned char *l, unsigned char *p, int len)
  725. {
  726. static unsigned char win2koi[] = {
  727. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  728. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  729. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  730. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  731. 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00,
  732. 0xb3, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0xb7,
  733. 0x00, 0x00, 0xb6, 0xa6, 0xad, 0x00, 0x00, 0x00,
  734. 0xa3, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0xa7,
  735. 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
  736. 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
  737. 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
  738. 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
  739. 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
  740. 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
  741. 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
  742. 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1
  743. };
  744. latin2mic_with_table(l, p, len, LC_KOI8_R, win2koi);
  745. }
  746. /* mic2win: Mule internal code to CP1251 */
  747. static void
  748. mic2win(unsigned char *mic, unsigned char *p, int len)
  749. {
  750. static unsigned char koi2win[] = {
  751. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  752. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  753. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  754. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  755. 0x00, 0x00, 0x00, 0xb8, 0xba, 0x00, 0xb3, 0xbf,
  756. 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00,
  757. 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x00, 0xb2, 0xaf,
  758. 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00,
  759. 0xfe, 0xe0, 0xe1, 0xf6, 0xe4, 0xe5, 0xf4, 0xe3,
  760. 0xf5, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
  761. 0xef, 0xff, 0xf0, 0xf1, 0xf2, 0xf3, 0xe6, 0xe2,
  762. 0xfc, 0xfb, 0xe7, 0xf8, 0xfd, 0xf9, 0xf7, 0xfa,
  763. 0xde, 0xc0, 0xc1, 0xd6, 0xc4, 0xc5, 0xd4, 0xc3,
  764. 0xd5, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
  765. 0xcf, 0xdf, 0xd0, 0xd1, 0xd2, 0xd3, 0xc6, 0xc2,
  766. 0xdc, 0xdb, 0xc7, 0xd8, 0xdd, 0xd9, 0xd7, 0xda
  767. };
  768. mic2latin_with_table(mic, p, len, LC_KOI8_R, koi2win);
  769. }
  770. /* alt2mic: CP866 to Mule internal code */
  771. static void
  772. alt2mic(unsigned char *l, unsigned char *p, int len)
  773. {
  774. static unsigned char alt2koi[] = {
  775. 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
  776. 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
  777. 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
  778. 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
  779. 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
  780. 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
  781. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  782. 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00,
  783. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  784. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  785. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  786. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  787. 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
  788. 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
  789. 0xb3, 0xa3, 0xb4, 0xa4, 0xb7, 0xa7, 0x00, 0x00,
  790. 0xb6, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  791. };
  792. latin2mic_with_table(l, p, len, LC_KOI8_R, alt2koi);
  793. }
  794. /* mic2alt: Mule internal code to CP866 */
  795. static void
  796. mic2alt(unsigned char *mic, unsigned char *p, int len)
  797. {
  798. static unsigned char koi2alt[] = {
  799. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  800. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  801. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  802. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  803. 0x00, 0x00, 0x00, 0xf1, 0xf3, 0x00, 0xf9, 0xf5,
  804. 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00,
  805. 0x00, 0x00, 0x00, 0xf0, 0xf2, 0x00, 0xf8, 0xf4,
  806. 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00,
  807. 0xee, 0xa0, 0xa1, 0xe6, 0xa4, 0xa5, 0xe4, 0xa3,
  808. 0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
  809. 0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xa6, 0xa2,
  810. 0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
  811. 0x9e, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
  812. 0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
  813. 0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82,
  814. 0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
  815. };
  816. mic2latin_with_table(mic, p, len, LC_KOI8_R, koi2alt);
  817. }
  818. /*
  819.  * end of Cyrillic support
  820.  */
  821. /*-----------------------------------------------------------------
  822.  * WIN1250
  823.  * Microsoft's CP1250(windows-1250)
  824.  *-----------------------------------------------------------------*/
  825. static void
  826. win12502mic(unsigned char *l, unsigned char *p, int len)
  827. {
  828. static unsigned char win1250_2_iso88592[] = {
  829. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  830. 0x88, 0x89, 0xA9, 0x8B, 0xA6, 0xAB, 0xAE, 0xAC,
  831. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  832. 0x98, 0x99, 0xB9, 0x9B, 0xB6, 0xBB, 0xBE, 0xBC,
  833. 0xA0, 0xB7, 0xA2, 0xA3, 0xA4, 0xA1, 0x00, 0xA7,
  834. 0xA8, 0x00, 0xAA, 0x00, 0x00, 0xAD, 0x00, 0xAF,
  835. 0xB0, 0x00, 0xB2, 0xB3, 0xB4, 0x00, 0x00, 0x00,
  836. 0xB8, 0xB1, 0xBA, 0x00, 0xA5, 0xBD, 0xB5, 0xBF,
  837. 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
  838. 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
  839. 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
  840. 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
  841. 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
  842. 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
  843. 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  844. 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  845. };
  846. latin2mic_with_table(l, p, len, LC_ISO8859_2, win1250_2_iso88592);
  847. }
  848. static void
  849. mic2win1250(unsigned char *mic, unsigned char *p, int len)
  850. {
  851. static unsigned char iso88592_2_win1250[] = {
  852. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  853. 0x88, 0x89, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x00,
  854. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  855. 0x98, 0x99, 0x00, 0x9B, 0x00, 0x00, 0x00, 0x00,
  856. 0xA0, 0xA5, 0xA2, 0xA3, 0xA4, 0xBC, 0x8C, 0xA7,
  857. 0xA8, 0x8A, 0xAA, 0x8D, 0x8F, 0xAD, 0x8E, 0xAF,
  858. 0xB0, 0xB9, 0xB2, 0xB3, 0xB4, 0xBE, 0x9C, 0xA1,
  859. 0xB8, 0x9A, 0xBA, 0x9D, 0x9F, 0xBD, 0x9E, 0xBF,
  860. 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
  861. 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
  862. 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
  863. 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
  864. 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
  865. 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
  866. 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  867. 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  868. };
  869. mic2latin_with_table(mic, p, len, LC_ISO8859_2, iso88592_2_win1250);
  870. }
  871. /*-----------------------------------------------------------------*/
  872. pg_encoding_conv_tbl pg_conv_tbl[] = {
  873. {SQL_ASCII, "SQL_ASCII", 0, ascii2mic, mic2ascii}, /* SQL/ACII */
  874. {EUC_JP, "EUC_JP", 0, euc_jp2mic, mic2euc_jp}, /* EUC_JP */
  875. {EUC_CN, "EUC_CN", 0, euc_cn2mic, mic2euc_cn}, /* EUC_CN */
  876. {EUC_KR, "EUC_KR", 0, euc_kr2mic, mic2euc_kr}, /* EUC_KR */
  877. {EUC_TW, "EUC_TW", 0, euc_tw2mic, mic2euc_tw}, /* EUC_TW */
  878. {UNICODE, "UNICODE", 0, 0, 0}, /* UNICODE */
  879. {MULE_INTERNAL, "MULE_INTERNAL", 0, 0, 0}, /* MULE_INTERNAL */
  880. {LATIN1, "LATIN1", 0, latin12mic, mic2latin1}, /* ISO 8859 Latin 1 */
  881. {LATIN2, "LATIN2", 0, latin22mic, mic2latin2}, /* ISO 8859 Latin 2 */
  882. {LATIN3, "LATIN3", 0, latin32mic, mic2latin3}, /* ISO 8859 Latin 3 */
  883. {LATIN4, "LATIN4", 0, latin42mic, mic2latin4}, /* ISO 8859 Latin 4 */
  884. {LATIN5, "LATIN5", 0, iso2mic, mic2iso}, /* ISO 8859 Latin 5 */
  885. {KOI8, "KOI8", 0, koi2mic, mic2koi}, /* KOI8-R */
  886. {WIN, "WIN", 0, win2mic, mic2win}, /* CP1251 */
  887. {ALT, "ALT", 0, alt2mic, mic2alt}, /* CP866 */
  888. {SJIS, "SJIS", 1, sjis2mic, mic2sjis}, /* SJIS */
  889. {BIG5, "BIG5", 1, big52mic, mic2big5}, /* Big5 */
  890. {WIN1250, "WIN1250", 1, win12502mic, mic2win1250}, /* WIN 1250 */
  891. {-1, "", 0, 0, 0} /* end mark */
  892. };