1 /****************************************************************
3 Copyright 1992, 1993 by FUJITSU LIMITED
4 Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
5 Copyright 1994 by Sony Corporation
7 Permission to use, copy, modify, distribute and sell this software
8 and its documentation for any purpose is hereby granted without fee,
9 provided that the above copyright notice appear in all copies and
10 that both that copyright notice and this permission notice appear
11 in supporting documentation, and that the name of FUJITSU LIMITED,
12 Fujitsu Open Systems Solutions, Inc. and Sony Corporation not be
13 used in advertising or publicity pertaining to distribution of the
14 software without specific, written prior permission.
15 FUJITSU LIMITED, Fujitsu Open Systems Solutions, Inc. and
16 Sony Corporation make no representations about the suitability of
17 this software for any purpose. It is provided "as is" without
18 express or implied warranty.
20 FUJITSU LIMITED, FUJITSU OPEN SYSTEMS SOLUTIONS, INC. AND SONY
21 CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
23 IN NO EVENT SHALL FUJITSU OPEN SYSTEMS SOLUTIONS, INC., FUJITSU LIMITED
24 AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
25 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
26 OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
27 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
28 OR PERFORMANCE OF THIS SOFTWARE.
30 Authors: Jeffrey Bloomfield (jeffb@ossi.com)
31 Shigeru Yamada (yamada@ossi.com)
32 Yoshiyuki Segawa (segawa@ossi.com)
33 Modifier:Makoto Wakamatsu Sony Corporation
36 *****************************************************************/
39 * A Japanese SJIS locale.
40 * Supports: all locales with codeset SJIS.
41 * How: Provides converters for SJIS.
42 * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2).
51 #include "XlcGeneric.h"
55 #define isascii __isascii
58 #define CS0 codesets[0] /* Codeset 0 - 7-bit ASCII */
59 #define CS1 codesets[1] /* Codeset 1 - Kanji */
60 #define CS2 codesets[2] /* Codeset 2 - Half-Kana */
61 #define CS3 codesets[3] /* Codeset 3 - User defined */
63 #define ascii (codeset->cs_num == 0)
64 #define kanji (codeset->cs_num == 1)
65 #define kana (codeset->cs_num == 2)
66 #define userdef (codeset->cs_num == 3)
68 #define ASCII_CODESET 0
69 #define KANJI_CODESET 1
70 #define KANA_CODESET 2
71 #define USERDEF_CODESET 3
72 #define MAX_CODESETS 4
74 #define GR 0x80 /* begins right-side (non-ascii) region */
75 #define GL 0x7f /* ends left-side (ascii) region */
77 #define isleftside(c) (((c) & GR) ? 0 : 1)
78 #define isrightside(c) (!isleftside(c))
80 typedef unsigned char Uchar;
81 typedef unsigned long Ulong;
82 typedef unsigned int Uint;
84 /* Acceptable range for 2nd byte of SJIS multibyte char */
85 #define VALID_MULTIBYTE(c) \
86 ((0x40<=((Uchar)c) && ((Uchar)c)<=0x7e) \
87 || (0x80<=((Uchar)c) && ((Uchar)c)<=0xfc))
90 #define iskanji(c) ((0x81<=((Uchar)c) && ((Uchar)c)<=0x9f) \
91 || (0xe0<=((Uchar)c) && ((Uchar)c)<=0xef))
95 #define iskana(c) (0xa1<=((Uchar)c) && ((Uchar)c)<=0xdf)
98 #define isuserdef(c) (0xf0<=((Uchar)c) && ((Uchar)c)<=0xfc)
100 #define BIT8OFF(c) ((c) & GL)
101 #define BIT8ON(c) ((c) | GR)
104 static void jis_to_sjis (Uchar *p1, Uchar *p2);
105 static void sjis_to_jis (Uchar *p1, Uchar *p2);
106 static CodeSet wc_codeset (XLCd lcd, wchar_t wch);
111 * 1. 16-bit widechar format is limited to 14 data bits. Since the 2nd byte
112 * of SJIS multibyte chars are in the ranges of 0x40 - 7E and 0x80 - 0xFC,
113 * SJIS cannot map directly into 16 bit widechar format within the confines
114 * of a single codeset. Therefore, for SJIS widechar conversion, SJIS Kanji
115 * is mapped into the JIS codeset. (The algorithms used in jis_to_sjis()
116 * and sjis_to_jis() are from Ken Lunde (lunde@mv.us.adobe.com) and are in
117 * the public domain.)
118 * 2. Defining FORCE_INDIRECT_CONVERTER (see _XlcEucLoader())
119 * forces indirect (charset) conversions (e.g. wcstocs()<->cstombs()).
120 * 3. Using direct converters (e.g. mbstowcs()) decreases conversion
121 * times by 20-40% (depends on specific converter used).
136 XLCd lcd = (XLCd)conv->state;
153 const char *inbufptr = *from;
154 wchar_t *outbufptr = (wchar_t *) *to;
155 wchar_t *outbuf_base = outbufptr;
157 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
158 int codeset_num = XLC_GENERIC(lcd, codeset_num);
159 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
161 if (*from_left > *to_left)
162 *from_left = *to_left;
164 for (new_char = True, firstbyte = True; *from_left > 0; (*from_left)--) {
169 if (ASCII_CODESET >= codeset_num) {
175 length = CS0->length;
176 *outbufptr++ = (wchar_t)ch;
179 else if (iskanji(ch)) {
180 if (KANJI_CODESET >= codeset_num) {
186 length = CS1->length;
187 if (*from_left < length || *to_left < length)
189 wc_encode = CS1->wc_encoding;
191 sjis_to_jis(&ch, &ch2);
194 else if (iskana(ch)) {
195 if (KANA_CODESET >= codeset_num) {
200 length = CS2->length;
201 wc_encode = CS2->wc_encoding;
202 chrcode = BIT8OFF(ch);
204 else if (isuserdef(ch)) {
205 if (USERDEF_CODESET >= codeset_num) {
211 length = CS3->length;
212 if (*from_left < length || *to_left < length)
214 wc_encode = CS3->wc_encoding;
216 sjis_to_jis(&ch, &ch2);
224 } else { /* 2nd byte of multibyte char */
225 if (!VALID_MULTIBYTE((Uchar) *(inbufptr-1))) {
234 shift_mult = length - 1;
238 chrcode <<= (wc_shift * shift_mult);
241 if (--chr_len == 0) {
243 *outbufptr++ = wc_tmp;
252 *to = (XPointer)outbufptr;
254 if ((num_conv = outbufptr - outbuf_base) > 0)
255 (*to_left) -= num_conv;
261 #define byte1 (length == codeset->length - 1)
262 #define byte2 (byte1 == 0)
274 const wchar_t *inbufptr = (const wchar_t *) *from;
275 XPointer outbufptr = *to;
276 XPointer outbuf_base = outbufptr;
284 XLCd lcd = (XLCd)conv->state;
286 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
288 if (*from_left > *to_left)
289 *from_left = *to_left;
291 for (; *from_left > 0 ; (*from_left)-- ) {
295 if (!(codeset = wc_codeset(lcd, wch))) {
301 length = codeset->length;
302 wch ^= (wchar_t)codeset->wc_encoding;
306 tmp = wch>>(wchar_t)( (Ulong)length * wc_shift);
311 else if (byte1 && (kanji || userdef)) {
316 else if (byte2 && (kanji || userdef)) {
318 jis_to_sjis(&t1, &t2);
319 *outbufptr++ = (char)t1;
323 *outbufptr++ = (char)tmp;
328 *to = (XPointer)outbufptr;
330 if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
331 (*to_left) -= num_conv;
339 * sjis<->jis conversion for widechar kanji (See Note at top of file)
348 Uchar adjust = c2 < 0x9f;
349 Uchar rowOffset = c1 < 0xa0 ? 0x70 : 0xb0;
350 Uchar cellOffset = adjust ? (0x1f + (c2 > 0x7f)) : 0x7e;
352 *p1 = ((c1 - rowOffset) << 1) - adjust;
363 Uchar rowOffset = c1 < 0x5f ? 0x70 : 0xb0;
364 Uchar cellOffset = c1 % 2 ? 0x1f + (c2 > 0x5f) : 0x7e;
366 *p1 = ((Uchar)(c1 + 1) >> 1) + rowOffset;
367 *p2 = c2 + cellOffset;
375 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
376 #if !defined(__sony_news) || defined(SVR4)
377 int end = XLC_GENERIC(lcd, codeset_num);
378 Ulong widech = (Ulong)(wch & XLC_GENERIC(lcd, wc_encode_mask));
380 for (; --end >= 0; codesets++)
381 if ( widech == (*codesets)->wc_encoding )
386 if( iskanji(wch >> 8) )
387 return( codesets[1] );
388 if( iskana(wch & 0xff) )
389 return( codesets[2] );
390 return( codesets[0] );
405 XLCd lcd = (XLCd)conv->state;
406 XlcCharSet charset = NULL;
409 const char *src = *from;
411 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
412 int codeset_num = XLC_GENERIC(lcd, codeset_num);
415 if (KANJI_CODESET >= codeset_num)
417 charset = *CS1->charset_list;
418 char_size = charset->char_size;
420 if (*from_left >= char_size && *to_left >= char_size) {
423 if (!VALID_MULTIBYTE((Uchar) *(src-1))) /* check 2nd byte */
425 sjis_to_jis((Uchar *)(dst-2), (Uchar *)(dst-1));
429 else if (isuserdef(*src)) {
430 if (USERDEF_CODESET >= codeset_num)
432 charset = *CS3->charset_list;
433 char_size = charset->char_size;
435 if (*from_left >= char_size && *to_left >= char_size) {
438 if (!VALID_MULTIBYTE((Uchar) *(src-1))) /* check 2nd byte */
440 sjis_to_jis((Uchar *)(dst-2), (Uchar *)(dst-1));
444 else if (isascii(*src)) {
445 if (ASCII_CODESET >= codeset_num)
447 charset = *CS0->charset_list;
448 char_size = charset->char_size;
450 if (*from_left >= char_size && *to_left >= char_size)
455 else if (iskana(*src)) {
456 if (KANA_CODESET >= codeset_num)
458 charset = *CS2->charset_list;
459 char_size = charset->char_size;
461 if (*from_left >= char_size && *to_left >= char_size)
469 *from_left -= char_size;
470 *to_left -= char_size;
472 *to = (XPointer) dst;
473 *from = (XPointer) src;
476 *((XlcCharSet *) args[0]) = charset;
492 const char *tmp_from;
494 int tmp_from_left, tmp_to_left;
495 XlcCharSet charset, tmp_charset;
496 XPointer tmp_args[1];
497 int unconv_num = 0, ret;
499 /* Determine the charset of the segment and convert one character: */
501 tmp_args[0] = (XPointer) &charset; /* charset from sjis_mbtocs() */
503 ((ret = sjis_mbtocs(conv, from, from_left, to, to_left, tmp_args, 1)) > 0)
509 tmp_from_left = *from_left;
510 tmp_to_left = *to_left;
513 /* Convert remainder of the segment: */
515 tmp_args[0] = (XPointer) &tmp_charset;
516 while( (ret = sjis_mbtocs(conv, (XPointer *) &tmp_from, &tmp_from_left,
517 (XPointer *) &tmp_to, &tmp_to_left, tmp_args, 1)) >= 0 ) {
524 if (tmp_charset != charset) /* quit on end of segment */
527 *from = (XPointer) tmp_from;
528 *from_left = tmp_from_left;
529 *to = (XPointer) tmp_to;
530 *to_left = tmp_to_left;
534 *((XlcCharSet *) args[0]) = charset;
549 XLCd lcd = (XLCd) conv->state;
550 const wchar_t *wcptr = *((const wchar_t **)from);
551 char *bufptr = *((char **) to);
557 int buf_len = *to_left;
558 int wcstr_len = *from_left;
560 if (!(codeset = wc_codeset(lcd, *wcptr)))
563 if (wcstr_len < buf_len / codeset->length)
564 buf_len = wcstr_len * codeset->length;
566 #if !defined(__sony_news) || defined(SVR4)
567 wc_encoding = codeset->wc_encoding;
569 for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
572 if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
575 length = codeset->length;
582 *tmpptr-- = kana ? BIT8ON(wch) : BIT8OFF(wch);
583 wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
587 length = codeset->length;
588 for( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len-- ) {
590 if( codeset != wc_codeset( lcd, wch ) )
597 code = sjis2jis( wch & 0xffff );
598 *bufptr++ = code >> 8;
599 *bufptr++ = code & 0xff;
602 *bufptr++ = wch & 0xff;
607 *((XlcCharSet *) args[0]) = *codeset->charset_list;
609 *from_left -= wcptr - (wchar_t *) *from;
610 *from = (XPointer) wcptr;
612 *to_left -= bufptr - *to;
619 GetCodeSetFromCharSet(
623 CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
624 XlcCharSet *charset_list;
625 int codeset_num, num_charsets;
627 codeset_num = XLC_GENERIC(lcd, codeset_num);
629 for ( ; codeset_num-- > 0; codeset++) {
630 num_charsets = (*codeset)->num_charsets;
631 charset_list = (*codeset)->charset_list;
633 for ( ; num_charsets-- > 0; charset_list++)
634 if (*charset_list == charset)
638 return (CodeSet) NULL;
652 XLCd lcd = (XLCd) conv->state;
653 const char *csptr = *from;
655 int csstr_len = *from_left;
656 int buf_len = *to_left;
664 if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
667 csstr_len /= codeset->length;
668 buf_len /= codeset->length;
669 if (csstr_len < buf_len)
672 cvt_length += buf_len * codeset->length;
676 length = codeset->length;
678 *bufptr++ = codeset->length == 1 && codeset->side == XlcGR ?
679 BIT8ON(*csptr++) : BIT8OFF(*csptr++);
681 if (codeset->length == 2)
682 jis_to_sjis((Uchar *)(bufptr-2), (Uchar *)(bufptr-1));
686 *from_left -= csptr - *from;
687 *from = (XPointer) csptr;
691 *to_left -= cvt_length;
707 XLCd lcd = (XLCd) conv->state;
708 const char *csptr = (const char *) *from;
709 wchar_t *bufptr = (wchar_t *) *to;
710 wchar_t *toptr = (wchar_t *) *to;
711 int csstr_len = *from_left;
712 int buf_len = *to_left;
715 Ulong wc_shift_bits = (int)XLC_GENERIC(lcd, wc_shift_bits);
721 if (!(codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0])))
724 csstr_len /= codeset->length;
725 if (csstr_len < buf_len)
733 *to = (XPointer) toptr;
736 wch = (wchar_t) BIT8OFF(*csptr);
739 length = codeset->length - 1;
741 wch = (wch << wc_shift_bits) | BIT8OFF(*csptr);
744 *bufptr++ = wch | codeset->wc_encoding;
748 *from_left -= csptr - *from;
749 *from = (XPointer) csptr;
756 * Stripped down Direct CT converters for SJIS
760 #define BADCHAR(min_ch, c) (BIT8OFF(c) < (char)min_ch && BIT8OFF(c) != 0x0 && \
761 BIT8OFF(c) != '\t' && BIT8OFF(c) != '\n' && \
764 typedef struct _CTDataRec {
774 } CTDataRec, *CTData;
776 typedef struct _StateRec {
790 static CTDataRec ctdata[] =
792 { XlcGL, 1, "ISO8859-1:GL", 0, "\033(B" , 3, 0, 0, CT_STD },
793 { XlcGR, 1, "ISO8859-1:GR", 0, "\033-A" , 3, 0, 0, CT_STD },
794 { XlcGL, 1, "JISX0201.1976-0:GL", 0, "\033(J" , 3, 0, 0, CT_STD },
795 { XlcGR, 1, "JISX0201.1976-0:GR", 0, "\033)I" , 3, 0, 0, CT_STD },
796 { XlcGL, 2, "JISX0208.1983-0:GL", 0, "\033$(B" , 4, 0, 0, CT_STD },
797 { XlcGR, 2, "JISX0208.1983-0:GR", 0, "\033$)B" , 4, 0, 0, CT_STD },
798 { XlcGL, 2, "JISX0212.1990-0:GL", 0, "\033$(D" , 4, 0, 0, CT_STD },
799 { XlcGR, 2, "JISX0212.1990-0:GR", 0, "\033$)D" , 4, 0, 0, CT_STD },
800 { XlcUnknown, 0, "Ignore-Ext-Status?", 0, "\033#" , 2, 0, 0, CT_VER },
801 { XlcUnknown, 0, "NonStd-?-OctetChar", 0, "\033%/0" , 4, 0, 0, CT_NSTD },
802 { XlcUnknown, 1, "NonStd-1-OctetChar", 0, "\033%/1" , 4, 0, 0, CT_NSTD },
803 { XlcUnknown, 2, "NonStd-2-OctetChar", 0, "\033%/2" , 4, 0, 0, CT_NSTD },
804 { XlcUnknown, 3, "NonStd-3-OctetChar", 0, "\033%/3" , 4, 0, 0, CT_NSTD },
805 { XlcUnknown, 4, "NonStd-4-OctetChar", 0, "\033%/4" , 4, 0, 0, CT_NSTD },
806 { XlcUnknown, 0, "Extension-2" , 0, "\033%/" , 3, 0, 0, CT_EXT2 },
807 { XlcUnknown, 0, "Extension-0" , 0, "\033" , 1, 0, 0, CT_EXT0 },
808 { XlcUnknown, 0, "Begin-L-to-R-Text", 0, "\2331]" , 3, 0, 0, CT_DIR },
809 { XlcUnknown, 0, "Begin-R-to-L-Text", 0, "\2332]" , 3, 0, 0, CT_DIR },
810 { XlcUnknown, 0, "End-Of-String", 0, "\233]" , 2, 0, 0, CT_DIR },
811 { XlcUnknown, 0, "Extension-1" , 0, "\233" , 1, 0, 0, CT_EXT1 },
814 /* Note on above table: sjis_ctstombs() and sjis_ctstowcs() parser depends on
815 * certain table entries occuring in decreasing string length--
816 * 1. CT_EXT2 and CT_EXT0 entries must occur after CT_NSTD entries.
817 * 2. CT_DIR and CT_EXT1 entries must occur after CT_DIR entries.
820 static CTData ctdptr[sizeof(ctdata) / sizeof(CTDataRec)];
821 static CTData ctd_endp = ctdata + ((sizeof(ctdata) / sizeof(CTDataRec))) - 1;
829 * initCTptr(): Set ctptr[] to point at ctdata[], indexed by codeset_num.
835 int num_codesets = XLC_GENERIC(lcd, codeset_num);
838 CodeSet *codesets = XLC_GENERIC(lcd, codeset_list);
841 CTData ctdp = ctdata;
843 ctdptr[Ascii] = &ctdata[0]; /* failsafe */
845 for (i = 0; i < num_codesets; i++) {
847 codeset = codesets[i];
848 num_charsets = codeset->num_charsets;
850 for (j = 0; j < num_charsets; j++) {
852 charset = codeset->charset_list[j];
854 for (ctdp = ctdata; ctdp <= ctd_endp; ctdp++)
856 if (! strcmp(ctdp->name, charset->name)) {
858 ctdptr[codeset->cs_num] = ctdp;
860 ctdptr[codeset->cs_num]->wc_encoding = codeset->wc_encoding;
862 ctdptr[codeset->cs_num]->set_size =
865 ctdptr[codeset->cs_num]->min_ch =
866 charset->set_size == 94 &&
867 (ctdptr[codeset->cs_num]->length > 1 ||
868 ctdptr[codeset->cs_num]->side == XlcGR) ? 0x21 : 0x20;
887 int ct_len = *to_left;
892 const char *inbufptr = *from;
894 XPointer ct_base = ctptr;
897 CTData charset = NULL;
898 XLCd lcd = (XLCd) conv->state;
899 int codeset_num = XLC_GENERIC(lcd, codeset_num);
903 ct_state.GL_charset = ctdptr[Ascii];
904 ct_state.GR_charset = NULL;
906 if (*from_left > *to_left)
907 *from_left = *to_left;
909 for (;*from_left > 0; (*from_left) -= charset->length) {
911 if (iskanji(*inbufptr)) {
912 if (KANJI_CODESET >= codeset_num) {
918 charset = ctdptr[Kanji];
919 if (!VALID_MULTIBYTE((Uchar) *(inbufptr+1)))
922 else if (isuserdef(*inbufptr)) {
923 if (USERDEF_CODESET >= codeset_num) {
929 charset = ctdptr[Userdef];
930 if (!VALID_MULTIBYTE((Uchar) *(inbufptr+1)))
933 else if (isascii(*inbufptr)) {
934 if (ASCII_CODESET >= codeset_num) {
940 charset = ctdptr[Ascii];
942 else if (iskana(*inbufptr)) {
943 if (KANA_CODESET >= codeset_num) {
949 charset = ctdptr[Kana];
957 if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
958 (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
960 ct_len -= ctdptr[cs_num]->ct_encoding_len;
967 strcpy(ctptr, ctdptr[cs_num]->ct_encoding);
968 ctptr += ctdptr[cs_num]->ct_encoding_len;
972 clen = charset->length;
974 *ctptr++ = *inbufptr++;
977 if (charset->length >= 2) {
978 sjis_to_jis((Uchar *)(ctptr-2), (Uchar *)(ctptr-1));
979 if (BADCHAR(charset->min_ch, *(ctptr-2)) ||
980 BADCHAR(charset->min_ch, *(ctptr-1))) {
986 if (BADCHAR(charset->min_ch, *(ctptr-1))) {
991 if (charset->side == XlcGR)
992 ct_state.GR_charset = charset;
993 else if (charset->side == XlcGL)
994 ct_state.GL_charset = charset;
996 if (charset->side == XlcGR) {
997 clen = charset->length;
999 (*(Uchar *)(ctptr-clen)) = BIT8ON(*(Uchar *)(ctptr-clen));
1004 *to = (XPointer)ctptr;
1006 if ((num_conv = (int)(ctptr - ct_base)) > 0)
1007 (*to_left) -= num_conv;
1014 #define byte1 (length == codeset->length - 1)
1015 #define byte2 (byte1 == 0)
1027 int ct_len = *to_left;
1028 const wchar_t *inbufptr = (const wchar_t *) *from;
1030 XPointer ct_base = ctptr;
1038 XLCd lcd = (XLCd)conv->state;
1042 Ulong wc_shift = XLC_GENERIC(lcd, wc_shift_bits);
1044 /* Initial State: */
1045 ct_state.GL_charset = ctdptr[0]; /* Codeset 0 */
1046 ct_state.GR_charset = NULL;
1048 if (*from_left > *to_left)
1049 *from_left = *to_left;
1051 for (; *from_left > 0 ; (*from_left)-- ) {
1055 if (!(codeset = wc_codeset(lcd, wch))) {
1061 charset = ctdptr[codeset->cs_num];
1063 length = codeset->length;
1064 wch ^= (wchar_t)codeset->wc_encoding;
1066 if ( (charset->side == XlcGR && charset != ct_state.GR_charset) ||
1067 (charset->side == XlcGL && charset != ct_state.GL_charset) ) {
1069 ct_len -= ctdptr[codeset->cs_num]->ct_encoding_len;
1076 strcpy(ctptr, ctdptr[codeset->cs_num]->ct_encoding);
1077 ctptr += ctdptr[codeset->cs_num]->ct_encoding_len;
1082 if (charset->side == XlcGR)
1083 ct_state.GR_charset = charset;
1084 else if (charset->side == XlcGL)
1085 ct_state.GL_charset = charset;
1089 tmp = wch>>(wchar_t)( (Ulong)length * wc_shift);
1092 if (BADCHAR(charset->min_ch, (char)tmp)) {
1096 *ctptr++ = (char)BIT8ON(tmp);
1099 else if (byte1 && (kanji || userdef)) {
1103 else if (byte2 && (kanji || userdef)) {
1104 if (BADCHAR(charset->min_ch, (char)t1) ||
1105 BADCHAR(charset->min_ch, (char)tmp)) {
1110 *ctptr++ = (char)BIT8OFF(t1);
1111 *ctptr++ = (char)BIT8OFF(tmp);
1115 if (BADCHAR(charset->min_ch, (char)tmp)) {
1119 *ctptr++ = (char)tmp;
1125 *to = (XPointer)ctptr;
1127 if ((num_conv = (int)(ctptr - ct_base)) > 0)
1128 (*to_left) -= num_conv;
1135 #define SKIP_I(str) while (*(str) >= 0x20 && *(str) <= 0x2f) (str)++;
1136 #define SKIP_P(str) while (*(str) >= 0x30 && *(str) <= 0x3f) (str)++;
1148 const char *inbufptr = *from;
1149 XPointer outbufptr = *to;
1150 const char *inbuf_base;
1151 XPointer outbuf_base = outbufptr;
1155 unsigned int ct_seglen = 0;
1157 CTData ctdp = ctdata; /* default */
1158 CTData GL_ctdp = ctdp; /* GL ctdp save */
1159 CTData GR_ctdp = ctdp; /* GR ctdp save */
1161 if (*from_left > *to_left)
1162 *from_left = *to_left;
1164 for (length = ctdata[Ascii].length; *from_left > 0 ; (*from_left) -= length)
1167 /* change GL/GR charset */
1168 if(ctdp->side == XlcGR && isleftside(*inbufptr)){
1169 /* select GL side */
1171 length = ctdp->length;
1172 ct_type = ctdp->ct_type;
1173 }else if(ctdp->side == XlcGL && isrightside(*inbufptr)){
1174 /* select GR side */
1176 length = ctdp->length;
1177 ct_type = ctdp->ct_type;
1179 if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
1181 for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
1183 if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
1185 inbufptr += ctdp->ct_encoding_len;
1186 (*from_left) -= ctdp->ct_encoding_len;
1187 if( ctdp->length ) {
1188 length = ctdp->length;
1189 if( *from_left < length ) {
1190 *to = (XPointer)outbufptr;
1191 *to_left -= outbufptr - outbuf_base;
1192 return( unconv_num + *from_left );
1195 ct_type = ctdp->ct_type;
1196 if(ctdp->side == XlcGL){
1197 GL_ctdp = ctdp; /* save GL ctdp */
1199 GR_ctdp = ctdp; /* save GR ctdp */
1204 if (ctdp > ctd_endp) /* failed to match CT sequence */
1208 /* The following code insures that non-standard encodings, direction, extension,
1209 * and version strings are ignored; subject to change in future.
1218 ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
1219 inbufptr += ct_seglen;
1220 (*from_left) -= ct_seglen;
1223 inbuf_base = inbufptr;
1226 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1227 (*from_left) -= ct_seglen;
1230 inbuf_base = inbufptr;
1234 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1235 (*from_left) -= ct_seglen;
1245 if (ctdp->side == XlcGL || isrightside (*inbufptr)) {
1249 *from_left += length - clen;
1252 Uchar mask = (length == 2) ? GL : -1;
1253 *outbufptr++ = *inbufptr++ & mask;
1257 jis_to_sjis((Uchar *)(outbufptr-2), (Uchar *)(outbufptr-1));
1260 *to = (XPointer)outbufptr;
1262 if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
1263 (*to_left) -= num_conv;
1279 XLCd lcd = (XLCd)conv->state;
1280 Ulong wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
1281 const char *inbufptr = *from;
1282 const char *inbuf_base;
1283 wchar_t *outbufptr = (wchar_t *) *to;
1284 wchar_t *outbuf_base = outbufptr;
1288 unsigned int ct_seglen = 0;
1294 CTData ctdp = ctdata;
1295 CTData GL_ctdp = ctdp; /* GL ctdp save */
1296 CTData GR_ctdp = ctdp; /* GR ctdp save */
1298 if (*from_left > *to_left)
1299 *from_left = *to_left;
1301 for (length = ctdata[Ascii].length; *from_left > 0; (*from_left) -= length )
1304 /* change GL/GR charset */
1305 if(ctdp->side == XlcGR && isleftside(*inbufptr)){
1306 /* select GL side */
1308 length = ctdp->length;
1309 ct_type = ctdp->ct_type;
1310 }else if(ctdp->side == XlcGL && isrightside(*inbufptr)){
1311 /* select GR side */
1313 length = ctdp->length;
1314 ct_type = ctdp->ct_type;
1316 if (*inbufptr == '\033' || *inbufptr == (char)'\233') {
1317 for (ctdp = ctdata; ctdp <= ctd_endp ; ctdp++) {
1319 if(!strncmp(inbufptr, ctdp->ct_encoding, ctdp->ct_encoding_len))
1321 inbufptr += ctdp->ct_encoding_len;
1322 (*from_left) -= ctdp->ct_encoding_len;
1323 if( ctdp->length ) {
1324 length = ctdp->length;
1325 if( *from_left < length ) {
1326 *to = (XPointer)outbufptr;
1327 *to_left -= outbufptr - outbuf_base;
1328 return( unconv_num + *from_left );
1331 ct_type = ctdp->ct_type;
1332 if(ctdp->side == XlcGL){
1333 GL_ctdp = ctdp; /* save GL ctdp */
1335 GR_ctdp = ctdp; /* save GR ctdp */
1340 if (ctdp > ctd_endp) /* failed to match CT sequence */
1344 /* The following block of code insures that non-standard encodings, direction,
1345 * extension, and version strings are ignored; subject to change in future.
1354 ct_seglen = (BIT8OFF(*inbufptr) << 7) + BIT8OFF(*(inbufptr+1)) + 2;
1355 inbufptr += ct_seglen;
1356 (*from_left) -= ct_seglen;
1359 inbuf_base = inbufptr;
1362 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1363 (*from_left) -= ct_seglen;
1366 inbuf_base = inbufptr;
1370 ct_seglen = (unsigned)(inbufptr - inbuf_base);
1371 (*from_left) -= ct_seglen;
1380 #if !defined(__sony_news) || defined(SVR4)
1381 if (ctdp->side == XlcGL || isrightside (*inbufptr)) {
1383 wc_encoding = ctdp->wc_encoding;
1386 *from_left += length - clen;
1387 wc_encoding = ctdptr[Ascii]->wc_encoding;
1389 shift_mult = clen - 1;
1393 wc_tmp = BIT8OFF(*inbufptr++) << (wc_shift_bits * shift_mult);
1397 *outbufptr++ = wch | wc_encoding;
1400 *outbufptr++ = (unsigned char)*inbufptr++;
1401 else if( length == 2 ) {
1402 unsigned short code;
1403 code = (*inbufptr << 8) | *(inbufptr+1);
1404 *outbufptr++ = jis2sjis( code );
1409 *to = (XPointer)outbufptr;
1411 if ((num_conv = (int)(outbufptr - outbuf_base)) > 0)
1412 (*to_left) -= num_conv ;
1423 Xfree((char *) conv);
1430 XlcConvMethods methods)
1434 conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
1436 return (XlcConv) NULL;
1438 conv->methods = methods;
1439 conv->state = (XPointer) lcd;
1444 enum { MBSTOCS, WCSTOCS, MBTOCS, CSTOMBS, CSTOWCS, MBSTOWCS, WCSTOMBS,
1445 WCSTOCTS, MBSTOCTS, CTSTOMBS, CTSTOWCS };
1447 static XlcConvMethodsRec conv_methods[] = {
1448 {close_converter, sjis_mbstocs, NULL },
1449 {close_converter, sjis_wcstocs, NULL },
1450 {close_converter, sjis_mbtocs, NULL },
1451 {close_converter, sjis_cstombs, NULL },
1452 {close_converter, sjis_cstowcs, NULL },
1453 {close_converter, sjis_mbstowcs, NULL },
1454 {close_converter, sjis_wcstombs, NULL },
1455 {close_converter, sjis_wcstocts, NULL },
1456 {close_converter, sjis_mbstocts, NULL },
1457 {close_converter, sjis_ctstombs, NULL },
1458 {close_converter, sjis_ctstowcs, NULL },
1465 const char *from_type,
1467 const char *to_type)
1469 return create_conv(from_lcd, &conv_methods[MBSTOCS]);
1475 const char *from_type,
1477 const char *to_type)
1479 return create_conv(from_lcd, &conv_methods[WCSTOCS]);
1485 const char *from_type,
1487 const char *to_type)
1489 return create_conv(from_lcd, &conv_methods[MBTOCS]);
1495 const char *from_type,
1497 const char *to_type)
1499 return create_conv(from_lcd, &conv_methods[CSTOMBS]);
1505 const char *from_type,
1507 const char *to_type)
1509 return create_conv(from_lcd, &conv_methods[CSTOWCS]);
1515 const char *from_type,
1517 const char *to_type)
1519 return create_conv(from_lcd, &conv_methods[MBSTOWCS]);
1525 const char *from_type,
1527 const char *to_type)
1529 return create_conv(from_lcd, &conv_methods[WCSTOMBS]);
1535 const char *from_type,
1537 const char *to_type)
1539 return create_conv(from_lcd, &conv_methods[WCSTOCTS]);
1545 const char *from_type,
1547 const char *to_type)
1549 return create_conv(from_lcd, &conv_methods[MBSTOCTS]);
1555 const char *from_type,
1557 const char *to_type)
1559 return create_conv(from_lcd, &conv_methods[CTSTOMBS]);
1565 const char *from_type,
1567 const char *to_type)
1569 return create_conv(from_lcd, &conv_methods[CTSTOWCS]);
1578 lcd = _XlcCreateLC(name, _XlcGenericMethods);
1582 if (!XLC_PUBLIC_PART(lcd)->codeset ||
1583 (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "SJIS"))) {
1590 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
1591 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
1592 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
1593 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
1594 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
1596 #ifndef FORCE_INDIRECT_CONVERTER
1597 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
1598 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs);
1599 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
1600 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs);
1601 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts);
1602 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs);
1605 _XlcAddUtf8Converters(lcd);
1612 #endif /* X_LOCALE */