1 /******************************************************************
3 Copyright 1992, 1993 by FUJITSU LIMITED
4 Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
6 Permission to use, copy, modify, distribute and sell this software
7 and its documentation for any purpose is hereby granted without fee,
8 provided that the above copyright notice appear in all copies and
9 that both that copyright notice and this permission notice appear
10 in supporting documentation, and that the name of FUJITSU LIMITED and
11 Fujitsu Open Systems Solutions, Inc. not be used in advertising or
12 publicity pertaining to distribution of the software without specific,
13 written prior permission.
14 FUJITSU LIMITED and Fujitsu Open Systems Solutions, Inc. makes no
15 representations about the suitability of this software for any purpose.
16 It is provided "as is" without express or implied warranty.
18 FUJITSU LIMITED AND FUJITSU OPEN SYSTEMS SOLUTIONS, INC. DISCLAIMS ALL
19 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU OPEN SYSTEMS
21 SOLUTIONS, INC. AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT
22 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
23 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
27 Authors: Shigeru Yamada (yamada@ossi.com)
28 Jeffrey Bloomfield (jeffb@ossi.com)
29 Yoshiyuki Segawa (segawa@ossi.com)
31 *****************************************************************/
35 * Supports: all locales with codeset eucJP, eucKR, eucCN, eucTW.
36 * How: Provides converters for euc*.
37 * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2).
46 #include "XlcGeneric.h"
50 #define isascii __isascii
53 #define CS0 codesets[0] /* Codeset 0 - 7-bit ASCII */
54 #define CS1 codesets[1] /* Codeset 1 - Kanji */
55 #define CS2 codesets[2] /* Codeset 2 - Half-Kana */
56 #define CS3 codesets[3] /* Codeset 3 - User defined */
58 #define SS2 0x8e /* Single-shift char: CS2 */
59 #define SS3 0x8f /* Single-shift char: CS3 */
61 #define ASCII_CODESET 0
62 #define KANJI_CODESET 1
63 #define KANA_CODESET 2
64 #define USERDEF_CODESET 3
67 #define GR 0x80 /* begins right-side (non-ascii) region */
68 #define GL 0x7f /* ends left-side (ascii) region */
70 #define isleftside(c) (((c) & GR) ? 0 : 1)
71 #define isrightside(c) (!isleftside(c))
73 #define BIT8OFF(c) ((c) & GL)
74 #define BIT8ON(c) ((c) | GR)
76 typedef unsigned char Uchar;
77 typedef unsigned long Ulong;
78 typedef unsigned int Uint;
80 static CodeSet GetCodeSetFromCharSet (XLCd lcd, XlcCharSet charset);
81 static CodeSet wc_codeset (XLCd lcd, wchar_t wch);
83 #define BADCHAR(min_ch, c) (BIT8OFF(c) < (char)min_ch && BIT8OFF(c) != 0x0 && \
84 BIT8OFF(c) != '\t' && BIT8OFF(c) != '\n' && \
89 * 1. Defining FORCE_INDIRECT_CONVERTER (see _XlcEucLoader())
90 * forces indirect (charset) conversions (e.g. wcstocs()<->cstombs()).
91 * 2. Using direct converters (e.g. mbstowcs()) decreases conversion
92 * times by 20-40% (depends on specific converter used).
105 XLCd lcd = (XLCd)conv->state;
123 const char *inbufptr = *from;
124 wchar_t *outbufptr = (wchar_t *) *to;
126 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
127 int codeset_num = XLC_GENERIC(lcd, codeset_num);
128 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
130 for (new_char = True; *from_left > 0 && *to_left > 0;) {
134 if (isleftside(ch)) { /* CS0 */
135 if (ASCII_CODESET >= codeset_num) {
140 if( cs0flg == True) {
144 length = CS0->length;
145 *outbufptr++ = (wchar_t)ch;
150 else if (ch == SS2) { /* CS2 */
151 if (KANA_CODESET >= codeset_num) {
156 if (sshift == True || cs1flg == True) {
161 length = CS2->length;
162 wc_encode = CS2->wc_encoding;
169 else if (ch == SS3) { /* CS3 */
170 if (USERDEF_CODESET >= codeset_num) {
175 if (sshift == True || cs1flg == True) {
180 length = CS3->length;
183 wc_encode = CS3->wc_encoding;
191 if (KANJI_CODESET >= codeset_num) {
196 if (sshift == False) {
197 length = CS1->length;
200 wc_encode = CS1->wc_encoding;
202 chrcode = BIT8OFF(ch);
208 if (new_char) { /* begin new character */
210 shift_mult = length - 1;
214 chrcode <<= (wc_shift * shift_mult);
218 if (--chr_len == 0) {
220 *outbufptr++ = wc_tmp;
232 *to = (XPointer)outbufptr;
234 if (cs0flg == True || cs1flg == True) /* error check on last char */
251 const wchar_t *inbufptr = (const wchar_t *) *from;
252 XPointer outbufptr = *to;
258 XLCd lcd = (XLCd)conv->state;
260 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
262 for (; *from_left > 0 && *to_left > 0; (*from_left)-- ) {
266 if (!(codeset = wc_codeset(lcd, wch))) {
272 length = codeset->length;
273 wch ^= (wchar_t)codeset->wc_encoding;
275 if (codeset->parse_info) { /* put out SS2 or SS3 */
276 if (*to_left < length + 1) {
280 *outbufptr++ = *codeset->parse_info->encoding;
283 if (*to_left < length) {
291 tmp = (wch>>(wchar_t)(length * wc_shift));
293 if (codeset->side == XlcGR)
296 *outbufptr++ = (Uchar)tmp;
301 *to = (XPointer)outbufptr;
317 XLCd lcd = (XLCd)conv->state;
319 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
320 int codeset_num = XLC_GENERIC(lcd, codeset_num);
324 const char *src = *from;
327 if (isleftside(*src)) { /* 7-bit (CS0) */
328 if (ASCII_CODESET >= codeset_num)
330 charset = *CS0->charset_list;
332 else if ((Uchar)*src == SS2) { /* half-kana (CS2) */
333 if (KANA_CODESET >= codeset_num)
335 charset = *CS2->charset_list;
339 else if ((Uchar)*src == SS3) { /* user-def */
340 if (USERDEF_CODESET >= codeset_num)
342 charset = *CS3->charset_list;
346 else { /* Kanji (CS1) */
347 if (KANJI_CODESET >= codeset_num)
349 charset = *CS1->charset_list;
352 if(*from_left < charset->char_size || *to_left < charset->char_size)
356 if (charset->set_size == 94)
357 if (charset->char_size > 1 || charset->side == XlcGR)
360 length = charset->char_size;
362 if(BADCHAR(min_ch, *src)) {
367 switch (charset->side) {
369 *dst++ = BIT8OFF(*src++);
372 *dst++ = BIT8ON(*src++);
381 *from = (XPointer) src;
382 *from_left -= charset->char_size;
383 *to_left -= charset->char_size - length;
386 *((XlcCharSet *) args[0]) = charset;
402 const char *tmp_from;
404 int tmp_from_left, tmp_to_left;
405 XlcCharSet charset, tmp_charset;
406 XPointer tmp_args[1];
407 int unconv_num = 0, ret;
409 /* Determine the charset of the segment and convert one characater: */
411 tmp_args[0] = (XPointer) &charset; /* charset from euc_mbtocs() */
413 ((ret = euc_mbtocs(conv, from, from_left, to, to_left, tmp_args, 1)) > 0)
419 tmp_from_left = *from_left;
420 tmp_to_left = *to_left;
423 /* Convert remainder of the segment: */
425 tmp_args[0] = (XPointer) &tmp_charset;
426 while( (ret = euc_mbtocs(conv, (XPointer *) &tmp_from, &tmp_from_left,
427 (XPointer *) &tmp_to, &tmp_to_left, tmp_args, 1)) >= 0 ) {
434 if (tmp_charset != charset) /* quit on end of segment */
437 *from = (XPointer) tmp_from;
438 *from_left = tmp_from_left;
439 *to = (XPointer) tmp_to;
440 *to_left = tmp_to_left;
444 *((XlcCharSet *) args[0]) = charset;
460 XLCd lcd = (XLCd)conv->state;
461 const wchar_t *wcptr = (const wchar_t *) *from;
462 char *bufptr = (char *) *to;
468 int wcstr_len = *from_left, buf_len = *to_left;
470 if (!(codeset = wc_codeset(lcd, *wcptr)))
473 wc_encoding = codeset->wc_encoding;
475 if (wcstr_len < buf_len / codeset->length)
476 buf_len = wcstr_len * codeset->length;
478 for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
481 if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
484 length = codeset->length;
491 *tmpptr-- = codeset->length == 1 && codeset->side == XlcGR ?
492 BIT8ON(wch) : BIT8OFF(wch);
493 wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
498 *((XlcCharSet *) args[0]) = *codeset->charset_list;
500 *from_left -= wcptr - (wchar_t *) *from;
501 *from = (XPointer) wcptr;
503 *to_left -= bufptr - *to;
520 XLCd lcd = (XLCd)conv->state;
521 const char *csptr = *from;
523 int csstr_len = *from_left;
524 int buf_len = *to_left;
532 if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
536 csstr_len /= codeset->length;
537 buf_len /= codeset->length;
539 if (codeset->parse_info)
542 if (csstr_len < buf_len)
545 cvt_length += buf_len * codeset->length;
549 if (codeset->parse_info) /* put out SS2 or SS3 */
550 *bufptr++ = *codeset->parse_info->encoding;
552 length = codeset->length;
554 *bufptr++ = codeset->side == XlcGR ?
555 BIT8ON(*csptr++) : BIT8OFF(*csptr++);
559 *from_left -= csptr - *from;
560 *from = (XPointer) csptr;
563 *to_left -= cvt_length;
579 XLCd lcd = (XLCd)conv->state;
580 const char *csptr = *from;
581 wchar_t *bufptr = (wchar_t *) *to;
582 wchar_t *toptr = (wchar_t *) *to;
583 int csstr_len = *from_left;
584 int buf_len = *to_left;
587 Ulong wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
593 if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
596 csstr_len /= codeset->length;
597 if (csstr_len < buf_len)
604 *to = (XPointer) toptr;
608 wch = (wchar_t) BIT8OFF(*csptr);
611 length = codeset->length - 1;
613 wch = (wch << wc_shift_bits) | BIT8OFF(*csptr);
616 *bufptr++ = wch | codeset->wc_encoding;
619 *from_left -= csptr - *from;
620 *from = (XPointer) csptr;
631 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
632 int end = XLC_GENERIC(lcd, codeset_num);
633 Ulong widech = (Ulong)(wch & XLC_GENERIC(lcd, wc_encode_mask));
635 for (; --end >= 0; codesets++)
636 if ( widech == (*codesets)->wc_encoding )
644 GetCodeSetFromCharSet(
648 CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
649 XlcCharSet *charset_list;
650 int codeset_num, num_charsets;
652 codeset_num = XLC_GENERIC(lcd, codeset_num);
654 for ( ; codeset_num-- > 0; codeset++) {
655 num_charsets = (*codeset)->num_charsets;
656 charset_list = (*codeset)->charset_list;
658 for ( ; num_charsets-- > 0; charset_list++)
659 if (*charset_list == charset)
663 return (CodeSet) NULL;
670 XlcConvMethods methods)
674 conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
676 return (XlcConv) NULL;
678 conv->methods = methods;
679 conv->state = (XPointer) lcd;
685 * Stripped down Direct CT converters for EUC
689 typedef struct _CTDataRec {
700 } CTDataRec, *CTData;
702 typedef struct _StateRec {
716 static CTDataRec ctdata[] =
718 { XlcGL, 1, "ISO8859-1:GL", 0, 0, "\033(B" , 3, 0, 0, CT_STD },
719 { XlcGR, 1, "ISO8859-1:GR", 0, 0, "\033-A" , 3, 0, 0, CT_STD },
720 { XlcGL, 1, "JISX0201.1976-0:GL", 0, 0, "\033(J" , 3, 0, 0, CT_STD },
721 { XlcGR, 1, "JISX0201.1976-0:GR", 0, 0, "\033)I" , 3, 0, 0, CT_STD },
722 { XlcGL, 2, "JISX0208.1983-0:GL", 0, 0, "\033$(B" , 4, 0, 0, CT_STD },
723 { XlcGR, 2, "JISX0208.1983-0:GR", 0, 0, "\033$)B" , 4, 0, 0, CT_STD },
724 { XlcGL, 2, "JISX0212.1990-0:GL", 0, 0, "\033$(D" , 4, 0, 0, CT_STD },
725 { XlcGR, 2, "JISX0212.1990-0:GR", 0, 0, "\033$)D" , 4, 0, 0, CT_STD },
726 { XlcUnknown, 0, "Ignore-Ext-Status?", 0, 0, "\033#" , 2, 0, 0, CT_VER },
727 { XlcUnknown, 0, "NonStd-?-OctetChar", 0, 0, "\033%/0" , 4, 0, 0, CT_NSTD },
728 { XlcUnknown, 1, "NonStd-1-OctetChar", 0, 0, "\033%/1" , 4, 0, 0, CT_NSTD },
729 { XlcUnknown, 2, "NonStd-2-OctetChar", 0, 0, "\033%/2" , 4, 0, 0, CT_NSTD },
730 { XlcUnknown, 3, "NonStd-3-OctetChar", 0, 0, "\033%/3" , 4, 0, 0, CT_NSTD },
731 { XlcUnknown, 4, "NonStd-4-OctetChar", 0, 0, "\033%/4" , 4, 0, 0, CT_NSTD },
732 { XlcUnknown, 0, "Extension-2" , 0, 0, "\033%/" , 3, 0, 0, CT_EXT2 },
733 { XlcUnknown, 0, "Extension-0" , 0, 0, "\033" , 1, 0, 0, CT_EXT0 },
734 { XlcUnknown, 0, "Begin-L-to-R-Text", 0, 0, "\2331]" , 3, 0, 0, CT_DIR },
735 { XlcUnknown, 0, "Begin-R-to-L-Text", 0, 0, "\2332]" , 3, 0, 0, CT_DIR },
736 { XlcUnknown, 0, "End-Of-String", 0, 0, "\233]" , 2, 0, 0, CT_DIR },
737 { XlcUnknown, 0, "Extension-1" , 0, 0, "\233" , 1, 0, 0, CT_EXT1 },
740 /* Note on above table: euc_ctstombs() and euc_ctstowcs() parser depends on
741 * certain table entries occuring in decreasing string length--
742 * 1. CT_EXT2 and CT_EXT0 entries must occur after CT_NSTD entries.
743 * 2. CT_DIR and CT_EXT1 entries must occur after CT_DIR entries.
746 static CTData ctd_endp = ctdata + ((sizeof(ctdata) / sizeof(CTDataRec))) - 1;
747 static CTData ctdptr[sizeof(ctdata) / sizeof(CTDataRec)];
755 * initCTptr(): Set ctdptr[] to point at ctdata[], indexed by codeset_num.
761 int num_codesets = XLC_GENERIC(lcd, codeset_num);
764 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
767 CTData ctdp = ctdata;
769 ctdptr[Ascii] = &ctdata[0]; /* failsafe */
771 for (i = 0; i < num_codesets; i++) {
773 codeset = codesets[i];
774 num_charsets = codeset->num_charsets;
776 for (j = 0; j < num_charsets; j++) {
778 charset = codeset->charset_list[j];
780 for (ctdp = ctdata; ctdp <= ctd_endp; ctdp++)
782 if (! strcmp(ctdp->name, charset->name)) {
784 ctdptr[codeset->cs_num] = ctdp;
786 ctdptr[codeset->cs_num]->wc_encoding = codeset->wc_encoding;
788 ctdptr[codeset->cs_num]->set_size =
791 ctdptr[codeset->cs_num]->min_ch =
792 charset->set_size == 94 &&
793 (ctdptr[codeset->cs_num]->length > 1 ||
794 ctdptr[codeset->cs_num]->side == XlcGR) ? 0x21 : 0x20;
796 if (codeset->parse_info) {
797 ctdptr[codeset->cs_num]->sshift =
798 *codeset->parse_info->encoding;
808 #define SKIP_I(str) while (*(str) >= 0x20 && *(str) <= 0x2f) (str)++;
809 #define SKIP_P(str) while (*(str) >= 0x30 && *(str) <= 0x3f) (str)++;
821 XLCd lcd = (XLCd)conv->state;
822 Ulong wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
823 const char *inbufptr = *from;
824 const char *inbuf_base;
825 wchar_t *outbufptr = (wchar_t *) *to;
826 wchar_t *outbuf_base = outbufptr;
829 unsigned int ct_seglen = 0;
835 CTData ctdp = ctdata;
836 CTData GL_ctdp = ctdp; /* GL ctdp save */
837 CTData GR_ctdp = ctdp; /* GR ctdp save */
838 Bool save_outbuf = True;
839 /* If outbufptr is NULL, doen't save output, but just counts
840 a length to hold the output */
841 if (outbufptr == NULL) save_outbuf = False;
843 for (length = ctdata[Ascii].length; *from_left > 0; (*from_left) -= length)
846 /* change GL/GR charset */
847 if(ctdp->side == XlcGR && isleftside(*inbufptr)){
850 length = ctdp->length;
851 ct_type = ctdp->ct_type;
852 }else if(ctdp->side == XlcGL && isrightside(*inbufptr)){
855 length = ctdp->length;
856 ct_type = ctdp->ct_type;
858 if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
859 for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
861 if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
863 inbufptr += ctdp->ct_encoding_len;
864 (*from_left) -= ctdp->ct_encoding_len;
866 length = ctdp->length;
867 if( *from_left < length ) {
868 *to = (XPointer)outbufptr;
869 *to_left -= outbufptr - outbuf_base;
870 return( unconv_num + *from_left );
873 ct_type = ctdp->ct_type;
874 if(ctdp->side == XlcGL){
875 GL_ctdp = ctdp; /* save GL ctdp */
877 GR_ctdp = ctdp; /* save GR ctdp */
882 if (ctdp > ctd_endp) /* failed to match CT sequence */
886 /* The following code insures that non-standard encodings, direction, extension,
887 * and version strings are ignored; subject to change in future.
896 ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
897 inbufptr += ct_seglen;
898 (*from_left) -= ct_seglen;
901 inbuf_base = inbufptr;
904 ct_seglen = (unsigned)(inbufptr - inbuf_base);
905 *(from_left) -= ct_seglen;
908 inbuf_base = inbufptr;
912 ct_seglen = (unsigned)(inbufptr - inbuf_base);
913 *(from_left) -= ct_seglen;
923 wc_encoding = (ctdp == ctdptr[Kana] && isleftside(*inbufptr)) ?
924 ctdptr[Ascii]->wc_encoding: ctdp->wc_encoding;
926 shift_mult = length - 1;
931 wc_tmp = BIT8OFF(*inbufptr++) << (wc_shift_bits * shift_mult);
936 if (save_outbuf == True)
937 *outbufptr++ = wch | wc_encoding;
938 if (--*to_left == 0 && *from_left != length) {
939 *to = (XPointer)outbufptr;
940 unconv_num = *from_left;
945 *to = (XPointer)outbufptr;
952 #define byte1 (length == codeset->length - 1)
953 #define byte2 (byte1 == 0)
954 #define kanji (codeset->cs_num == 1)
955 #define kana (codeset->cs_num == 2)
956 #define userdef (codeset->cs_num == 3)
968 int ct_len = *to_left;
969 const wchar_t *inbufptr = (const wchar_t *) *from;
971 XPointer ct_base = ctptr;
980 XLCd lcd = (XLCd)conv->state;
983 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
986 ct_state.GL_charset = ctdptr[0]; /* Codeset 0 */
987 ct_state.GR_charset = NULL;
989 if (*from_left > *to_left)
990 *from_left = *to_left;
992 for (; *from_left > 0 ; (*from_left)-- ) {
996 if (!(codeset = wc_codeset(lcd, wch))) {
1002 charset = ctdptr[codeset->cs_num];
1004 length = codeset->length;
1005 wch ^= (wchar_t)codeset->wc_encoding;
1007 if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
1008 (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
1010 ct_len -= ctdptr[codeset->cs_num]->ct_encoding_len;
1018 strcpy(ctptr, ctdptr[codeset->cs_num]->ct_encoding);
1019 ctptr += ctdptr[codeset->cs_num]->ct_encoding_len;
1023 if (charset->side == XlcGR) {
1024 ct_state.GR_charset = charset;
1025 ct_state.GL_charset = NULL;
1026 } else if (charset->side == XlcGL) {
1027 ct_state.GL_charset = charset;
1028 ct_state.GR_charset = NULL;
1034 tmp = wch>>(wchar_t)( (Ulong)length * wc_shift);
1037 if (BADCHAR(charset->min_ch, (char)tmp)) {
1041 *ctptr++ = (char)BIT8ON(tmp);
1044 else if (byte1 && (kanji || userdef))
1047 else if (byte2 && (kanji || userdef)) {
1048 if (BADCHAR(charset->min_ch, (char)t1) ||
1049 BADCHAR(charset->min_ch, (char)tmp)) {
1053 if (charset->side == XlcGR) {
1054 *ctptr++ = (char)BIT8ON(t1);
1055 *ctptr++ = (char)BIT8ON(tmp);
1057 *ctptr++ = (char)BIT8OFF(t1);
1058 *ctptr++ = (char)BIT8OFF(tmp);
1063 if (BADCHAR(charset->min_ch, (char)tmp)) {
1067 *ctptr++ = (char)tmp;
1075 *to = (XPointer)ctptr;
1077 if ((num_conv = (int)(ctptr - ct_base)) > 0)
1078 (*to_left) -= num_conv;
1089 #define byte1 (ctdp->length == clen)
1090 #define kana (ctdp == ctdptr[Kana] && isrightside(*inbufptr))
1091 /* #define kanji (ctdp == ctdptr[Kanji]) */
1092 #define kanji (strstr(ctdp->name, "JISX0208"))
1093 #define userdef (ctdp == ctdptr[Userdef])
1105 char *inbufptr = *from;
1106 XPointer outbufptr = *to;
1107 const char *inbuf_base;
1108 XPointer outbuf_base = outbufptr;
1111 unsigned int ct_seglen = 0;
1113 CTData ctdp = &ctdata[0]; /* default */
1114 CTData GL_ctdp = ctdp; /* GL ctdp save */
1115 CTData GR_ctdp = ctdp; /* GR ctdp save */
1116 Bool save_outbuf = True;
1117 /* If outbufptr is NULL, doen't save output, but just counts
1118 a length to hold the output */
1119 if (outbufptr == NULL) save_outbuf = False;
1121 for (length = ctdata[Ascii].length; *from_left > 0; (*from_left) -= length)
1124 /* change GL/GR charset */
1125 if(ctdp->side == XlcGR && isleftside(*inbufptr)){
1126 /* select GL side */
1128 length = ctdp->length;
1129 ct_type = ctdp->ct_type;
1130 }else if(ctdp->side == XlcGL && isrightside(*inbufptr)){
1131 /* select GR side */
1133 length = ctdp->length;
1134 ct_type = ctdp->ct_type;
1136 if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
1138 for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
1140 if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
1142 inbufptr += ctdp->ct_encoding_len;
1143 (*from_left) -= ctdp->ct_encoding_len;
1145 length = ctdp->length;
1146 if( *from_left < length ) {
1147 *to = (XPointer)outbufptr;
1148 *to_left -= outbufptr - outbuf_base;
1149 return( unconv_num + *from_left );
1152 ct_type = ctdp->ct_type;
1153 if(ctdp->side == XlcGL){
1154 GL_ctdp = ctdp; /* save GL ctdp */
1156 GR_ctdp = ctdp; /* save GR ctdp */
1161 if (ctdp > ctd_endp) /* failed to match CT sequence */
1165 /* The following code insures that non-standard encodings, direction, extension,
1166 * and version strings are ignored; subject to change in future.
1175 ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
1176 inbufptr += ct_seglen;
1177 (*from_left) -= ct_seglen;
1180 inbuf_base = inbufptr;
1183 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1184 *(from_left) -= ct_seglen;
1187 inbuf_base = inbufptr;
1191 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1192 *(from_left) -= ct_seglen;
1207 /* FIXME: assignment of read-only location */
1208 *inbufptr = BIT8ON(*inbufptr);
1209 *(inbufptr+1) = BIT8ON(*(inbufptr+1));
1211 else if (kana || userdef) {
1212 if (save_outbuf == True) {
1213 *outbufptr++ = ctdp->sshift;
1218 if (save_outbuf == True) {
1219 *outbufptr++ = *inbufptr;
1224 if (*to_left == 0 && *from_left != length) {
1225 *to = (XPointer)outbufptr;
1226 unconv_num = *from_left;
1253 int ct_len = *to_left;
1255 int clen, length = 0;
1258 const char *inbufptr = *from;
1260 XPointer ct_base = ctptr;
1264 XLCd lcd = (XLCd) conv->state;
1265 int codeset_num = XLC_GENERIC(lcd, codeset_num);
1267 /* Initial State: */
1268 ct_state.GL_charset = NULL;
1269 ct_state.GR_charset = NULL;
1271 if (*from_left > *to_left)
1272 *from_left = *to_left;
1274 for (;*from_left > 0; (*from_left) -= length) {
1276 if (isleftside(*inbufptr)) { /* 7-bit (CS0) */
1277 if (ASCII_CODESET >= codeset_num) {
1283 charset = ctdptr[Ascii];
1285 else if ((Uchar)*inbufptr == SS2) { /* Kana */
1286 if (KANA_CODESET >= codeset_num) {
1292 charset = ctdptr[Kana];
1296 else if ((Uchar)*inbufptr == SS3) { /* Userdef */
1297 if (USERDEF_CODESET >= codeset_num) {
1303 charset = ctdptr[Userdef];
1308 if (KANJI_CODESET >= codeset_num) {
1314 charset = ctdptr[Kanji];
1317 length = charset->length;
1319 if (BADCHAR(charset->min_ch, *inbufptr))
1322 if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
1323 (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
1325 ct_len -= ctdptr[cs_num]->ct_encoding_len;
1332 strcpy(ctptr, ctdptr[cs_num]->ct_encoding);
1333 ctptr += ctdptr[cs_num]->ct_encoding_len;
1337 if (charset->side == XlcGR) {
1338 ct_state.GR_charset = charset;
1339 ct_state.GL_charset = NULL;
1340 } else if (charset->side == XlcGL) {
1341 ct_state.GL_charset = charset;
1342 ct_state.GR_charset = NULL;
1348 *ctptr++ = charset == ct_state.GR_charset ?
1349 BIT8ON(*inbufptr++) : BIT8OFF(*inbufptr++);
1353 *to = (XPointer)ctptr;
1355 if ((num_conv = (int)(ctptr - ct_base)) > 0)
1356 (*to_left) -= num_conv;
1366 Xfree((char *) conv);
1369 enum { MBSTOCS, WCSTOCS, MBTOCS, CSTOMBS, CSTOWCS, MBSTOWCS, WCSTOMBS,
1370 CTSTOWCS, CTSTOMBS, WCSTOCTS, MBSTOCTS };
1372 static XlcConvMethodsRec conv_methods[] = {
1373 {close_converter, euc_mbstocs, NULL },
1374 {close_converter, euc_wcstocs, NULL },
1375 {close_converter, euc_mbtocs, NULL },
1376 {close_converter, euc_cstombs, NULL },
1377 {close_converter, euc_cstowcs, NULL },
1378 {close_converter, euc_mbstowcs, NULL },
1379 {close_converter, euc_wcstombs, NULL },
1380 {close_converter, euc_ctstowcs, NULL },
1381 {close_converter, euc_ctstombs, NULL },
1382 {close_converter, euc_wcstocts, NULL },
1383 {close_converter, euc_mbstocts, NULL },
1390 const char *from_type,
1392 const char *to_type)
1394 return create_conv(from_lcd, &conv_methods[MBSTOCS]);
1400 const char *from_type,
1402 const char *to_type)
1404 return create_conv(from_lcd, &conv_methods[WCSTOCS]);
1410 const char *from_type,
1412 const char *to_type)
1414 return create_conv(from_lcd, &conv_methods[MBTOCS]);
1420 const char *from_type,
1422 const char *to_type)
1424 return create_conv(from_lcd, &conv_methods[CSTOMBS]);
1430 const char *from_type,
1432 const char *to_type)
1434 return create_conv(from_lcd, &conv_methods[CSTOWCS]);
1440 const char *from_type,
1442 const char *to_type)
1444 return create_conv(from_lcd, &conv_methods[MBSTOWCS]);
1450 const char *from_type,
1452 const char *to_type)
1454 return create_conv(from_lcd, &conv_methods[WCSTOMBS]);
1460 const char *from_type,
1462 const char *to_type)
1464 return create_conv(from_lcd, &conv_methods[CTSTOWCS]);
1470 const char *from_type,
1472 const char *to_type)
1474 return create_conv(from_lcd, &conv_methods[CTSTOMBS]);
1480 const char *from_type,
1482 const char *to_type)
1484 return create_conv(from_lcd, &conv_methods[WCSTOCTS]);
1490 const char *from_type,
1492 const char *to_type)
1494 return create_conv(from_lcd, &conv_methods[MBSTOCTS]);
1503 lcd = _XlcCreateLC(name, _XlcGenericMethods);
1507 if (!XLC_PUBLIC_PART(lcd)->codeset ||
1508 (_XlcNCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "euc", 3))) {
1515 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
1516 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
1517 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
1518 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
1519 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
1521 #ifndef FORCE_INDIRECT_CONVERTER
1522 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
1523 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs);
1524 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
1525 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs);
1526 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts);
1527 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs);
1530 _XlcAddUtf8Converters(lcd);
1537 #endif /* X_LOCALE */