_fallcEuc.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* lcEuc.c 1.1 - Fujitsu source for CDEnext 95/11/06 20:32:36 */
  24. /* $XConsortium: _fallcEuc.c /main/1 1996/04/08 15:16:38 cde-fuj $ */
  25. /******************************************************************
  26. Copyright 1992, 1993 by FUJITSU LIMITED
  27. Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
  28. Permission to use, copy, modify, distribute and sell this software
  29. and its documentation for any purpose is hereby granted without fee,
  30. provided that the above copyright notice appear in all copies and
  31. that both that copyright notice and this permission notice appear
  32. in supporting documentation, and that the name of FUJITSU LIMITED and
  33. Fujitsu Open Systems Solutions, Inc. not be used in advertising or
  34. publicity pertaining to distribution of the software without specific,
  35. written prior permission.
  36. FUJITSU LIMITED and Fujitsu Open Systems Solutions, Inc. makes no
  37. representations about the suitability of this software for any purpose.
  38. It is provided "as is" without express or implied warranty.
  39. FUJITSU LIMITED AND FUJITSU OPEN SYSTEMS SOLUTIONS, INC. DISCLAIMS ALL
  40. WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  41. OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU OPEN SYSTEMS
  42. SOLUTIONS, INC. AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT
  43. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  44. USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  45. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  46. OF THIS SOFTWARE.
  47. Authors: Shigeru Yamada (yamada@ossi.com)
  48. Jeffrey Bloomfield (jeffb@ossi.com)
  49. Yoshiyuki Segawa (segawa@ossi.com)
  50. *****************************************************************/
  51. #include "_fallibint.h"
  52. #include "_fallcGeneric.h"
  53. #include <ctype.h>
  54. #define CS0 codesets[0] /* Codeset 0 - 7-bit ASCII */
  55. #define CS1 codesets[1] /* Codeset 1 - Kanji */
  56. #define CS2 codesets[2] /* Codeset 2 - Half-Kana */
  57. #define CS3 codesets[3] /* Codeset 3 - User defined */
  58. #define SS2 0x8e /* Single-shift char: CS2 */
  59. #define SS3 0x8f /* Single-shift char: CS3 */
  60. #define ASCII_CODESET 0
  61. #define KANJI_CODESET 1
  62. #define KANA_CODESET 2
  63. #define USERDEF_CODESET 3
  64. #define MAX_CODESETS
  65. #define GR 0x80 /* begins right-side (non-ascii) region */
  66. #define GL 0x7f /* ends left-side (ascii) region */
  67. #define isleftside(c) (((c) & GR) ? 0 : 1)
  68. #define isrightside(c) (!isleftside(c))
  69. #define BIT8OFF(c) ((c) & GL)
  70. #define BIT8ON(c) ((c) | GR)
  71. typedef unsigned char Uchar;
  72. typedef unsigned long Ulong;
  73. typedef unsigned int Uint;
  74. static CodeSet GetCodeSetFromCharSet();
  75. static CodeSet wc_codeset();
  76. #define BADCHAR(min_ch, c) (BIT8OFF(c) < (char)min_ch && BIT8OFF(c) != 0x0 && \
  77. BIT8OFF(c) != '\t' && BIT8OFF(c) != '\n' && \
  78. BIT8OFF(c) != 0x1b)
  79. /*
  80. * Notes:
  81. * 1. Defining FORCE_INDIRECT_CONVERTER (see _fallcEucLoader())
  82. * forces indirect (charset) conversions (e.g. wcstocs()<->cstombs()).
  83. * 2. Using direct converters (e.g. mbstowcs()) decreases conversion
  84. * times by 20-40% (depends on specific converter used).
  85. */
  86. static int
  87. euc_mbstowcs(
  88. XlcConv conv,
  89. XPointer *from,
  90. int *from_left,
  91. XPointer *to,
  92. int *to_left,
  93. XPointer *args,
  94. int num_args)
  95. {
  96. XLCd lcd = (XLCd)conv->state;
  97. Uchar ch;
  98. int chr_len = 0;
  99. int sshift = False;
  100. int shift_mult = 0;
  101. Uint chrcode;
  102. Uint wc_encode = 0;
  103. Uint wc_tmp = 0;
  104. int cs0flg = False;
  105. int cs1flg = False;
  106. int length;
  107. int num_conv;
  108. int unconv_num = 0;
  109. Bool new_char;
  110. XPointer inbufptr = *from;
  111. wchar_t *outbufptr = (wchar_t *) *to;
  112. wchar_t *outbuf_base = outbufptr;
  113. CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
  114. int codeset_num = XLC_GENERIC(lcd, codeset_num);
  115. Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
  116. if (*from_left > *to_left)
  117. *from_left = *to_left;
  118. for (new_char = True; *from_left > 0;) {
  119. ch = *inbufptr++;
  120. if (isleftside(ch)) { /* CS0 */
  121. if (ASCII_CODESET >= codeset_num) {
  122. unconv_num++;
  123. (*from_left)--;
  124. continue;
  125. }
  126. if( cs0flg == True) {
  127. new_char = True;
  128. cs0flg = False;
  129. }
  130. length = CS0->length;
  131. *outbufptr++ = (wchar_t)ch;
  132. (*from_left)--;
  133. continue;
  134. }
  135. else if (ch == SS2) { /* CS2 */
  136. if (KANA_CODESET >= codeset_num) {
  137. unconv_num++;
  138. (*from_left)--;
  139. continue;
  140. }
  141. if (sshift == True || cs1flg == True) {
  142. cs1flg = False;
  143. unconv_num++;
  144. continue;
  145. }
  146. length = CS2->length;
  147. wc_encode = CS2->wc_encoding;
  148. chrcode = 0;
  149. sshift = True;
  150. cs0flg = True;
  151. (*from_left)--;
  152. continue;
  153. }
  154. else if (ch == SS3) { /* CS3 */
  155. if (USERDEF_CODESET >= codeset_num) {
  156. unconv_num++;
  157. (*from_left)--;
  158. continue;
  159. }
  160. if (sshift == True || cs1flg == True) {
  161. cs1flg = False;
  162. unconv_num++;
  163. continue;
  164. }
  165. length = CS3->length;
  166. if (*from_left < 1 )
  167. unconv_num++;
  168. wc_encode = CS3->wc_encoding;
  169. chrcode = 0;
  170. sshift = True;
  171. cs0flg = True;
  172. (*from_left)--;
  173. continue;
  174. } else { /* CS1 */
  175. if (KANJI_CODESET >= codeset_num) {
  176. unconv_num++;
  177. (*from_left)--;
  178. continue;
  179. }
  180. if (sshift == False) {
  181. length = CS1->length;
  182. if (*from_left < 1)
  183. unconv_num++;
  184. wc_encode = CS1->wc_encoding;
  185. }
  186. chrcode = BIT8OFF(ch);
  187. cs0flg = True;
  188. cs1flg = True;
  189. (*from_left)--;
  190. }
  191. if (new_char) { /* begin new character */
  192. chr_len = length;
  193. shift_mult = length - 1;
  194. new_char = False;
  195. }
  196. chrcode <<= (wc_shift * shift_mult);
  197. shift_mult--;
  198. wc_tmp |= chrcode;
  199. if (--chr_len == 0) {
  200. wc_tmp |= wc_encode;
  201. *outbufptr++ = wc_tmp;
  202. new_char = True;
  203. sshift = False;
  204. cs0flg = False;
  205. cs1flg = False;
  206. wc_tmp = (Uint)0;
  207. }
  208. } /* end for */
  209. *to = (XPointer)outbufptr;
  210. if (cs0flg == True || cs1flg == True) /* error check on last char */
  211. unconv_num++;
  212. if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
  213. *to_left = (*to_left) - num_conv;
  214. return unconv_num;
  215. }
  216. static int
  217. euc_wcstombs(
  218. XlcConv conv,
  219. XPointer *from,
  220. int *from_left,
  221. XPointer *to,
  222. int *to_left,
  223. XPointer *args,
  224. int num_args)
  225. {
  226. wchar_t *inbufptr = (wchar_t *) *from;
  227. XPointer outbufptr = *to;
  228. XPointer outbuf_base = outbufptr;
  229. wchar_t wch;
  230. int length;
  231. Uchar tmp;
  232. int num_conv;
  233. int unconv_num = 0;
  234. XLCd lcd = (XLCd)conv->state;
  235. CodeSet codeset;
  236. Ulong wc_encoding_mask = XLC_GENERIC(lcd, wc_encode_mask);
  237. Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
  238. Ulong wch_encode;
  239. if (*from_left > *to_left)
  240. *from_left = *to_left;
  241. for (; *from_left > 0 ; (*from_left)-- ) {
  242. wch = *inbufptr++;
  243. if (!(codeset = wc_codeset(lcd, wch))) {
  244. unconv_num++;
  245. (*from_left)--;
  246. continue;
  247. }
  248. length = codeset->length;
  249. wch ^= (wchar_t)codeset->wc_encoding;
  250. if (codeset->parse_info) /* put out SS2 or SS3 */
  251. *outbufptr++ = *codeset->parse_info->encoding;
  252. do {
  253. length--;
  254. tmp = (wch>>(wchar_t)(length * wc_shift));
  255. if (codeset->side == XlcGR)
  256. tmp = BIT8ON(tmp);
  257. *outbufptr++ = (Uchar)tmp;
  258. } while (length);
  259. }
  260. *to = (XPointer)outbufptr;
  261. if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
  262. *to_left -= num_conv;
  263. return unconv_num;
  264. }
  265. static int
  266. euc_mbtocs(
  267. XlcConv conv,
  268. XPointer *from,
  269. int *from_left,
  270. XPointer *to,
  271. int *to_left,
  272. XPointer *args,
  273. int num_args)
  274. {
  275. XLCd lcd = (XLCd)conv->state;
  276. XlcCharSet charset;
  277. CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
  278. int codeset_num = XLC_GENERIC(lcd, codeset_num);
  279. int length;
  280. int unconv_num = 0;
  281. int min_ch = 0;
  282. char *src = *from, *dst = *to;
  283. if (isleftside(*src)) { /* 7-bit (CS0) */
  284. if (ASCII_CODESET >= codeset_num)
  285. return -1;
  286. charset = *CS0->charset_list;
  287. }
  288. else if ((Uchar)*src == SS2) { /* half-kana (CS2) */
  289. if (KANA_CODESET >= codeset_num)
  290. return -1;
  291. charset = *CS2->charset_list;
  292. src++;
  293. (*from_left)--;
  294. }
  295. else if ((Uchar)*src == SS3) { /* user-def */
  296. if (USERDEF_CODESET >= codeset_num)
  297. return -1;
  298. charset = *CS3->charset_list;
  299. src++;
  300. (*from_left)--;
  301. }
  302. else { /* Kanji (CS1) */
  303. if (KANJI_CODESET >= codeset_num)
  304. return -1;
  305. charset = *CS1->charset_list;
  306. }
  307. if(*from_left < charset->char_size || *to_left < charset->char_size)
  308. return -1;
  309. min_ch = 0x20;
  310. if (charset->set_size == 94)
  311. if (charset->char_size > 1 || charset->side == XlcGR)
  312. min_ch = 0x21;
  313. length = charset->char_size;
  314. do {
  315. if(BADCHAR(min_ch, *src)) {
  316. unconv_num++;
  317. break;
  318. }
  319. switch (charset->side) {
  320. case XlcGL:
  321. *dst++ = BIT8OFF(*src++);
  322. break;
  323. case XlcGR:
  324. *dst++ = BIT8ON(*src++);
  325. break;
  326. default:
  327. *dst++ = *src++;
  328. break;
  329. }
  330. } while (--length);
  331. if (unconv_num)
  332. src += charset->char_size - length;
  333. *to = dst;
  334. *from = src;
  335. *from_left -= charset->char_size;
  336. *to_left -= charset->char_size;
  337. if (num_args > 0)
  338. *((XlcCharSet *) args[0]) = charset;
  339. return unconv_num;
  340. }
  341. static int
  342. euc_mbstocs(
  343. XlcConv conv,
  344. XPointer *from,
  345. int *from_left,
  346. XPointer *to,
  347. int *to_left,
  348. XPointer *args,
  349. int num_args)
  350. {
  351. XLCd lcd = (XLCd)conv->state;
  352. char *tmp_from, *tmp_to;
  353. int tmp_from_left, tmp_to_left;
  354. XlcCharSet charset, tmp_charset;
  355. XPointer tmp_args[1];
  356. int unconv_num = 0, ret;
  357. /* Determine the charset of the segment and convert one characater: */
  358. tmp_args[0] = (XPointer) &charset; /* charset from euc_mbtocs() */
  359. while
  360. ((ret = euc_mbtocs(conv, from, from_left, to, to_left, tmp_args, 1)) > 0)
  361. unconv_num += ret;
  362. if ( ret < 0 )
  363. return ret;
  364. tmp_from = *from;
  365. tmp_from_left = *from_left;
  366. tmp_to_left = *to_left;
  367. tmp_to = *to;
  368. /* Convert remainder of the segment: */
  369. tmp_args[0] = (XPointer) &tmp_charset;
  370. while( (ret = euc_mbtocs(conv, &tmp_from, &tmp_from_left, &tmp_to,
  371. &tmp_to_left, tmp_args, 1)) >= 0 ) {
  372. if (ret > 0) {
  373. unconv_num += ret;
  374. continue;
  375. }
  376. if (tmp_charset != charset) /* quit on end of segment */
  377. break;
  378. *from = tmp_from;
  379. *from_left = tmp_from_left;
  380. *to = tmp_to;
  381. *to_left = tmp_to_left;
  382. }
  383. if (num_args > 0)
  384. *((XlcCharSet *) args[0]) = charset;
  385. return unconv_num;
  386. }
  387. static int
  388. euc_wcstocs(
  389. XlcConv conv,
  390. XPointer *from,
  391. int *from_left,
  392. XPointer *to,
  393. int *to_left,
  394. XPointer *args,
  395. int num_args)
  396. {
  397. XLCd lcd = (XLCd)conv->state;
  398. wchar_t *wcptr = (wchar_t *) *from;
  399. char *bufptr = (char *) *to;
  400. wchar_t wch;
  401. char *tmpptr;
  402. int length;
  403. CodeSet codeset;
  404. Ulong wc_encoding;
  405. int unconv_num = 0;
  406. int wcstr_len = *from_left, buf_len = *to_left;
  407. if (!(codeset = wc_codeset(lcd, *wcptr)))
  408. return -1;
  409. wc_encoding = codeset->wc_encoding;
  410. if (wcstr_len < buf_len / codeset->length)
  411. buf_len = wcstr_len * codeset->length;
  412. for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
  413. wch = *wcptr;
  414. if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
  415. break;
  416. length = codeset->length;
  417. buf_len -= length;
  418. bufptr += length;
  419. tmpptr = bufptr - 1;
  420. while (length--) {
  421. *tmpptr-- = codeset->length == 1 && codeset->side == XlcGR ?
  422. BIT8ON(wch) : BIT8OFF(wch);
  423. wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
  424. }
  425. }
  426. if (num_args > 0)
  427. *((XlcCharSet *) args[0]) = *codeset->charset_list;
  428. *from_left -= wcptr - (wchar_t *) *from;
  429. *from = (XPointer) wcptr;
  430. *to_left -= bufptr - *to;
  431. *to = bufptr;
  432. return 0;
  433. }
  434. static int
  435. euc_cstombs(
  436. XlcConv conv,
  437. XPointer *from,
  438. int *from_left,
  439. XPointer *to,
  440. int *to_left,
  441. XPointer *args,
  442. int num_args)
  443. {
  444. XLCd lcd = (XLCd)conv->state;
  445. char *csptr = *from;
  446. char *bufptr = *to;
  447. int csstr_len = *from_left;
  448. int buf_len = *to_left;
  449. int length;
  450. CodeSet codeset;
  451. int cvt_length;
  452. if (num_args < 1)
  453. return -1;
  454. if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
  455. return -1;
  456. cvt_length = 0;
  457. csstr_len /= codeset->length;
  458. buf_len /= codeset->length;
  459. if (codeset->parse_info)
  460. csstr_len *= 2;
  461. if (csstr_len < buf_len)
  462. buf_len = csstr_len;
  463. cvt_length += buf_len * codeset->length;
  464. if (bufptr) {
  465. while (buf_len--) {
  466. if (codeset->parse_info) /* put out SS2 or SS3 */
  467. *bufptr++ = *codeset->parse_info->encoding;
  468. length = codeset->length;
  469. while (length--)
  470. *bufptr++ = codeset->side == XlcGR ?
  471. BIT8ON(*csptr++) : BIT8OFF(*csptr++);
  472. }
  473. }
  474. *from_left -= csptr - *from;
  475. *from = csptr;
  476. if (bufptr)
  477. *to += cvt_length;
  478. *to_left -= cvt_length;
  479. return 0;
  480. }
  481. static int
  482. euc_cstowcs(
  483. XlcConv conv,
  484. XPointer *from,
  485. int *from_left,
  486. XPointer *to,
  487. int *to_left,
  488. XPointer *args,
  489. int num_args)
  490. {
  491. XLCd lcd = (XLCd)conv->state;
  492. char *csptr = *from;
  493. wchar_t *bufptr = (wchar_t *) *to;
  494. wchar_t *toptr = (wchar_t *) *to;
  495. int csstr_len = *from_left;
  496. int buf_len = *to_left;
  497. wchar_t wch;
  498. int length;
  499. Ulong wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
  500. CodeSet codeset;
  501. if (num_args < 1)
  502. return -1;
  503. if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
  504. return -1;
  505. csstr_len /= codeset->length;
  506. if (csstr_len < buf_len)
  507. buf_len = csstr_len;
  508. *to_left -= buf_len;
  509. if (bufptr) {
  510. toptr += buf_len;
  511. *to = (XPointer) toptr;
  512. while (buf_len--) {
  513. wch = (wchar_t) BIT8OFF(*csptr);
  514. csptr++;
  515. length = codeset->length - 1;
  516. while (length--) {
  517. wch = (wch << wc_shift_bits) | BIT8OFF(*csptr);
  518. csptr++;
  519. }
  520. *bufptr++ = wch | codeset->wc_encoding;
  521. }
  522. }
  523. *from_left -= csptr - *from;
  524. *from = csptr;
  525. return 0;
  526. }
  527. static CodeSet
  528. wc_codeset(XLCd lcd, wchar_t wch)
  529. {
  530. CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
  531. int end = XLC_GENERIC(lcd, codeset_num);
  532. Ulong widech = (Ulong)(wch & XLC_GENERIC(lcd, wc_encode_mask));
  533. for (; --end >= 0; codesets++)
  534. if ( widech == (*codesets)->wc_encoding )
  535. return *codesets;
  536. return NULL;
  537. }
  538. static CodeSet
  539. GetCodeSetFromCharSet(XLCd lcd, XlcCharSet charset)
  540. {
  541. CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
  542. XlcCharSet *charset_list;
  543. int codeset_num, num_charsets;
  544. codeset_num = XLC_GENERIC(lcd, codeset_num);
  545. for ( ; codeset_num-- > 0; codeset++) {
  546. num_charsets = (*codeset)->num_charsets;
  547. charset_list = (*codeset)->charset_list;
  548. for ( ; num_charsets-- > 0; charset_list++)
  549. if (*charset_list == charset)
  550. return *codeset;
  551. }
  552. return (CodeSet) NULL;
  553. }
  554. static XlcConv
  555. create_conv(XLCd lcd, XlcConvMethods methods)
  556. {
  557. XlcConv conv;
  558. conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
  559. if (conv == NULL)
  560. return (XlcConv) NULL;
  561. conv->methods = methods;
  562. conv->state = (XPointer) lcd;
  563. return conv;
  564. }
  565. /*
  566. * Stripped down Direct CT converters for EUC
  567. */
  568. typedef struct _CTDataRec {
  569. int side;
  570. int length;
  571. char *name;
  572. Ulong wc_encoding;
  573. char sshift;
  574. char *ct_encoding;
  575. int ct_encoding_len;
  576. int set_size;
  577. Uchar min_ch;
  578. Uchar ct_type;
  579. } CTDataRec, *CTData;
  580. typedef struct _StateRec {
  581. CTData GL_charset;
  582. CTData GR_charset;
  583. CTData charset;
  584. } StateRec, *State;
  585. static enum { CT_STD, CT_NSTD, CT_DIR, CT_EXT0, CT_EXT1, CT_EXT2, CT_VER }
  586. ct_types;
  587. static CTDataRec ctdata[] =
  588. {
  589. { XlcGL, 1, "ISO8859-1:GL", 0, 0, "\033(B" , 3, 0, 0, CT_STD },
  590. { XlcGR, 1, "ISO8859-1:GR", 0, 0, "\033-A" , 3, 0, 0, CT_STD },
  591. { XlcGL, 1, "JISX0201.1976-0:GL", 0, 0, "\033(J" , 3, 0, 0, CT_STD },
  592. { XlcGR, 1, "JISX0201.1976-0:GR", 0, 0, "\033)I" , 3, 0, 0, CT_STD },
  593. { XlcGL, 2, "JISX0208.1983-0:GL", 0, 0, "\033$(B" , 4, 0, 0, CT_STD },
  594. { XlcGR, 2, "JISX0208.1983-0:GR", 0, 0, "\033$)B" , 4, 0, 0, CT_STD },
  595. { XlcGL, 2, "JISX0212.1990-0:GL", 0, 0, "\033$(D" , 4, 0, 0, CT_STD },
  596. { XlcGR, 2, "JISX0212.1990-0:GR", 0, 0, "\033$)D" , 4, 0, 0, CT_STD },
  597. { XlcUnknown, 0, "Ignore-Ext-Status?", 0, 0, "\033#" , 2, 0, 0, CT_VER },
  598. { XlcUnknown, 0, "NonStd-?-OctetChar", 0, 0, "\033%/0" , 4, 0, 0, CT_NSTD },
  599. { XlcUnknown, 1, "NonStd-1-OctetChar", 0, 0, "\033%/1" , 4, 0, 0, CT_NSTD },
  600. { XlcUnknown, 2, "NonStd-2-OctetChar", 0, 0, "\033%/2" , 4, 0, 0, CT_NSTD },
  601. { XlcUnknown, 3, "NonStd-3-OctetChar", 0, 0, "\033%/3" , 4, 0, 0, CT_NSTD },
  602. { XlcUnknown, 4, "NonStd-4-OctetChar", 0, 0, "\033%/4" , 4, 0, 0, CT_NSTD },
  603. { XlcUnknown, 0, "Extension-2" , 0, 0, "\033%/" , 3, 0, 0, CT_EXT2 },
  604. { XlcUnknown, 0, "Extension-0" , 0, 0, "\033" , 1, 0, 0, CT_EXT0 },
  605. { XlcUnknown, 0, "Begin-L-to-R-Text", 0, 0, "\2331]" , 3, 0, 0, CT_DIR },
  606. { XlcUnknown, 0, "Begin-R-to-L-Text", 0, 0, "\2332]" , 3, 0, 0, CT_DIR },
  607. { XlcUnknown, 0, "End-Of-String", 0, 0, "\233]" , 2, 0, 0, CT_DIR },
  608. { XlcUnknown, 0, "Extension-1" , 0, 0, "\233" , 1, 0, 0, CT_EXT1 },
  609. };
  610. /* Note on above table: euc_ctstombs() and euc_ctstowcs() parser depends on
  611. * certain table entries occurring in decreasing string length--
  612. * 1. CT_EXT2 and CT_EXT0 entries must occur after CT_NSTD entries.
  613. * 2. CT_DIR and CT_EXT1 entries must occur after CT_DIR entries.
  614. */
  615. static CTData ctd_endp = ctdata + ((sizeof(ctdata) / sizeof(CTDataRec))) - 1;
  616. static CTData ctdptr[sizeof(ctdata) / sizeof(CTDataRec)];
  617. static enum { Ascii, Kanji, Kana, Userdef } cs_nums;
  618. /*
  619. * initCTptr(): Set ctdptr[] to point at ctdata[], indexed by codeset_num.
  620. */
  621. static void
  622. initCTptr(XLCd lcd)
  623. {
  624. int num_codesets = XLC_GENERIC(lcd, codeset_num);
  625. int num_charsets;
  626. int i, j;
  627. CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
  628. CodeSet codeset;
  629. XlcCharSet charset;
  630. CTData ctdp = ctdata;
  631. ctdptr[Ascii] = &ctdata[0]; /* failsafe */
  632. for (i = 0; i < num_codesets; i++) {
  633. codeset = codesets[i];
  634. num_charsets = codeset->num_charsets;
  635. for (j = 0; j < num_charsets; j++) {
  636. charset = codeset->charset_list[j];
  637. for (ctdp = ctdata; ctdp <= ctd_endp; ctdp++)
  638. if (! strcmp(ctdp->name, charset->name)) {
  639. ctdptr[codeset->cs_num] = ctdp;
  640. ctdptr[codeset->cs_num]->wc_encoding = codeset->wc_encoding;
  641. ctdptr[codeset->cs_num]->set_size =
  642. charset->set_size;
  643. ctdptr[codeset->cs_num]->min_ch =
  644. charset->set_size == 94 &&
  645. (ctdptr[codeset->cs_num]->length > 1 ||
  646. ctdptr[codeset->cs_num]->side == XlcGR) ? 0x21 : 0x20;
  647. if (codeset->parse_info) {
  648. ctdptr[codeset->cs_num]->sshift =
  649. *codeset->parse_info->encoding;
  650. }
  651. break;
  652. }
  653. }
  654. }
  655. }
  656. #define SKIP_I(str) while (*(str) >= 0x20 && *(str) <= 0x2f) (str)++;
  657. #define SKIP_P(str) while (*(str) >= 0x30 && *(str) <= 0x3f) (str)++;
  658. static int
  659. euc_ctstowcs(
  660. XlcConv conv,
  661. XPointer *from,
  662. int *from_left,
  663. XPointer *to,
  664. int *to_left,
  665. XPointer *args,
  666. int num_args)
  667. {
  668. XLCd lcd = (XLCd)conv->state;
  669. Ulong wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
  670. XPointer inbufptr = *from;
  671. XPointer inbuf_base;
  672. wchar_t *outbufptr = (wchar_t *) *to;
  673. wchar_t *outbuf_base = outbufptr;
  674. int clen, length;
  675. int num_conv;
  676. int unconv_num = 0;
  677. unsigned int ct_seglen = 0;
  678. Uchar ct_type = 0;
  679. int shift_mult;
  680. wchar_t wc_tmp;
  681. wchar_t wch;
  682. Ulong wc_encoding;
  683. CTData ctdp = ctdata;
  684. if (*from_left > *to_left)
  685. *from_left = *to_left;
  686. for (length = ctdata[Ascii].length; *from_left > 0; (*from_left) -= length)
  687. {
  688. ct_type = CT_STD;
  689. if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
  690. for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
  691. if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
  692. {
  693. inbufptr += ctdp->ct_encoding_len;
  694. (*from_left) -= ctdp->ct_encoding_len;
  695. if (ctdp->length) {
  696. length = ctdp->length;
  697. if( *from_left < length ) {
  698. *to = (XPointer)outbufptr;
  699. *to_left -= outbufptr - outbuf_base;
  700. return( unconv_num + *from_left );
  701. }
  702. }
  703. ct_type = ctdp->ct_type;
  704. break;
  705. }
  706. }
  707. if (ctdp > ctd_endp) /* failed to match CT sequence */
  708. unconv_num++;
  709. }
  710. /* The following code insures that non-standard encodings, direction, extension,
  711. * and version strings are ignored; subject to change in future.
  712. */
  713. switch (ct_type) {
  714. case CT_STD:
  715. break;
  716. case CT_EXT2:
  717. inbufptr++;
  718. (*from_left)--;
  719. case CT_NSTD:
  720. ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
  721. inbufptr += ct_seglen;
  722. (*from_left) -= ct_seglen;
  723. continue;
  724. case CT_EXT0:
  725. inbuf_base = inbufptr;
  726. SKIP_I(inbufptr);
  727. inbufptr++;
  728. ct_seglen = (unsigned)(inbufptr - inbuf_base);
  729. *(from_left) -= ct_seglen;
  730. continue;
  731. case CT_EXT1:
  732. inbuf_base = inbufptr;
  733. SKIP_P(inbufptr);
  734. SKIP_I(inbufptr);
  735. inbufptr++;
  736. ct_seglen = (unsigned)(inbufptr - inbuf_base);
  737. *(from_left) -= ct_seglen;
  738. continue;
  739. case CT_DIR:
  740. continue;
  741. case CT_VER:
  742. inbufptr += 2;
  743. *(from_left) -= 2;
  744. continue;
  745. }
  746. wc_encoding = (ctdp == ctdptr[Kana] && isleftside(*inbufptr)) ?
  747. ctdptr[Ascii]->wc_encoding: ctdp->wc_encoding;
  748. shift_mult = length - 1;
  749. wch = (wchar_t)0;
  750. clen = length;
  751. do {
  752. wc_tmp = BIT8OFF(*inbufptr++) << (wc_shift_bits * shift_mult);
  753. wch |= wc_tmp;
  754. shift_mult--;
  755. } while (--clen);
  756. *outbufptr++ = wch | wc_encoding;
  757. }
  758. *to = (XPointer)outbufptr;
  759. if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
  760. (*to_left) -= num_conv;
  761. return unconv_num;
  762. }
  763. #define byte1 (length == codeset->length - 1)
  764. #define byte2 (byte1 == 0)
  765. #define kanji (codeset->cs_num == 1)
  766. #define kana (codeset->cs_num == 2)
  767. #define userdef (codeset->cs_num == 3)
  768. static int
  769. euc_wcstocts(
  770. XlcConv conv,
  771. XPointer *from,
  772. int *from_left,
  773. XPointer *to,
  774. int *to_left,
  775. XPointer *args,
  776. int num_args)
  777. {
  778. int ct_len = *to_left;
  779. wchar_t *inbufptr = (wchar_t *) *from;
  780. char *ctptr = *to;
  781. XPointer ct_base = ctptr;
  782. wchar_t wch;
  783. int length;
  784. int unconv_num = 0;
  785. Uchar tmp;
  786. Uchar t1 = 0, t2;
  787. int num_conv;
  788. StateRec ct_state;
  789. XLCd lcd = (XLCd)conv->state;
  790. CTData charset;
  791. CodeSet codeset;
  792. Ulong wc_encoding_mask = XLC_GENERIC(lcd, wc_encode_mask);
  793. Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
  794. /* Initial State: */
  795. ct_state.GL_charset = ctdptr[0]; /* Codeset 0 */
  796. ct_state.GR_charset = NULL;
  797. if (*from_left > *to_left)
  798. *from_left = *to_left;
  799. for (; *from_left > 0 ; (*from_left)-- ) {
  800. wch = *inbufptr++;
  801. if (!(codeset = wc_codeset(lcd, wch))) {
  802. unconv_num++;
  803. (*from_left)--;
  804. continue;
  805. }
  806. charset = ctdptr[codeset->cs_num];
  807. length = codeset->length;
  808. wch ^= (wchar_t)codeset->wc_encoding;
  809. if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
  810. (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
  811. ct_len -= ctdptr[codeset->cs_num]->ct_encoding_len;
  812. if (ct_len < 0) {
  813. unconv_num++;
  814. break;
  815. }
  816. if (ctptr) {
  817. strcpy(ctptr, ctdptr[codeset->cs_num]->ct_encoding);
  818. ctptr += ctdptr[codeset->cs_num]->ct_encoding_len;
  819. }
  820. }
  821. if (charset->side == XlcGR)
  822. ct_state.GR_charset = charset;
  823. else if (charset->side == XlcGL)
  824. ct_state.GL_charset = charset;
  825. do {
  826. length--;
  827. tmp = wch>>(wchar_t)( (Ulong)length * wc_shift);
  828. if (kana) {
  829. if (BADCHAR(charset->min_ch, (char)tmp)) {
  830. unconv_num++;
  831. break;
  832. }
  833. *ctptr++ = (char)BIT8ON(tmp);
  834. }
  835. else if (byte1 && (kanji || userdef))
  836. t1 = tmp;
  837. else if (byte2 && (kanji || userdef)) {
  838. if (BADCHAR(charset->min_ch, (char)t1) ||
  839. BADCHAR(charset->min_ch, (char)tmp)) {
  840. unconv_num++;
  841. break;
  842. }
  843. *ctptr++ = (char)t1;
  844. *ctptr++ = (char)tmp;
  845. }
  846. else {
  847. if (BADCHAR(charset->min_ch, (char)tmp)) {
  848. unconv_num++;
  849. break;
  850. }
  851. *ctptr++ = (char)tmp;
  852. }
  853. } while (length);
  854. } /* end for */
  855. *to = (XPointer)ctptr;
  856. if ((num_conv = (int)(ctptr - ct_base)) > 0)
  857. (*to_left) -= num_conv;
  858. return unconv_num;
  859. }
  860. #undef byte1
  861. #undef byte2
  862. #undef kana
  863. #undef kanji
  864. #undef userdef
  865. #define byte1 (ctdp->length == clen)
  866. #define kana (ctdp == ctdptr[Kana] && isrightside(*inbufptr))
  867. #define kanji (ctdp == ctdptr[Kanji])
  868. #define userdef (ctdp == ctdptr[Userdef])
  869. static int
  870. euc_ctstombs(
  871. XlcConv conv,
  872. XPointer *from,
  873. int *from_left,
  874. XPointer *to,
  875. int *to_left,
  876. XPointer *args,
  877. int num_args)
  878. {
  879. XPointer inbufptr = *from;
  880. XPointer outbufptr = *to;
  881. XPointer inbuf_base;
  882. XPointer outbuf_base = outbufptr;
  883. int clen, length;
  884. int unconv_num = 0;
  885. int num_conv;
  886. unsigned int ct_seglen = 0;
  887. Uchar ct_type = 0;
  888. CTData ctdp = &ctdata[0]; /* default */
  889. if (*from_left > *to_left)
  890. *from_left = *to_left;
  891. for (length = ctdata[Ascii].length; *from_left > 0; (*from_left) -= length)
  892. {
  893. ct_type = CT_STD;
  894. if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
  895. for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
  896. if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
  897. {
  898. inbufptr += ctdp->ct_encoding_len;
  899. (*from_left) -= ctdp->ct_encoding_len - 1;
  900. if (ctdp->length) {
  901. length = ctdp->length;
  902. if( *from_left < length ) {
  903. *to = (XPointer)outbufptr;
  904. *to_left -= outbufptr - outbuf_base;
  905. return( unconv_num + *from_left );
  906. }
  907. }
  908. ct_type = ctdp->ct_type;
  909. break;
  910. }
  911. }
  912. if (ctdp > ctd_endp) /* failed to match CT sequence */
  913. unconv_num++;
  914. }
  915. /* The following code insures that non-standard encodings, direction, extension,
  916. * and version strings are ignored; subject to change in future.
  917. */
  918. switch (ct_type) {
  919. case CT_STD:
  920. break;
  921. case CT_EXT2:
  922. inbufptr++;
  923. (*from_left)--;
  924. case CT_NSTD:
  925. ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
  926. inbufptr += ct_seglen;
  927. (*from_left) -= ct_seglen;
  928. continue;
  929. case CT_EXT0:
  930. inbuf_base = inbufptr;
  931. SKIP_I(inbufptr);
  932. inbufptr++;
  933. ct_seglen = (unsigned)(inbufptr - inbuf_base);
  934. *(from_left) -= ct_seglen;
  935. continue;
  936. case CT_EXT1:
  937. inbuf_base = inbufptr;
  938. SKIP_P(inbufptr);
  939. SKIP_I(inbufptr);
  940. inbufptr++;
  941. ct_seglen = (unsigned)(inbufptr - inbuf_base);
  942. *(from_left) -= ct_seglen;
  943. continue;
  944. case CT_DIR:
  945. continue;
  946. case CT_VER:
  947. inbufptr += 2;
  948. *(from_left) -= 2;
  949. continue;
  950. }
  951. clen = length;
  952. do {
  953. if (byte1)
  954. if (kanji) {
  955. *inbufptr = BIT8ON(*inbufptr);
  956. *(inbufptr+1) = BIT8ON(*(inbufptr+1));
  957. }
  958. else if (kana || userdef)
  959. *outbufptr++ = ctdp->sshift;
  960. *outbufptr++ = *inbufptr++;
  961. } while (--clen);
  962. }
  963. *to = outbufptr;
  964. if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
  965. (*to_left) -= num_conv;
  966. return unconv_num;
  967. }
  968. #undef byte1
  969. #undef kana
  970. #undef kanji
  971. #undef userdef
  972. static int
  973. euc_mbstocts(
  974. XlcConv conv,
  975. XPointer *from,
  976. int *from_left,
  977. XPointer *to,
  978. int *to_left,
  979. XPointer *args,
  980. int num_args)
  981. {
  982. int ct_len = *to_left;
  983. int cs_num;
  984. int clen, length;
  985. int unconv_num = 0;
  986. int num_conv;
  987. XPointer inbufptr = *from;
  988. char *ctptr = *to;
  989. XPointer ct_base = ctptr;
  990. StateRec ct_state;
  991. CTData charset;
  992. XLCd lcd = (XLCd) conv->state;
  993. int codeset_num = XLC_GENERIC(lcd, codeset_num);
  994. /* Initial State: */
  995. ct_state.GL_charset = ctdptr[Ascii];
  996. ct_state.GR_charset = NULL;
  997. if (*from_left > *to_left)
  998. *from_left = *to_left;
  999. for (;*from_left > 0; (*from_left) -= length) {
  1000. if (isleftside(*inbufptr)) { /* 7-bit (CS0) */
  1001. if (ASCII_CODESET >= codeset_num) {
  1002. unconv_num++;
  1003. (*from_left)--;
  1004. continue;
  1005. }
  1006. cs_num = Ascii;
  1007. charset = ctdptr[Ascii];
  1008. }
  1009. else if ((Uchar)*inbufptr == SS2) { /* Kana */
  1010. if (KANA_CODESET >= codeset_num) {
  1011. unconv_num++;
  1012. (*from_left)--;
  1013. continue;
  1014. }
  1015. cs_num = Kana;
  1016. charset = ctdptr[Kana];
  1017. inbufptr++;
  1018. (*from_left)--;
  1019. }
  1020. else if ((Uchar)*inbufptr == SS3) { /* Userdef */
  1021. if (USERDEF_CODESET >= codeset_num) {
  1022. unconv_num++;
  1023. (*from_left)--;
  1024. continue;
  1025. }
  1026. cs_num = Userdef;
  1027. charset = ctdptr[Userdef];
  1028. inbufptr++;
  1029. (*from_left)--;
  1030. }
  1031. else {
  1032. if (KANJI_CODESET >= codeset_num) {
  1033. unconv_num++;
  1034. (*from_left)--;
  1035. continue;
  1036. }
  1037. cs_num = Kanji;
  1038. charset = ctdptr[Kanji];
  1039. }
  1040. length = charset->length;
  1041. if (BADCHAR(charset->min_ch, *inbufptr))
  1042. continue;
  1043. if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
  1044. (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
  1045. ct_len -= ctdptr[cs_num]->ct_encoding_len;
  1046. if (ct_len < 0) {
  1047. unconv_num++;
  1048. break;
  1049. }
  1050. if (ctptr) {
  1051. strcpy(ctptr, ctdptr[cs_num]->ct_encoding);
  1052. ctptr += ctdptr[cs_num]->ct_encoding_len;
  1053. }
  1054. }
  1055. if (charset->side == XlcGR)
  1056. ct_state.GR_charset = charset;
  1057. else if (charset->side == XlcGL)
  1058. ct_state.GL_charset = charset;
  1059. clen = length;
  1060. do {
  1061. *ctptr++ = charset == ct_state.GR_charset ?
  1062. BIT8ON(*inbufptr++) : BIT8OFF(*inbufptr++);
  1063. } while (--clen);
  1064. }
  1065. *to = (XPointer)ctptr;
  1066. if ((num_conv = (int)(ctptr - ct_base)) > 0)
  1067. (*to_left) -= num_conv;
  1068. return unconv_num;
  1069. }
  1070. static void
  1071. close_converter(XlcConv conv)
  1072. {
  1073. Xfree((char *) conv);
  1074. }
  1075. enum { MBSTOCS, WCSTOCS, MBTOCS, CSTOMBS, CSTOWCS, MBSTOWCS, WCSTOMBS,
  1076. CTSTOWCS, CTSTOMBS, WCSTOCTS, MBSTOCTS };
  1077. static XlcConvMethodsRec conv_methods[] = {
  1078. {close_converter, euc_mbstocs, NULL },
  1079. {close_converter, euc_wcstocs, NULL },
  1080. {close_converter, euc_mbtocs, NULL },
  1081. {close_converter, euc_cstombs, NULL },
  1082. {close_converter, euc_cstowcs, NULL },
  1083. {close_converter, euc_mbstowcs, NULL },
  1084. {close_converter, euc_wcstombs, NULL },
  1085. {close_converter, euc_ctstowcs, NULL },
  1086. {close_converter, euc_ctstombs, NULL },
  1087. {close_converter, euc_wcstocts, NULL },
  1088. {close_converter, euc_mbstocts, NULL },
  1089. };
  1090. static XlcConv
  1091. open_mbstocs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1092. {
  1093. return create_conv(from_lcd, &conv_methods[MBSTOCS]);
  1094. }
  1095. static XlcConv
  1096. open_wcstocs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1097. {
  1098. return create_conv(from_lcd, &conv_methods[WCSTOCS]);
  1099. }
  1100. static XlcConv
  1101. open_mbtocs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1102. {
  1103. return create_conv(from_lcd, &conv_methods[MBTOCS]);
  1104. }
  1105. static XlcConv
  1106. open_cstombs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1107. {
  1108. return create_conv(from_lcd, &conv_methods[CSTOMBS]);
  1109. }
  1110. static XlcConv
  1111. open_cstowcs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1112. {
  1113. return create_conv(from_lcd, &conv_methods[CSTOWCS]);
  1114. }
  1115. static XlcConv
  1116. open_mbstowcs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1117. {
  1118. return create_conv(from_lcd, &conv_methods[MBSTOWCS]);
  1119. }
  1120. static XlcConv
  1121. open_wcstombs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1122. {
  1123. return create_conv(from_lcd, &conv_methods[WCSTOMBS]);
  1124. }
  1125. static XlcConv
  1126. open_ctstowcs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1127. {
  1128. return create_conv(from_lcd, &conv_methods[CTSTOWCS]);
  1129. }
  1130. static XlcConv
  1131. open_ctstombs(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1132. {
  1133. return create_conv(from_lcd, &conv_methods[CTSTOMBS]);
  1134. }
  1135. static XlcConv
  1136. open_wcstocts(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1137. {
  1138. return create_conv(from_lcd, &conv_methods[WCSTOCTS]);
  1139. }
  1140. static XlcConv
  1141. open_mbstocts(XLCd from_lcd, char *from_type, XLCd to_lcd, char *to_type)
  1142. {
  1143. return create_conv(from_lcd, &conv_methods[MBSTOCTS]);
  1144. }
  1145. XLCd
  1146. _fallcEucLoader(char *name)
  1147. {
  1148. XLCd lcd;
  1149. lcd = _fallcCreateLC(name, _fallcGenericMethods);
  1150. if (lcd == NULL)
  1151. return lcd;
  1152. if ((_fallcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "euc"))) {
  1153. _fallcDestroyLC(lcd);
  1154. return (XLCd) NULL;
  1155. }
  1156. initCTptr(lcd);
  1157. _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
  1158. _fallcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
  1159. _fallcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
  1160. _fallcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
  1161. _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
  1162. #ifndef FORCE_INDIRECT_CONVERTER
  1163. _fallcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
  1164. _fallcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs);
  1165. _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
  1166. _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs);
  1167. _fallcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts);
  1168. _fallcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs);
  1169. #endif
  1170. return lcd;
  1171. }